[Erlang11] 那些经历过的Erlang小坑11-20

11.每次重装系统时都会重新安装Erlang,Ubuntu安装sh秒杀一切.

     https://gist.github.com/zhongwencool/11174620

12. Erlang Shell隐藏的小技巧:

    f(). %%把所有绑定变量释放掉
    f(Val). %%把Val变量释放掉
    v(Line). %%把Line行函数重新执行一次
    v(-1). %%把前一行的函数重新执行一次
    rr(Module).%%把Module中的Record加载到Shell中,【超有用】
    rr("*/*"). %%把在这个子目录下的所有Module里面的Record给加载到Shell里面
    rp(Expression).%%把Expression的全部元素给打印到shell里面【超有用】
     rl(). %%列出所有已定义过的Record.rf(RecordName).%%不加载名为RecordName的Record
     %%如果你的code加了debug_info信息【compile:file(Module,[debug_info])】你可以这样看源代码
    {ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]),
    io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

13. Erlang中有很多不可逆函数:比如 binary_to_list/1 , list_to_binary/1

  > binary_to_list(list_to_binary([ <<1,2>>,<<3,4>>])).
    [1,2,3,4]

    这个坑有点深,踩过才知道!这还有个和binary一起的小Tip:

   > <<"xyz","ets","bt">> =:= <<"xyzetsbt">>.           
     true

    binary居然是等价的。

14.在保护式里面 ,等价于andalso ;等价于orelse------[但是:不是完全相同,原因如下]

   %%相同点:
right_age(X) when X >= 16, X =< 104 -> %% X>=16 andalso X =< 104 true; right_age(_) –> false.

     不同点:

    %%当Condition1异常出错时,还会去判断Condtion2,如果使用orelse则会直接返回false
    func() when Condition1 ; Condition2 –> 
      ok;
    func() –>
      error.

     可以和http://www.cnblogs.com/zhongwencool/p/3712909.html 第一条对比一下,理解更深哦。

15.如果你想在实践中使用二叉树,请看gb_tree.erl,不要再造不必要的轮子啦,【不过可以考虑用来做练习】

16. 在try catch 的异常处理中禁止使用尾递归:

      因为在这个异常处理部分有一个保护机制,Erlang绝对相信异常处理是正常的,如果你在这里面使用尾递归,会出现以下情况:

    1) 尾递归变死循环啦【项目实践中可能会发生的】;
    2) 非常多的进程进入了这个异常中,这个尾递归处理的东西又非常复杂,VM运行长久后,block大量的进程和消耗内存

      这样的结果是:内存耗尽或程序特别慢,关键你还是查找不到最后的crash的原因。

      所以推荐:异常处理中只使用必要且简单的处理就行了

17. 如果你想在Erlang中 kill一个进程:找到Pid后,exit(Pid,Reasno).【效果和kill一样啦】

      大部分情况不会起作用!!!!!因为在项目里面你的进程如果合规范都是在监控树下的,如果被exit/2后还会被监控树自动重启啦,所以你要先把进程移除监控树!!!

    supervisor:terminate_child(SupPid,Pid), 
    supervisor: delete_child(SupPid,Pid).

18. 2个进程可以双向连接和单向连接:

     双向: link(Pid1,Pid2). 重复调用效果一样,也就是说对同2个进程无论调用多少次link,只要使用一次unlink(Pid1,Pid2)就解除连接

     单向:erlang:monitor/2   erlang: demonitor/1

19. receive  after Time

      这个Time最大值是50*24*60*60*1000,当时间大于50天时,就会报错:

      所以要把Time拆成小于最大值的列表:

  normalize(Time) –>
      Limit = 49*24*60*60,
      [Time rem Limit | lists:duplicate(Time div Limit, Limit)].

      然后如果时间列表不为空就不断减少列表并等待直到列表为空:

  loop([T|Next]}) –>
     receive
        {Server, Ref, cancel} –>
           Server ! {Ref, ok}
        after T*1000 –>
           if Next =:= [] –>
               Server ! {done, S#state.name};
              Next =/= [] –>
              loop(Next})
           end
     end.

20. gen_server里面的handle_call/3 和handle_cast/2返回值都可以加个Timeout时间。

     如果这个时间内没有处理完就会发出一个timeout信息:由handle_info处理,具体可见:http://www.cnblogs.com/zhongwencool/p/erlang_timer.html 里面的方法二。

posted @ 2014-07-10 00:26  写着写着就懂了  阅读(1337)  评论(0编辑  收藏  举报