Created
October 24, 2012 08:24
-
-
Save lhwork/3944817 to your computer and use it in GitHub Desktop.
Erlang代码片段
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.列表操作 | |
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}}] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment