[Erlang 0043] Erlang Code Snippet

简介:
在使用Erlang开发过程中我们会积累一些常用的util方法,同时会把一些方便编译调试的方法放在Erlang的user_default模块.今天翻阅Evernote发现两段非常实用的代码片段,由于google codesearch服务已经关闭,源头不可追溯,好东西不可独享,和大家分享.
本文会持续更新补充内容.
 
复制代码
-module(u).
-compile(nowarn_unused_function).
-compile(export_all).

trace(X) -> spawn(fun() -> io:format("~p~n",[X]) end).
trace(X,Y) -> spawn(fun() -> io:format("~p: ~p~n",[X,Y]) end).
traceBinary(X) -> spawn(fun() -> io:format("~p~n",[b2h(X)]) end).

for(Max, Max, F) -> [F(Max)];
for(I, Max, F) -> [F(I)|for(I+1, Max, F)].


b2h(Bin) -> lists:flatten([io_lib:format("~2.16.0B", [X]) || X <- binary_to_list(Bin)]).
h2b(String) -> << << (erlang:list_to_integer([Char], 16)):4/integer >> || Char <- String >>.
t(String)-> h2b(String).
txt(Bin) -> [X || <<X>> <= Bin,X > 32, X < 127, X =/= 45].
b2s(Bin) -> b2s1(binary_to_list(Bin),[]).
b2s1([],Str) -> lists:reverse(Str);
b2s1([H|T],Str) ->
case H > 32 andalso H < 127 andalso H =/= 45 of
true -> b2s1(T,[H|Str]);
false -> b2s1(T,[46,46|Str])
end.

pmap(F, L,Parent) -> [receive {Pid, Res} -> Res end || Pid <- [spawn(fun() -> Parent ! {self(), F(X)} end) || X <- L]].

timer(Time,Fun) -> spawn(fun() -> receive after Time -> ?MODULE:Fun() end end).


signSubtract(A,B) ->
case A<0 of
true -> (erlang:abs(A)-erlang:abs(B))*-1;
false -> (erlang:abs(A)-erlang:abs(B))
end.

signSubtract1(A,B) ->
case A<0 of
true -> (erlang:abs(A)-B)*-1;
_ -> (erlang:abs(A)-B)
end.

%% u:floor(-4.7).
%% Output: -5
floor(X) when X < 0 ->
T = trunc(X),
case (X - T) =:= 0 of
true -> T;
false -> T - 1
end;
floor(X) -> trunc(X).

%%添加协议头
addLen(Bin) ->
Len=erlang:size(Bin)+2,
<<Len:16,Bin/binary>>.
复制代码
 

user_default

   [Erlang 0027] Using Record in Erlang Shell 一文中我们已经提到过user_default的用法,不过上次只是小试牛刀用来加载record的定义而已,看看下面的方法;注意这些方法可以直接在Erlang Shell中使用的哦
 
     Erlang doc link : http://www.erlang.org/documentation/doc-5.4.12/lib/stdlib-1.13.11/doc/html/shell.html

If a command (local function call) is not recognized by the shell, an attempt is first made to find the function in the module user_default, where customized local commands can be placed. If found, then the function is evaluated. Otherwise, an attempt is made to evaluate the function in the module shell_default. The module user_default must be explicitly loaded.

There is some support for reading and printing records in the shell. During compilation record expressions are translated to tuple expressions. In runtime it is not known whether a tuple actually represents a record. Nor are the record definitions used by compiler available at runtime. So in order to read the record syntax and print tuples as records when possible, record definitions have to be maintained by the shell itself. The shell commands for reading, defining, forgetting, listing, and printing records are described below. Note that each job has its own set of record definitions. To facilitate matters record definitions in the modules shell_default and user_default (if loaded) are read each time a new job is started.

复制代码
-module(user_default).
-compile(export_all).

z(File) ->
Out=compile:file(["./src/", atom_to_list(File),".erl"],
[{outdir,"./ebin/"}, {i,"./src/"},report,debug_info ]),
lm(),
Out.

x(File) ->
Out=compile:file(["./test/", atom_to_list(File),".erl"],
[ {outdir,"./ebin/"}, {i,"./src/"},report,debug_info ]),
lm(),
Out.

s(App) ->
application:start(App).

r(App) ->
application:stop(App),
% os:cmd("ebin ./src/*.erl -I ./include/ +debug_info"),
make:all(),
make:all([load]),
lm(),
application:start(App).

zz(File) ->
?MODULE:z(File),
File:start().

xx(File) ->
?MODULE:x(File),
File:start().

rbb() ->
rb:start([{max,20}]).

rbb(Num) -> rb:start([{max,Num}]).

rbl() -> rb:list().

rbs(Num) ->
rb:show(Num).

test() ->
reloader:reload_modules(reloader:all_changed()).

ll() ->
make:all(),
lm().
lm() -> [c:l(M) || M <- mm()].
mm() -> modified_modules().
modified_modules() ->
[M || {M,_} <- code:all_loaded(), module_modified(M) == true].
module_modified(Module) ->
case code:is_loaded(Module) of
{file,preloaded} ->
false;
{file,Path} ->
CompileOpts = proplists:get_value(compile,Module:module_info()),
CompileTime = proplists:get_value (time,CompileOpts),
Src = proplists:get_value (source,CompileOpts),
module_modified (Path,CompileTime,Src);
_ -> false
end.

module_modified(Path,PrevCompileTime,PrevSrc) ->
case find_module_file(Path) of
false -> false;
ModPath -> case beam_lib:chunks(ModPath, ["CInf"]) of
{ok, {_, [{_, CB}]}} ->
CompileOpts = binary_to_term(CB),
CompileTime = proplists:get_value(time,CompileOpts),
Src = proplists:get_value(source,CompileOpts),
not (CompileTime == PrevCompileTime) and (Src == PrevSrc);
_ -> false
end
end.

find_module_file(Path) ->
case file:read_file_info(Path) of
{ok,_} -> Path;
_ -> % maybe path was changed
case code:where_is_file(filename:basename(Path)) of
non_existing -> false;
NewPath -> NewPath
end
end.
复制代码
 
2012-11-20 09:28 更新 新增一版
 
复制代码
-module(user_default).

-export([sync/0]).
-export([make/0]).
-export([git/1]).
-export([reload/0]).
-export([reload_then/1]).

-export([dbg/0]).
-export([dbg/1]).
-export([dbg/2]).
-export([dbg/3]).
-export([dbg/4]).

-export([tc_avg/4]).

-compile(inline).

%% Reload code
reload() ->
    LibExclude = base_lib_path(),
    Modules = [M || {M, P} <- code:all_loaded(), is_list(P) andalso string:str(P, LibExclude) =:= 0],
    [shell_default:l(M) || M <- Modules].

%% Reload code then exec F
reload_then(F) ->
    reload(),
    F().

%% Compiles all files in Emakefile and load into current shell.
sync() ->
    make:all([load]).

%% Run the make command in shell.
make() ->
    run_command(["make", "all"]).

%% Run git command in shell.
git(Command) ->
    CommandList = ["git", Command],
    run_command(CommandList).

dbg()                           -> dbg:tracer().

dbg(c)                          -> dbg:stop_clear();
dbg(M)                          -> dbge({M, '_', '_'}, []).

dbg(M, c)                       -> dbgc({M, '_', '_'});
dbg(M, r)                       -> dbge({M, '_', '_'}, dbg_rt());
dbg(M, l)                       -> dbgl({M, '_', '_'}, []);
dbg(M, lr)                      -> dbgl({M, '_', '_'}, dbg_rt());
dbg(M, F) when is_atom(F)       -> dbge({M,   F, '_'}, []);
dbg(M, O)                       -> dbge({M, '_', '_'}, O).

dbg(M, F, c)                    -> dbgc({M,   F, '_'});
dbg(M, F, l)                    -> dbgl({M,   F, '_'}, dbg_rt());
dbg(M, F, r)                    -> dbge({M,   F, '_'}, dbg_rt());
dbg(M, F, lr)                   -> dbgl({M,   F, '_'}, dbg_rt());
dbg(M, F, A) when is_integer(A) -> dbge({M,   F,   A}, []);
dbg(M, F, O)                    -> dbge({M,   F, '_'}, O).

dbg(M, F, A, c)                 -> dbgc({M,   F,   A});
dbg(M, F, A, r)                 -> dbge({M,   F,   A}, dbg_rt());
dbg(M, F, A, l)                 -> dbgl({M,   F,   A}, dbg_rt());
dbg(M, F, A, lr)                -> dbgl({M,   F,   A}, dbg_rt());
dbg(M, F, A, O)                 -> dbge({M,   F,   A}, O).

tc_avg(M, F, A, N) when N > 1 ->
    L = tl(lists:reverse(tc_loop(M, F, A, N, []))),
    Length = length(L),
    Min = lists:min(L),
    Max = lists:max(L),
    Med = lists:nth(round((Length / 2)), lists:sort(L)),
    Avg = round(lists:foldl(fun(X, Sum) -> X + Sum end, 0, L) / Length),
    io:format("Range: ~b - ~b mics~n"
              "Median: ~b mics~n"
              "Average: ~b mics~n",
              [Min, Max, Med, Avg]),
    Med.

tc_loop(_M, _F, _A, 0, List) ->
    List;
tc_loop(M, F, A, N, List) ->
    case timer:tc(M, F, A) of
        {_T, {'EXIT', Reason}} -> exit(Reason);
        {T, _Result} -> tc_loop(M, F, A, N - 1, [T|List])
    end.

%%%% Private Functions

run_command(CommandList) ->
    Result = os:cmd(string:join(CommandList, " ")),
    io:format("~s~n", [Result]).

dbgc(MFA)    -> dbg:ctp(MFA).
dbge(MFA, O) -> dbg:tracer(), dbg:p(all, call), dbg:tp(MFA, O).
dbgl(MFA, O) -> dbg:tracer(), dbg:p(all, call), dbg:tpl(MFA, O).
dbg_rt() -> x.

base_lib_path() ->
    KernAppPath = code:where_is_file("kernel.app"),
    string:substr(KernAppPath, 1, string:str(KernAppPath,"kernel") - 1).
复制代码

 

2012-11-20 09:36 补充一版

 
复制代码
%%
%% ----------------------------------------------------------------------------
%% "THE BEER-WARE LICENSE" (Revision 42.1):
%% <gustav.simonsson@gmail.com> wrote this file.
%% As long as you retain this notice you
%% can do whatever you want with this stuff. If we meet some day, and you think
%% this stuff is worth it, you can buy me a beer in return. 
%% ----------------------------------------------------------------------------
%%
%%%-------------------------------------------------------------------
%%% @author Gustav Simonsson <gustav.simonsson@gmail.com>
%%% @doc
%%%
%%% Miscellaneous Erlang function collection.
%%%
%%% @end
%%% Created : 29 Nov 2011 by Gustav Simonsson <gustav.simonsson@gmail.com>
%%%-------------------------------------------------------------------
-module(gs_util).

-compile(export_all).

words(Words) ->
    lists:flatten([0|| _X <- lists:seq(1, Words div 2)]).

substrings(S) -> 
    Slen = length(S),
    [string:sub_string(S,B,E) || 
        B <- lists:seq(1, Slen), E <- lists:seq(B, Slen)].

get_file_lines(F) ->
    get_file_lines_acc(F, []).
get_file_lines_acc(F, Acc) ->
    case file:read_line(F) of
        eof ->
            Acc;
        {ok, Data} ->
            get_file_lines_acc(F, [Data | Acc])
    end.

p(S, S2) ->
    io:format("~n~p:~n~p~n", [S, S2]).

int_to_month(Int) ->
    lists:nth(Int, [jan, feb, mar, apr, may, jun, jul, aug,
                    sep, oct, nov, dec]).

fat_processes() ->
    fat_processes(10).
fat_processes(C) ->
    L = lists:sort([{proplists:get_value(heap_size,L),
                     P,
                     proplists:get_value(initial_call, L),
                     proplists:get_value(current_function, L)}
                    ||{L,P} <- [{process_info(P), P} || P <- processes()]]),
    lists:reverse(lists:nthtail(length(L) - C, L)).

t(Mod, Fun, Args) ->
    dbg:stop_clear(),
    dbg:start(),
    dbg:tracer(),
    dbg:p(all,c),
    dbg:tpl(Mod, Fun, Args).

intervals(Start, Stop, _) when Start > Stop ->
    [];
intervals(Start, Stop, N) when Start == Stop; (Start + N) > Stop ->
    [{Start, Stop}];
intervals(Start, Stop, N) ->
    [{Start, Start + N} | intervals(Start + N + 1, Stop, N)].
复制代码

 

2012-11-23 09:49

复制代码
-module(user_default).

-export([sync/0]).
-export([make/0]).
-export([git/1]).
-export([reload/0]).
-export([reload_then/1]).

-export([dbg/0]).
-export([dbg/1]).
-export([dbg/2]).
-export([dbg/3]).
-export([dbg/4]).

-export([tc_avg/4]).

-compile(inline).

%% Reload code
reload() ->
    LibExclude = base_lib_path(),
    Modules = [M || {M, P} <- code:all_loaded(), is_list(P) andalso string:str(P, LibExclude) =:= 0],
    [shell_default:l(M) || M <- Modules].

%% Reload code then exec F
reload_then(F) ->
    reload(),
    F().

%% Compiles all files in Emakefile and load into current shell.
sync() ->
    make:all([load]).

%% Run the make command in shell.
make() ->
    run_command(["make", "all"]).

%% Run git command in shell.
git(Command) ->
    CommandList = ["git", Command],
    run_command(CommandList).

dbg()                           -> dbg:tracer().

dbg(c)                          -> dbg:stop_clear();
dbg(M)                          -> dbge({M, '_', '_'}, []).

dbg(M, c)                       -> dbgc({M, '_', '_'});
dbg(M, r)                       -> dbge({M, '_', '_'}, dbg_rt());
dbg(M, l)                       -> dbgl({M, '_', '_'}, []);
dbg(M, lr)                      -> dbgl({M, '_', '_'}, dbg_rt());
dbg(M, F) when is_atom(F)       -> dbge({M,   F, '_'}, []);
dbg(M, O)                       -> dbge({M, '_', '_'}, O).

dbg(M, F, c)                    -> dbgc({M,   F, '_'});
dbg(M, F, l)                    -> dbgl({M,   F, '_'}, dbg_rt());
dbg(M, F, r)                    -> dbge({M,   F, '_'}, dbg_rt());
dbg(M, F, lr)                   -> dbgl({M,   F, '_'}, dbg_rt());
dbg(M, F, A) when is_integer(A) -> dbge({M,   F,   A}, []);
dbg(M, F, O)                    -> dbge({M,   F, '_'}, O).

dbg(M, F, A, c)                 -> dbgc({M,   F,   A});
dbg(M, F, A, r)                 -> dbge({M,   F,   A}, dbg_rt());
dbg(M, F, A, l)                 -> dbgl({M,   F,   A}, dbg_rt());
dbg(M, F, A, lr)                -> dbgl({M,   F,   A}, dbg_rt());
dbg(M, F, A, O)                 -> dbge({M,   F,   A}, O).

tc_avg(M, F, A, N) when N > 1 ->
    L = tl(lists:reverse(tc_loop(M, F, A, N, []))),
    Length = length(L),
    Min = lists:min(L),
    Max = lists:max(L),
    Med = lists:nth(round((Length / 2)), lists:sort(L)),
    Avg = round(lists:foldl(fun(X, Sum) -> X + Sum end, 0, L) / Length),
    io:format("Range: ~b - ~b mics~n"
              "Median: ~b mics~n"
              "Average: ~b mics~n",
              [Min, Max, Med, Avg]),
    Med.

tc_loop(_M, _F, _A, 0, List) ->
    List;
tc_loop(M, F, A, N, List) ->
    case timer:tc(M, F, A) of
        {_T, {'EXIT', Reason}} -> exit(Reason);
        {T, _Result} -> tc_loop(M, F, A, N - 1, [T|List])
    end.

%%%% Private Functions

run_command(CommandList) ->
    Result = os:cmd(string:join(CommandList, " ")),
    io:format("~s~n", [Result]).

dbgc(MFA)    -> dbg:ctp(MFA).
dbge(MFA, O) -> dbg:tracer(), dbg:p(all, call), dbg:tp(MFA, O).
dbgl(MFA, O) -> dbg:tracer(), dbg:p(all, call), dbg:tpl(MFA, O).
dbg_rt() -> x.

base_lib_path() ->
    KernAppPath = code:where_is_file("kernel.app"),
    string:substr(KernAppPath, 1, string:str(KernAppPath,"kernel") - 1).
复制代码

 

 

 

 是不是省了好多麻烦?打开Shell试一下吧
 
 
最后一张小图

 
目录
相关文章
[Erlang 0125] Know a little Erlang opcode
  Erlang源代码编译为beam文件,代码要经过一系列的过程(见下面的简图),Core Erlang之前已经简单介绍过了Core Erlang,代码转换为Core Erlang,就容易拨开一些语法糖的真面目了.
2273 0
[Erlang 0127] Term sharing in Erlang/OTP 上篇
之前,在 [Erlang 0126] 我们读过的Erlang论文 提到过下面这篇论文:  On Preserving Term Sharing in the Erlang Virtual Machine地址: http://user.
1286 0
|
XML 测试技术 数据格式
|
Shell 自然语言处理 网络协议