[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試一下吧
 
 
最后一張小圖

 
 晚安!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM