• 【转】Erlang代码片段


    转自: http://blogold.chinaunix.net/u3/104903/showart_2074188.html

    .列表操作

    lists:foreach (fun(X) -> io:format("E=~p~n",[X]) end, [1,2,3]).

    lists:duplicate (10, 16#f).  % [15,15,15,15,15,15,15,15,15,15]

    "abc-123" -> "abc"

    no_vsn(Name) -> lists:takewhile (fun($-)->false;(_)-> true end,Name).

    "abc-123" -> "123"

    vsn(Name) ->

        case lists:dropwhile (fun($-)->false;(_)->true end,Name) of

        [_Sep|Vsn] -> Vsn;

        _ -> "0"

        end.

    取偶数

    EvenN = lists:filter (fun (N) -> N rem 2 == 0 end, lists:seq (1,100))

    折叠

    lists:foldl (fun(F, Last) -> F(Last) end, foo(), [fun whee/1, fun bar/1])

    Fun = fun
        (A = #auth{dir = [Dir]}, Acc) -> [{Dir, A}| Acc];
        (A, Acc) -> [A| Acc]
    end,
    Authdirs = lists:foldr(Fun, [], SC#sconf.authdirs),

    将URL中的空格换成+
    UW = lists:map (fun($ )->$+;(C)->C end,Words)

    判断是否为空格

    is_nb_space(X) ->
        lists:member (X, [$\s, $\t]).

    >Data = [{"apple", "red"}, {"banana", "yellow"}, {"pear", "white"}].

    >lists:keymember ("pear",1,Data).

      true

    >lists:keydelete ("banana",1,Data).
      [{"apple","red"},{"pear","white"}]

    >lists:keyreplace ("apple",1,Data,{"tomato", "red"}).
      [{"tomato","red"},{"banana","yellow"},{"pear","white"}]

    > rd(user,{id,name}).   %% 用户记录

    > lists:keysearch ("wang", #user.name, [#user{id=1,name="li"}, #user{id=2,name="wang"}]).

    > {value,#user{id = 2,name = "wang"}}

    case lists:any(fun(Str) -> lists:prefix(Str, "redColor") end, ["apple","red"]) of
       true -> {ok, Num, [H|T]};
       false -> false
    end


    .二进制操作

    -define(BYTE, 8/unsigned-big-integer).

    <<C:2/unit :?BYTE>> 意思就是取两个单位,每单位8bits。

    unit的默认值取决于type,如果type是integer或者float,则为1,binary为8。

    <<C:4/binary, _/binary>> 意思就是取4个单位,每单位8比特,总共4*8比特

    1>A = <<1:32/little,1:8/little>>.   %低位在前
    <<1,0,0,0,1>>
    2> B = <<1:32/big,1:8/big>>.        %高位在前
      <<0,0,0,1,1>>
    3> C = <<1:1,0:1>>.
    <<2:2>>


    > B = <<3.2:32/big-float>>.
    > io:format("~w~n", [B]).
    > <<64,76,204,205>>
    > <<R:32/big-float>> = B.
    > R.
    > 3.200000047683716

    << PointID:32/unsigned-little-integer, Value:32/little-float>> = Bin.


    对于utf相关类型,不能指定unit spec

    utf8匹配1-4个bytes(参考RFC-2279)
    utf16匹配2 或 4 个bytes (参考 RFC-2781)
    utf32匹配4个 bytes


    1> <<1024/utf8>>.
    <<208,128>>
    2> <<1024/utf16>>.
    <<4,0>>
    3> <<1024/utf32>>.
    <<0,0,4,0>>
    4> Bin = <<1024/utf8>>.
    <<208,128>>
    5> <<U/utf8>> = Bin.
    <<208,128>>
    6> U.
    1024


    .Binary Comprehensions

    << <<case X of $a -> $X; _ -> $Y end>> || <<X>> <= <<"abcaa">> >>.


    返回: <<"XYYXX">>

    << <<X>> || <<X:1>>  <= <<255, 3:2>> >>.

    返回: <<1,1,1,1,1,1,1,1,1,1>>

    .位操作

        O2 = ((C1 band 16#03) bsl 4) bor (C2 bsr 4).

    . 文件操作

    Destination = filename:join ([code:root_dir(), "include", no_vsn( New_lib )]),

    file:make_dir (Destination),

    lists:foreach( fun(File) ->

        FileName = lists:last(string:tokens(File,"/\\")),

        file:copy (File, filename:join([Destination,FileName]))

        end,

        filelib:wildcard (filename:join([Source,"*"])) ).

    w_ctl_file(Sid, Port, Key) ->
    case catch
       begin
         F = yaws:ctl_file(Sid),
         error_logger:info_msg("Ctlfile : ~s~n", [F]),
         file:write_file(F, io_lib:format("~w.", [{Port,Key}])),
        {ok, FI} = file:read_file_info(F),
        ok = file:write_file_info(F, FI#file_info{mode = 8#00600})
       end of
       {'EXIT', _} -> error;
       _ -> ok
    end.

    remove(Path, File) ->
        Desc = filename:join([Path,File]),
        case filelib:is_dir (Desc) of
        true ->
            case file:list_dir (Desc) of
            {ok,Sub} -> lists:foreach(fun(S) -> remove(Desc,S) end,Sub);
            {error,Reason} -> io:format("error: ~p~n",[Reason])
            end,
            file:del_dir (Desc);
        false ->
            file:delete (Desc)
        end.

    file:write_file("test.txt", "12 13 14 15 16 17 18").

    {ok, Bin } = file:read_file (File ),

    Rules = string:tokens (erlang:binary_to_list (Bin), "\n").

    case file:open(File, [write]) of
            {ok, FD} ->
                %io:put_chars(FD, Text), <-- ERROR
                ok = file:close(FD),

                file:write_file(File, unicode:characters_to_binary(Text));   <-- HACK

            {error, R} ->
                R1 = file:format_error(R),
                report("could not write file '~s': ~s.", [File, R1]),
                exit(error)

    end.

    file:open(File, [write, {encoding, utf8}]).

    {ok, Fd} = file:open("test_data.dat", [binary, write]),
    ok = file:write(Fd, lists:duplicate(100, "1")),
    ok = file:close(Fd).
     

    .日期,时间操作

    {{Y,M,D},{H,M,S}} = calendar:local_time ().

    calendar:day_of_the_week (2009,2,24).

    next_day({Y, M, D}) ->
        Day1 = calendar:date_to_gregorian_days (Y, M, D),
        calendar:gregorian_days_to_date (Day1 + 1).

    w3cdtf(GregSecs) ->

        Date = calendar:gregorian_seconds_to_datetime(GregSecs),
        {{Y, Mo, D},{H, Mi, S}} = Date,
        [UDate|_] = calendar:local_time_to_universal_time_dst(Date),
        {DiffD,{DiffH,DiffMi,_}}=calendar:time_difference(UDate,Date).

    .字符串操作

    count_chars(String, Char) ->
        length ([X || X <- String, X == Char]).

    格式化字符串, 像C语言的sscanf()

    Cmd = io_lib:format (\"cd ~s/include; rm ~s; ln -s ../lib/~s/include ~s\", [code:root_dir(), no_vsn( New_lib ), New_lib, no_vsn( New_lib )]),

    os:cmd(Cmd);

    PN = [erlang:list_to_integer(N) || N <- string:tokens ( vsn( Package_that_might_be_newer ), "." )],

    packages_from_html(Html,Packages) ->
        case string:str (Html,"class=\"package\"") of
        0 -> Packages;
        Start ->
            Sub = string:sub_string(Html,Start),
            T1 = string:sub_string(Sub,string:chr(Sub,$>)+1),
            PName = string:sub_string (T1,1,string:chr(T1,$<)-1),
            T2 = string:sub_string(T1,string:str(T1,"<i>")+3),
            Descr = string:sub_string(T2,1,string:str(T2,"</i>")-1),
            packages_from_html(T2,[{PName,Descr}|Packages])
        end.

    当使用Erlang程序与其它语言程序通讯时,可能需要把一个字符串转换成为Erlang的Term,可以这样实现
    {ok, Tokens, _} = erl_scan:string(String),
    {ok, Term} = erl_parse:parse_term(Tokens).
    注意这里的String需要以句号结尾。

    例如在erlang shell下:
    > {ok, Tokens, _} = erl_scan:string("{1, {2}, [3]}.").
    > {ok, {X, Y, Z}} = erl_parse:parse_term(Tokens).

    .端口操作

    1>Port = open_port({spawn, "cat"}, [stream]).
    #Port<0.522>
    2> port_command(Port, "Hello World\n").
    true
    3> flush().
    Shell got {#Port<0.522>,{data,{eol,"Hello World\n"}}}
    ok
    4> port_close(Port).
    true


    spawn_link(fun() -> tbz2(YPid, Dir) end),

    tbz2(YPid, Dir) ->
       process_flag(trap_exit, true), 
       P = open_port({spawn, "tar cj ."},[{cd, Dir},use_stdio, binary, exit_status]),
       stream_loop(YPid, P).

    stream_loop(YPid, P) ->
    receive
       {P, {data, Data}} ->
         yaws_api:stream_chunk_deliver_blocking(YPid, Data),
         stream_loop(YPid, P);
       {P, {exit_status, _}} ->
         yaws_api:stream_chunk_end(YPid);
       {'EXIT', YPid, Status} ->
        exit(Status);
       Else ->
        error_logger:error_msg("Could not deliver zip file: ~p\n", [Else])
    end.

    getuid() ->
          case os:type() of
              {win32, _} -> {ok, "0"};
              _ ->
                  load_setuid_drv(),
                  P = open_port({spawn, "setuid_drv g"},[]),
                  receive
                      {P, {data, "ok " ++ IntList}} ->  {ok, IntList}
                  end
          end.

    load_setuid_drv() ->
          Path = case yaws_generated:is_local_install() of
              true -> filename:dirname(code:which(?MODULE)) ++ "/../priv/lib";
              false ->
                  PrivDir = code:priv_dir(yaws),
                  filename:join(PrivDir,"lib")
          end,
          case erl_ddll:load_driver(Path, "setuid_drv") of
              ok -> ok;
             {error, Reason} ->
                  error_logger:format("Failed to load setuid_drv (from ~p) : ~p",[Path, erl_ddll:format_error(Reason)]),
                  exit(normal)
         end.


    例外处理


    call(URL, Options, Payload) ->
    try
       {ok, CallPayloadDeep} = encode_call_payload(Payload),
       CallPayload = lists:flatten(CallPayloadDeep),
       {ok, Response} = http:request(post, {URL,
           [{"Content-length",length(CallPayload)}],
           "application/x-www-form-urlencoded",CallPayload},Options, []),

       RespBody= if (size(Response) == 2) or (size(Response) == 3) ->
                    element(size(Response), Response)
                 end,
       decode_call_payload(RespBody)
    catch error:Err -> error_logger:error_report([
                             {'json_rpc:call', error},{error, Err},
                             {stack, erlang:get_stacktrace()}]),
                       {error,Err}

    catch _:_ -> ignore
    end .

    validate(A, B) ->
    try
       mnesia:transaction((fun my_funky_mnesia_test/2)(A,B))
    catch
       exit:{aborted, all_valid} -> ok;
       exit:{aborted, Error} -> {error, Error}
    end.

    -spec my_funky_mnesia_test(some_t(), another_t()) -> no_return().

    my_funky_mnesia_test(A, B) ->
       some_test_db_operations(A, B),
       mnesia:abort(all_valid).


    嵌套记录


    -record(name, {first = "Robert", last = "Ericsson"}). 
    -record(person, {name = #name{}, phone}). 
    demo() -> 
       P = #person{name= #name{first="Robert",last="Virding"}, phone=123}, 
       First = (P#person.name)#name.first.  
    动态运行代码


    1> FunStr = "fun (A) -> A+B end.".
    2> {ok, Tokens, _} = erl_scan:string(FunStr).
    3> {ok, [Form]} = erl_parse:parse_exprs(Tokens).
    4> Bindings = erl_eval:add_binding('B', 2, erl_eval:new_bindings()).
    5> {value, Fun, _} = erl_eval:expr(Form, Bindings).
    6> Fun(1).


    remote_load_code(Module, Node) ->
        {_, Binary, Filename} = code:get_object_code(Module),
        rpc:call(Node, code, load_binary, [Module, Filename, Binary])


    进程关系


    Start the supervisor:

    1> {ok, Sup} = supervisor:start_link(ignore_sup, []).
    {ok,<0.43.0>}

    It has no children:

    2> supervisor:which_children(Sup).
    []

    Starting the child:

    3> supervisor:start_child(Sup, []).

    =ERROR REPORT==== 13-Apr-2011::18:59:01 ===
    Ignoring: <0.46.0>
    {ok,undefined}

    The child specification is installed:

    4> supervisor:which_children(Sup).
    [{undefined,undefined,worker,[ignore_server]}]

    But the child process reported above is not alive:

    5> is_process_alive(list_to_pid("<0.46.0>")).
    false


    进制转换


    integer_to_hex(I) ->
          case catch erlang:integer_to_list(I, 16) of
              {'EXIT', _} ->
                   old_integer_to_hex(I);
              Int ->
                   Int
          end.


    old_integer_to_hex(I) when I<10 ->
          integer_to_list(I);
    old_integer_to_hex(I) when I<16 ->
          [I-10+$A];
    old_integer_to_hex(I) when I>=16 ->
          N = trunc(I/16),
          old_integer_to_hex(N) ++ old_integer_to_hex(I rem 16).


    %% hex_to_integer

    hex_to_integer(Hex) ->
          erlang:list_to_integer(Hex, 16).

    %% string_to_hex

    string_to_hex(String) ->
          HEXC = fun (D) when D > 9 -> $a + D - 10;
                     (D) -> $0 + D
                 end,
          lists:foldr(fun (E, Acc) ->
                  [HEXC(E div 16),HEXC(E rem 16)|Acc] end, [], String).


    %% hex_to_string

    hex_to_string(Hex) ->
          DEHEX = fun (H) when H >= $a -> H - $a + 10;
                      (H) when H >= $A -> H - $A + 10;
                      (H) -> H - $0
                  end,
      {String, _} =lists:foldr(fun

               (E, {Acc, nolow}) -> {Acc, DEHEX(E)};
               (E, {Acc, LO}) -> {[DEHEX(E)*16+LO|Acc], nolow}
          end, {[], nolow}, Hex),
          String.


    数据结构


    stdlib中包含大量的数据结构如lists,array,dict,gb_sets,gb_trees,ets,dets等


    .gb_trees
    1>X = gb_trees:from_orddict(orddict:from_list([{trace,false},{limit,-1},{timeout,-1}])).
    {3,{timeout,-1,{limit,-1,nil,nil},{trace,false,nil,nil}}}

    2>gb_trees:update(limit,true,X).
    {3,{timeout,-1,{limit,true,nil,nil},{trace,false,nil,nil}}}


    .ets/dets

    E = ets:new (my_code, [public, set]),
    ets:match_delete  (E,'_'),

    ets:insert (E, {num_files, 0}),
    ets:insert(E, {num_bytes, 0}).

    %% T = ets:new(?MODULE, [{write_concurrency, true}]).

    {ok,?MODULE}=dets:open_file(?MODULE,[{type,set},{file,"fcnum.dets"}]),
    dets:insert(?MODULE, {1, [1,2,3,4,5,6,7]}),

    dets:insert(?MODULE, {1, [7,6,5,4,3,2,1]}),
    dets:close (?MODULE).

    >Table = ets:new(foobar, [set, public]).
    >ets:tab2list (Table).
    []
    > ets:insert(Table, {1}).
    true
    > ets:insert(Table, {2}).
    true
    > ets:tab2list(Table).
    [{1},{2}]


    1> rd(data, {id, nick}).
    data
    2> rd(wrapper, {id, data}).
    wrapper

    3> L = [#wrapper{id=1,data=#data{id=1}}, #wrapper{id=2,data=#data{id=2,nick=n}}].
    [#wrapper{id = 1,data = #data{id = 1,nick = undefined}},
    #wrapper{id = 2,data = #data{id = 2,nick = n}}]

    4> qlc:e(qlc:q([W || #wrapper{data = #data{nick = N}} = W <- L, N =/= undefined])).
    [#wrapper{id = 2,data = #data{id = 2,nick = n}}]

    本文来自CSDN博客,转载请标明出处:http://blogold.chinaunix.net/u3/104903/showart_2074188.html

  • 相关阅读:
    phpmyadmi 上传大文件
    wget 命令用法详解
    cuDnn的安装ubuntu16.04环境下(tensorflow正式安装之前的必备安装操作)
    ubuntu16.04 源码安装Python3.7 (可以在此基础上安装Tensorflow) (确保Tensorflow计算框架与系统的彻底隔离)
    大工软件学院 校园网登录脚本
    UML图 之 活动图 (汇总版)
    详解UML图之类图 (转)
    Java中private、protected、public和default的区别 (转)
    AI产业将更凸显个人英雄主义 周志华老师的观点是如此的有深度
    对什么样的人应该敬而远之
  • 原文地址:https://www.cnblogs.com/samis/p/2061242.html
Copyright © 2020-2023  润新知