安装Erlan/OTP
$ kerl list releases Getting the available releases from erlang.org... R10B-0 R10B-2 R10B-3 R10B-4 R10B-5 R10B-6 R10B-7 R10B-8 R10B-9 R11B-0 R11B-1 R11B-2 R11B-3 R11B-4 R11B-5 R12B-0 R12B-1 R12B-2 R12B-3 R12B-4 R12B-5 R13A R13B R13B01 R13B02 R13B03 R13B04 R14A R14B R14B01 R14B02 Run "./kerl update releases" to update this list from erlang.org
2013-6-1 18:33:47更新 网友Wang Lihe的使用反馈,供参考
缘起是这样:在公司开发项目,但是公司使用的redhat很老旧,只有5.3至5.8系列的,甚至还有4系列。官方库里是没有erlang的,于是epel。但是epel 5里面只R12,版本相当的老。于是忍着各种基础不足(比如lists模块居然都少几个函数,binary根本没有,rebar要求R13以上啊),开发功能。但是干到第二版时,基本的性能已经达到极限了,<<160000个>>的解析变换居然要100几个毫秒,坚决不能同意。于是开始加入driver和nif。结果发现R14B才是nif真正可用的,R12根本没这个接口,头撞墙啊,俩小弟那无助的眼神啊,我只好放下功能,开始研究epel 6的rpm包(邪路,不小心中招,费力不讨好,没有成功编译过,而且分成十几个小包,巨细,且讨厌)。猛然间发现,给erlang epel打包的俄国哥们其实已经给epel5打了R14B的包,只是redhat官方喜欢“稳定”(我怀疑就是想让全世界开发新功能赶快升级就对了),进不去。不管怎么说,R14B成功进入开发系统。但是问题很快又出现了,这大哥打的包,不知是真的因为redhat太老,还是有失水准,R14B是没有HIPE的,而且所有的lib的src都是空的,这让我们开发挖源码时不胜烦恼。于是一边开发,一边还是在研究打包。一开始是看着erlang-solutions的rhel5.5 coming soon眼发绿,但是好久没有动静,后来开始看官方编译教程,猛然间,搜到了一个叫kerl的东西。这让我大喜过望,试用结果非常好。kerl本身只是一个shell脚本,运行后在$HOME下建立.kerl目录,所有的东西都放下面,不会扰乱其他的,而且从下载到编译安装一就俱全,特特别好的是,安装并不需要安装到系统,而是可以指定自己的位置,这样,可以同时安装好多个版本。只要引入不同的启动文件,就可以在不同的erlang版本里切换,非常方便。我一路从R14B编译至R16B,全部成功,哇卡卡,甚至可以在rhel4上使用,这是让公司的老机器焕发青春么(磁盘满了,编译过了,好像没安装成功,有机会再重试,有成功的各位分享一下)?至此,在合适的时候,所有的开发和应用环境,都有机会使用最新版erlang了,以上,分享给各位。
各种网址:
epel: https://fedoraproject.org/wiki/EPEL
以前上面还有4系列的,rhel4上的erlang是R11,完全不能用。
rhel4系列的源还活着https://dl.fedoraproject.org/pub/epel/4/x86_64/,俄国大哥的博客:https://lemenkov.wordpress.com/2010/11/07/erlang-otp-r14b-for-epel-5/
提到的rhel5上的r14b的源:http://repos.fedorapeople.org/repos/peter/erlang/
Erlang 多语言混搭
Reia is a Ruby-like scripting language for the Erlang virtual machine. Reia brings you the best of both worlds between Ruby's friendly syntax, reflection, metaprogramming, and the amazing power of blocks, and Erlang's immense abilities for concurrency, distribution, hot code swapping, and fault tolerance.Reia's source code is available on Github. There are no releases and thus no direct download links yet, sorry! See the README on Github for instructions on how to build Reia from source.
defmodule Hello do IO.puts "Defining the function world" def world do IO.puts "Hello World" end IO.puts "Function world defined"end Hello.world
项目地址: http://elixir-lang.org/
Meck
Eshell V5.8.4 (abort with ^G) 1> meck:new(dog). ok 2> meck:expect(dog, bark, fun() -> "Woof!" end). ok 3> dog:bark(). "Woof!" 4> meck:validate(dog). true 5> meck:unload(dog). ok 6> dog:bark(). ** exception error: undefined function dog:bark/0 7> meck:expect(dog, meow, fun() -> meck:exception(error, not_a_cat) end). ok 8> catch dog:meow(). {'EXIT',{not_a_cat,[{meck,exception,2}, {meck,exec,4}, {dog,meow,[]}, {erl_eval,do_apply,5}, {erl_eval,expr,5}, {shell,exprs,6}, {shell,eval_exprs,6}, {shell,eval_loop,3}]}} 9> meck:validate(dog). true
项目地址: https://github.com/eproxus/meck
还有一个gen_server_mock.erl 也可以看一下: https://github.com/jashmenn/gen_server_mock
Poolboy
init([]) -> {ok, Pools} = application:get_env(example, pools), PoolSpecs = lists:map(fun({Name, SizeArgs, WorkerArgs}) -> PoolArgs = [{name, {local, Name}}, {worker_module, example_worker}] ++ SizeArgs, poolboy:child_spec(Name, PoolArgs, WorkerArgs) end, Pools), {ok, {{one_for_one, 10, 10}, PoolSpecs}}. squery(PoolName, Sql) -> poolboy:transaction(PoolName, fun(Worker) -> gen_server:call(Worker, {squery, Sql}) end). equery(PoolName, Stmt, Params) -> poolboy:transaction(PoolName, fun(Worker) -> gen_server:call(Worker, {equery, Stmt, Params}) end).
Eshell V5.9 (abort with ^G) 1> fsm_demo:start(abc). {ok,<0.34.0>} 2> {_,Pid}=v(1). {ok,<0.34.0>} 3> erlang:process_info(Pid). [{registered_name,fsm_demo}, {current_function,{gen_fsm,loop,7}}, {initial_call,{proc_lib,init_p,5}}, {status,waiting}, {message_queue_len,0}, {messages,[]}, {links,[]}, {dictionary,[{'$ancestors',[<0.32.0>]}, {'$initial_call',{fsm_demo,init,1}}]}, {trap_exit,false}, {error_handler,error_handler}, {priority,normal}, {group_leader,<0.25.0>}, {total_heap_size,233}, {heap_size,233}, {stack_size,10}, {reductions,20}, {garbage_collection,[{min_bin_vheap_size,46368}, {min_heap_size,233}, {fullsweep_after,65535}, {minor_gcs,0}]}, {suspending,[]}] 4> sys:get_status(fsm_demo). {status,<0.34.0>, {module,gen_fsm}, [[{'$ancestors',[<0.32.0>]}, {'$initial_call',{fsm_demo,init,1}}], running,<0.34.0>,[], [{header,"Status for state machine fsm_demo"}, {data,[{"Status",running}, {"Parent",<0.34.0>}, {"Logged events",[]}, {"StateName",locked}]}, {data,[{"StateData",{[],abc}}]}]]} 5>
2012年12月18日 14:10:24 补记
Eshell V5.9 (abort with ^G) 1> T={a,12,"good_man",<<2,3,4>>}. {a,12,"good_man",<<2,3,4>>} 2> io:format("Data Dump:~p",[T]). Data Dump:{a,12,"good_man",<<2,3,4>>}ok 3> rd(a,{age,name,desc}). a 4> io:format("Data Dump:~p",[T]). Data Dump:{a,12,"good_man",<<2,3,4>>}ok 5> T2=T. #a{age = 12,name = "good_man",desc = <<2,3,4>>} 6> io:format("Data Dump:~p",[T2]). Data Dump:{a,12,"good_man",<<2,3,4>>}ok 7> io:format(io_lib_pretty:print(T, fun(a, 3) -> [age,name,desc] end)). #a{age = 12,name = "good_man",desc = <<2,3,4>>}ok 8>
2012-12-19 21:55 补记
今天群里面有人问到:一个进程被压了很多消息,处理速度变慢,开启了SMP更慢,何解?
这个和timer的情况很类似:
Creating timers using erlang:send_after/3 and erlang:start_timer/3 is much more efficient than using the timers provided by the timer module. The timer module uses a separate process to manage the timers, and that process can easily become overloaded if many processes create and cancel timers frequently (especially when using the SMP emulator).
http://www.erlang.org/doc/efficiency_guide/commoncaveats.html#id62547
最后小图一张: