安裝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
最后小圖一張: