2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Erlangメモ1

Last updated at Posted at 2014-12-16

handle_info/2

If the gen_server should be able to receive other messages than requests, the callback function handle_info(Info, State) must be implemented to handle them. Examples of other messages are exit messages, if the gen_server is linked to other processes (than the supervisor) and trapping exit signals.

handle_info({'EXIT', Pid, Reason}, State) ->
    ..code to handle exits here..
    {noreply, State1}.

io_lib:format, float_to_listを使って小数をフォーマット

6> F = 5/3.
1.6666666666666667
7> io_lib:format("~.1f", [F]).
["1.7"]
8> io_lib:format("~.2f", [F]).
["1.67"]
9> io_lib:format("~.3f", [F]).
["1.667"]
10> F1 = 5/2.
2.5
11> io_lib:format("~.3f", [F1]).
["2.500"]
14> float_to_list(223.665, [{decimals, 0}]).
"224"
15> list_to_integer(float_to_list(223.665, [{decimals, 0}])).
224
16> float_to_list(223.665, [{decimals, 2}]).
"223.67"
17> float_to_list(5/2, [{decimals, 2}]).
"2.50"
18> list_to_integer(float_to_list(5/2, [{decimals, 0}])).
3


mnesia:create_table(employee,[{disc_copies, [node()]}, {attributes, record_info(fields, employee)}])

テーブルはdisc_copiesと定義される場合,アプリケーション再起動するときにディスクからデータをロードしたいときにwait_for_tables/2を使います.

$ erl -mnesia dir '"./Mnesia.Company"'
4> mnesia:start()
5> mnesia:wait_for_tables([employee, dept, project, manager, at_dep, in_proj], 5000).
6> company:select_gender(male).

calendar:datetime_to_gregorian_seconds(DateTime) -> Seconds

This function computes the number of gregorian seconds starting with year 0 and ending at the given date and time.

3> calendar:datetime_to_gregorian_seconds({{2015, 2, 9}, {16,32, 12}}).
63590718732

4> calendar:datetime_to_gregorian_seconds({{2015, 2, 9}, {16,32, 14}}).
63590718734

11> calendar:datetime_to_gregorian_seconds({{0, 1, 1}, {0,0, 1}}).
1

12> calendar:datetime_to_gregorian_seconds({{0, 1, 1}, {0,1, 0}}).
60

13> calendar:datetime_to_gregorian_seconds({{0, 1, 1}, {1,0, 0}}).
3600

lists:subtract(List1, List2) -> List3

lists:subtract(A, B) is equivalent to A -- B. Returns a new list List3 which is a copy of List1, subjected to the following procedure: for each element in List2, its first occurrence in List1 is deleted.

1> lists:subtract("123212", "212").
"312"

dict:fetch_keysは辞書の中のすべてのkeyをリストとして返す

1> D = dict:from_list([{k1,v1}, {k2, v2}, {k3, v3}]).
{dict,3,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],
        [[k1|v1]],
        [[k2|v2]],
        [[k3|v3]],
        [],[],[],[],[],[],[],[],[],[],[],[]}}}
3> L = dict:fetch_keys(D).
[k1,k2,k3]
4> L.
[k1,k2,k3]

timer:sleep(Time|infinity) -> ok

Suspends the process calling this function for Time amount of milliseconds and then returns ok, or suspend the process forever if Time is the atom infinity. Naturally, this function does not return immediately.


ファイルの中の日本語を読み出す

$ erl +pc unicode
1>  {R, Data} = file:open("file", [read, {encoding, utf8}]).
{ok,<0.35.0>}
2> io:get_line(Data, "").
"こんにちは\n"
3>

string:to_integer(String) -> {Int, Rest} | {error, Reason}

tupleを返すことに注意

3> {I1, Is} = string:to_integer("33+22").
{33,"+22"}
4> {I2, I3} = string:to_integer(Is).
{22,[]}
5> f().
ok
6> {I1, Is} = string:to_integer("33/22").
{33,"/22"}
7> {I2, I3} = string:to_integer(Is).
{error,no_integer}

Sub protocols are used for creating new types of handlers that provide extra functionality in a reusable way. Cowboy uses this mechanism to provide its loop, REST and Websocket handlers.
To switch to a sub protocol, the init/2 callback must return the name of the sub protocol module. Everything past this point is handled by the sub protocol.

init(Req, Opts) ->
    {cowboy_websocket, Req, Opts}.

dict:from_list(L)

Key-Value形のリストを辞書に変換する

dict:append(Key, Value, Dict1) -> Dict2

1> L = [{keyA, "A"}, {keyB, "B"}, {keyC, "C"}].
[{keyA,"A"},{keyB,"B"},{keyC,"C"}]

3> D = dict:from_list(L).
{dict,3,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],
        [[keyA,65]],
        [[keyB,66]],
        [[keyC,67]],
        [],[],[],[],[],[],[],[],[],[],[],[]}}}

4> D1 = dict:append(keyD, "D", D).
{dict,4,16,16,8,80,48,
      {[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},
      {{[],
        [[keyA,65]],
        [[keyB,66]],
        [[keyC,67]],
        [[keyD,"D"]],
        [],[],[],[],[],[],[],[],[],[],[]}}}


---
How to get N bits from binary
> You'll need to use bitstring as the type as it will not be a multiple of 8 bits anymore (which the binary type requires). Rest is now 6 bits.

```erlang
23> <<B:2, Rest/bitstring>> = <<2#11000101>>.
<<"Å">>
24> B.
3
25> Rest.
<<5:6>>

binary:match(Subject, Pattern) -> Found | nomatch

戻り値に示しているように結果のoffsetは0から始まる

6> binary:match(<<"/etc/nginx/nginx.conf">>, <<"etc/">>).
{1,4}
7> binary:match(<<"/etc/nginx/nginx.conf">>, <<"etc//">>).
nomatch

e(-1)

reexecute expression on previous line

29> L = filename:split("local/bin").
["local","bin"]
30> e(-1).
["local","bin"]

9> filename:split("/usr/local/bin").
["/","usr","local","bin"]

10> filename:split("/usr/local/bin/").
["/","usr","local","bin"]

11> filename:split("local/bin").
["local","bin"]

12> filename:split("local/bin/").
["local","bin"]

14> filename:split("local/bin/foo").
["local","bin","foo"]

filename:absname(Filename)

Converts a relative Filename and returns an absolute name. No attempt is made to create the shortest absolute name,
because this can give incorrect results on file systems which allow links.

1> pwd().
/home/ec2-user
ok

2> filename:absname("foo").
"/home/ec2-user/foo"
3> filename:absname("../X").
"/home/ec2-user/../X"
4> filename:absname("/").
"/"

5> cd("/etc").
/etc
ok
6> filename:absname("foo").
"/etc/foo"

7> X= <<"foo">>.
<<"foo">>
8> filename:absname(X).
<<"/etc/foo">>

19> base64:encode_to_string("wang zhijun").
"d2FuZyB6aGlqdW4="
20> base64:encode_to_string(ab).
** exception error: no function clause matching
                    base64:encode_to_string(ab) (base64.erl, line 46)

21> base64:encode_to_string(<<"wang zhijun">>).
"d2FuZyB6aGlqdW4="

23> base64:encode_to_string(crypto:rand_bytes(32)).
"h46fo7CSL4Q/94Ji7664Txpw++mgWsnZ2W9TR0tZdSc="

8> lists:nth(5, [1,2,ab, "mike", <<"binary">>]).
<<"binary">>
9> lists:nth(0, [1,2,ab, "mike", <<"binary">>]).
** exception error: no function clause matching
                    lists:nth(0,[1,2,ab,"mike",<<"binary">>]) (lists.erl, line 168)

10> lists:nthtail(0, [1,2,ab, "mike", <<"binary">>]).
[1,2,ab,"mike",<<"binary">>]
11> lists:nthtail(2, [1,2,ab, "mike", <<"binary">>]).
[ab,"mike",<<"binary">>]
12> lists:nthtail(5, [1,2,ab, "mike", <<"binary">>]).
[]

crypto:rand_bytes(N).

rand_bytes(N) -> binary()
Generates N bytes randomly uniform 0..255, and returns the result in a binary. Uses the crypto library pseudo-random number generator.

6> crypto:rand_bytes(64).
<<90,108,103,210,241,40,111,211,250,40,227,216,56,149,110,
  182,219,237,182,157,194,81,207,85,121,56,224,201,18,...>>
7> length(binary_to_list(crypto:rand_bytes(64))).
64
8>

't'

is the Unicode translation modifier

's'

Prints the argument with the string syntax.
The argument is, if no Unicode translation modifier
is present, an iolist(), a binary(), or an atom().
If the Unicode translation modifier (t) is in effect,
the argument is unicode:chardata(), meaning that binaries are in UTF-8.

1> Bin = <<"こんにちは"/utf8>>.
<<227,129,147,227,130,147,227,129,171,227,129,161,227,129,
  175>>
2> lists:keyfind(encoding, 1, io:getopts()).
{encoding,unicode}
3> io:format("~ts~n", [Bin]).
こんにちは
ok
4>

mnesia:delete_object(Record) -> transaction abort | ok

Delete=#user{first_name = "ryan", _ = '_'},
Fun = fun() ->
              List = mnesia:match_object(Delete)
              lists:foreach(fun(X) ->
                                    mnesia:delete_object(X)
                            end, List)
      end,
mnesia:transaction(Fun).

employeeテーブルのEnoレコードに対して、読み込みを行った後、updateを行いたい場合
mnesia:read/3の三つ目のパラメータにwriteロックを掛ける

raise(Eno, Raise) ->
    F = fun() ->
                [E] = mnesia:read(employee, Eno, write),
                Salary = E#employee.salary + Raise,
                New = E#employee{salary = Salary},
                mnesia:write(New)
        end,
    mnesia:transaction(F).

mnesia:create_tableはデフォルトでram_copiesのテーブルを作成します。
最初に作成されたschemaはdisc_copies

$ erl -mnesia dir '"/tmp/funky"'
1> mnesia:create_schema([node()]).
ok
2> mnesia:start().
ok
4> mnesia:create_table(funky, []).
{atomic,ok}
5> mnesia:info().
---> Processes holding locks <---
---> Processes waiting for locks <---
---> Participant transactions <---
---> Coordinator transactions <---
---> Uncertain transactions <---
---> Active tables <---
funky          : with 0        records occupying 282      words of mem
schema         : with 2        records occupying 506      words of mem
===> System info in version "4.12.1", debug level = none <===
opt_disc. Directory "/tmp/funky" is used.
use fallback at restart = false
running db nodes   = [nonode@nohost]
stopped db nodes   = []
master node tables = []
remote             = []
ram_copies         = [funky]
disc_copies        = [schema]
disc_only_copies   = []
[{nonode@nohost,disc_copies}] = [schema]
[{nonode@nohost,ram_copies}] = [funky]
3 transactions committed, 0 aborted, 0 restarted, 2 logged to disc
0 held locks, 0 in queue; 0 local transactions, 0 remote
0 transactions waits for other nodes: []
ok


filelib:is_dir(Name) -> boolean()

The is_dir/1 function returns true if Name refers to a directory, and false otherwise.

AirBox:Desktop wzj$ erl
1> filelib:is_dir("~/Desktop").
false
2> filelib:is_dir("/Users/wzj/Desktop").
true
3> filelib:is_dir(".").
true
5> filelib:is_dir("..").
true

lists:keyfind(Key, Nth, Tuplelist) -> Tuple | false
Searches the list of tuples TupleList for a tuple whose Nth element compares equal to Key. Returns Tuple if such a tuple is found, otherwise false.


iolist_to_binaryの例

1> Bin1 = <<1,2,3>>.
<<1,2,3>>
2> Bin2 = <<4,5>>.
<<4,5>>
3> Bin3 = <<6>>.
<<6>>
4> B = iolist_to_binary([Bin1, 1, [2,3,Bin2], 4  | Bin3]).
<<1,2,3,1,2,3,4,5,4,6>>
5> B = iolist_to_binary([Bin1, 1, [2,3,Bin2], 4  | 9]).
** exception error: bad argument
     in function  iolist_to_binary/1
        called as iolist_to_binary([<<1,2,3>>,1,[2,3,<<4,5>>],4|9])
7> C = iolist_to_binary([Bin1, 1, [2,3,Bin2], 4  | <<9>>]).
<<1,2,3,1,2,3,4,5,4,9>>

list_to_binaryの例

2> list_to_binary(["abcdefg", $h]).
<<"abcdefgh">>
3> list_to_binary(["abcdefg" | <<"h">>]).
<<"abcdefgh">>
4> list_to_binary(["abcdefg" | $h ]).
** exception error: bad argument
     in function  list_to_binary/1
        called as list_to_binary(["abcdefg"|104])
5> list_to_binary(["abcdefg" | <<66>> ]).
<<"abcdefgB">>

list comprehensionの中に複数のステートメントを実行します。beginとendを使用

1> [begin erlang:display(N), N*10 end || N <- lists:seq(1,5)].
1
2
3
4
5
[10,20,30,40,50]

Erlangのrun time systemの中にどんなアプリケーションが動いているかを調べるには下のコマンドを使用する

6> application:which_applications().
[{rpn,"Reverse Polish Notation","1"},
 {stdlib,"ERTS  CXC 138 10","2.1"},
 {kernel,"ERTS  CXC 138 10","3.0.1"}]

アプリケーションの開始と停止はstartとstopで制御する
application:start(ApplicationName).
application:stop(ApplicationName).

1> application:start(rpn).
{local,rpn_sup} (<0.37.0>) starting...
ok
2> rpn_server:cal_rpn("2 3 4 5 6 sum").
20
3> application:stop(rpn).
ok
4>
=INFO REPORT==== 30-Dec-2014::11:20:14 ===
    application: rpn
    exited: stopped
    type: temporary

4> rpn_server:cal_rpn("2 3 4 5 6 sum").
** exception exit: {noproc,
                       {gen_server,call,
                           [rpn_server,{cal_rpn,"2 3 4 5 6 sum"}]}}
     in function  gen_server:call/2 (gen_server.erl, line 182)

string:to_lower(String) -> Result

2> string:to_lower("STRING").
"string"
3> string:to_lower("STRIこんにちは").
[115,116,114,105,12371,12435,12395,12385,12399]

lists:zip(List1, List2) -> List3
"Zips" two lists of equal length into one list of two-tuples
返すリストの中の要素はtupleであることを注意

2> lists:zip([1,2,3], [4,5,6]).
[{1,4},{2,5},{3,6}]
3> lists:zip([1,2,3], [4,5,6,7]).
** exception error: no function clause matching lists:zip([],[7]) (lists.erl, line 385)
     in function  lists:zip/2 (lists.erl, line 385)
     in call from lists:zip/2 (lists.erl, line 385)


mnesia:read({Tab, Key}) -> transaction abort | RecordList
Invokes mnesia:read(Tab, Key, read).
主キーがKeyに一致するレコードを返す。ets:lookup/2と同様にリストを返す。
set のテーブルのように主キーに一致する結果が絶対に1つしかないようなテーブル
でもリストを返します。 レコードが見つからない場合は、空のリストが返されます。


行を削除するには表のオブジェクトID(OID)が必要になる.OIDはテーブル名と主キーの値で構成される.

delete({Tab, Key}) -> transaction abort | ok

Invokes mnesia:delete(Tab, Key, write)

remove_shop_item(Item) ->
    Oid = {shop, Item},
    F = fun() ->
        mnesia:delete(Oid)
        end,
    mnesia:transaction(F).

データベースのデータの追加

add_shop_item(Name, Quantity, Cost) ->
    Row = #shop{item=Name, quantity=Quantity, cost=Cost},
    F = fun() ->
        mnesia:write(Row)
    end,
    mnesia:transaction(F).

実行

1> test_mnesia:do_this_once().
stopped

=INFO REPORT==== 25-Dec-2014::23:25:19 ===
    application: mnesia
    exited: stopped
    type: temporary
2>
2> test_mnesia:start().
ok
3> test_mnesia:reset_tables().
{atomic,ok}
4> test_mnesia:demo(select_shop).
[{shop,potato,2456,1.2},
 {shop,apple,20,2.3},
 {shop,orange,100,3.8},
 {shop,pear,200,3.6},
 {shop,banana,420,4.5}]
5> test_mnesia:add_shop_item(orange, 236, 2.8).
{atomic,ok}
6> test_mnesia:demo(select_shop).
[{shop,potato,2456,1.2},
 {shop,apple,20,2.3},
 {shop,orange,236,2.8},
 {shop,pear,200,3.6},
 {shop,banana,420,4.5}]

qlc:q()で問い合わせるときに簡単のjoinの例をしたの図で示している

5.png


改めて用意されているテーブルのデータをmnesiaに書き込みたいときに、下のやり方で

 start() ->
     mnesia:start(),
     mnesia:wait_for_tables([shop,cost], 20000).

 example_tables() ->
     [%% The shop table
      {shop, apple,   20,   2.3},
      {shop, orange,  100,  3.8},
      {shop, pear,    200,  3.6},
      {shop, banana,  420,  4.5},
      {shop, potato,  2456, 1.2},
      %% The cost table
      {cost, apple,   1.5},
      {cost, orange,  2.4},
      {cost, pear,    2.2},
      {cost, banana,  1.5},
      {cost, potato,  0.6}
     ].

 reset_tables() ->
     mnesia:clear_table(shop),
     mnesia:clear_table(cost),
     F = fun() ->
         foreach(fun mnesia:write/1, example_tables())
     end,
     mnesia:transaction(F).

実行すると

1> test_mnesia:start().
ok
2> test_mnesia:reset_tables().
{atomic, ok}

mnesia:transaction(Fun) -> {aborted, Reason} |{atomic, Value}. This function executes one transaction with the functional object Fun as the single parameter.


mnesiaを使う前に一回やっておくことはあって、
スキーマを作ってからmnesiaをスタートさせる
そして、テーブルを作って、mnesiaをストップ

4.png


mnesia:is_transaction() -> boolean

When this function is executed inside a transaction context it returns true, otherwise false.

traverse_table_and_show(Table_name)->
    Iterator =  fun(Rec,_)->
                    io:format("~p~n",[Rec]),
                    []
                end,
    case mnesia:is_transaction() of
        true -> mnesia:foldl(Iterator,[],Table_name);
        false -> 
            Exec = fun({Fun,Tab}) -> mnesia:foldl(Fun, [],Tab) end,
            mnesia:activity(transaction,Exec,[{Iterator,Table_name}],mnesia_frag)
    end.

mnesia:foldl(Function, Acc, Table) -> NewAcc | transaction abort
Iterates over the table Table and calls Function(Record, NewAcc) for each Record in the table. The term returned from Function will be used as the second argument in the next call to the Function.

foldl returns the same term as the last call to Function returned.


ファイルを作成してから,書き込む

7> {ok, S} = file:open("/Users/wzj/testfile", [write]).
{ok,<0.40.0>}
8> io:format(S, "~s~n", ["Hello world from wang"]).
ok
9> io:format(S, "~s~n", ["sorry for the delay"]).
ok
10> file:close(S).
ok

mnesia:write(Record) -> transaction abort | ok

write/1はmnesia:write(Tab, Record, write)関数を呼び出している

Screen Shot 2014-12-22 at 1.12.09 PM.png

clear_table(Tab) -> {aborted, R} | {atomic, ok}
clear_tableはテーブルのすべてのエントリを削除する


qlcはMnesiaデータベースのデータをアクセスするために使うモジュールの一つである.

qlc:q([X || X <- mnesia:table(shop) ])

上のコードはshopというMnesiaデータベースから取って来たXを要素とするリスト,Xの値はErlangのshopレコードになる


mnesiaのqlc:q()関数を呼び出すには下のヘッダーファイルをインクルードする必要がある

-include_lib("stdlib/include/qlc.hrl").

A common mistake is to have a unique gen_server to handle queries from many processes. This generally becomes the biggest bottleneck you'll want to fix. You should try to avoid relying on a single process, using a pool if you can.


Defining a Schema
The configuration of a Mnesia system is described in the schema. The schema is a special table which contains information such as the table names and each table's storage type, (i.e. whether a table should be stored in RAM, on disc or possibly on both, as well as its location).

it is possible to move a table and simultaneously perform write operations to the same table. This feature is essential for applications that require continuous service.


stringモジュールのstr関数
str(String, SubString) -> Index
SubStringがStringの中に現れる最初のIndexを返す
Indexが1から始まる。存在しない場合は0を返す

1> string:str(" Hello Hello World World ", "Hello World").
8
2> string:str(" Hello Hello World World ", "not exist").
0

ets:new(Name, Options) -> tid() | atom()
Optionsの中にアクセス権限をコントロールするpublicオプションがあって
すべてのプロセスがこのテーブルに対して,readとwriteが可能

Screen Shot 2014-12-21 at 12.46.24 PM.png


record_info(fields, Record) -> [Field]
test.erlを作成して,record_infoの使い方をテストする

-module(test).
-record(paint, {index, artist, title}).

実行する

$ erlc test.erl
test.erl:2: Warning: record paint is unused
$ erl
1> rr(test).
[paint]
2> record_info(fields, paint).
[index,artist,title]
3> record_info(size, paint).
4

create_table(Name, TabDef) -> {atomic, ok} | {aborted, Reason}
mnesiaモジュールのcreate_table関数が成功すると{atomic, ok}が戻り値として,返される
二個目の引数TabDefは{Item, Value}で構成されているリスト.

Screen Shot 2014-12-21 at 11.47.56 AM.png

{disc_copies, Nodelist}, where Nodelist is a list of the nodes where this table is supposed to have disc copies. If a table replica is of type disc_copies, all write operations on this particular replica of the table are written to disc as well as to the RAM copy of the table.


process_flag(Flag :: trap_exit, Boolean) -> OldBoolean
When trap_exit is set to true, exit signals arriving to a process are converted to {'EXIT', From, Reason} messages, which can be received as ordinary messages.


ets:info(Tab) -> InfoList | undefined
テーブルが定義されていないときにundefinedが返す

56> ets:new(ingredients, [set, named_table]).
ingredients
57> ets:info(ingredients).
[{compressed,false},
 {memory,305},
 {owner,<0.93.0>},
 {heir,none},
 {name,ingredients},
 {size,0},
 {node,nonode@nohost},
 {named_table,true},
 {type,set},
 {keypos,1},
 {protection,protected}]
58> ets:info(nonexist).
undefined

io:get_line(IoDevice, Prompt) -> Data | server_no_data()

53> {ok, IoDevice} = file:open("event.erl", [read]).
{ok,<0.96.0>}
54> io:get_line(IoDevice, "").
"-module(event).\n"
55> io:get_line(IoDevice, "").
"-compile(export_all).\n"

uniform/0関数は0.0~1.0範囲内の少数を返す

26> random:uniform().
0.989293905914232

uniform(N) -> integer() >= 1
1より大きい整数を渡すと1~4範囲内の整数を返す

32> random:uniform(4).
1
33> random:uniform(4).
4

file:open(File, Modes) -> {ok, IoDevice} | {error, Reason}
file:open/2関数は成功するときに{ok, IoDevice}を返します。失敗するときに {error, Reason}を返します。例

file:open(Fname, [read, raw, binary])

file:read(IoDevice, Number) -> {ok, Data} | eof | {error, Reason}
file:read/3関数の戻り値は三つのパターンがあります。{ok, Data}、 eof と {error, Reason}です。例

file:read(Fd, 1024)

listsモジュールのflatmap/2の動きは下のようになる

flatmap(Fun, List1) ->
    append(map(Fun, List1)).

4> lists:flatmap(fun(X) -> [X, X] end, [1,a, "abc"]).
[1,1,a,a,"abc","abc"]

stringモジュールのto_float関数で文字列をfloatに変更するときに、失敗すると
{error, Reason}が返される
この関数の形としては

to_float(String) -> {Float, Rest} | {error, Reason}

13> {Float, Rest} = string:to_float("1.12e2X").
{112.0,"X"}
14> f().
16> {Float, Rest} = string:to_float("a+b").
{error,no_float}

最後のXが変換できないので、Restとして保存される


stringモジュールのtokens/2関数
tokens(String, SeparatorList) -> Tokens

Stringに対して、SeparatorListに含まれている文字で区切られるリストを返す

4> string:tokens("abc defxxghix jkl", "x ").
["abc","def","ghi","jkl"]
5> string:tokens("10 4 3 + 2 * -", " ").
["10","4","3","+","2","*","-"]

gen_server:handle_call(Request, From, State)関数はgen_server:call/2,3のリクエストに対して,処理を行う関数.
Request = term()
From = {pid(), Tag}
戻り値として,
{reply,Reply,NewState} | {reply,Reply,NewState,Timeout}などが返される.
下は例

Screen Shot 2014-12-20 at 1.54.45 PM.png


gen_server:start_link/3,4が呼ばれると,init(Args)関数が実行される.initの戻り値として,{ok, State}, {ok, State, TimeOut}あるいは{ok, State, hibernate}が返される


join(StringList, Separator) -> String
Returns a string with the elements of StringList separated by the string in Separator.

5> string:join(["This","is","a","string","list"], ", ").
"This, is, a, string, list"

ローカルnodeの中に存在しているプロセスのリストを取得して、一個一個のプロセスに対して、情報を取得する

3> erlang:processes().
[<0.0.0>,<0.3.0>,<0.6.0>,<0.7.0>,<0.9.0>,<0.10.0>,<0.11.0>,
 <0.12.0>,f<0.13.0>,<0.14.0>,<0.15.0>,<0.16.0>,<0.18.0>,
 <0.19.0>,<0.20.0>,<0.21.0>,<0.22.0>,<0.23.0>,<0.24.0>,
 <0.25.0>,<0.26.0>,<0.27.0>,<0.28.0>,<0.29.0>,<0.33.0>]
4> erlang:process_info(pid(0,33,0)).
[{current_function,{erl_eval,do_apply,6}},
 {initial_call,{erlang,apply,2}},
 {status,running},
 {message_queue_len,0},
 {messages,[]},
 {links,[<0.27.0>]},
 {dictionary,[]},
 {trap_exit,false},
 {error_handler,error_handler},
 {priority,normal},
 {group_leader,<0.26.0>},
 {total_heap_size,3196},
 {heap_size,1598},
 {stack_size,24},
 {reductions,49451},
 {garbage_collection,[{min_bin_vheap_size,46422},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,30}]},
 {suspending,[]}]
5>

リストの中にユニークの要素をソートする

2> lists:usort([2,1,3,4,2,3,8,9,[a,c,q,m,x],a,v,c]).
[1,2,3,4,8,9,a,c,v,[a,c,q,m,x]]

Concatenates the text representation of the elements of Things. The elements of Things can be atoms, integers, floats or strings.
concat(Things) -> string()

1> lists:concat([doc, '/', file, '.', 3]).
"doc/file.3"

ファイルパスを組み立てる

29> filename:join(["/usr", "local", "bin"]).
"/usr/local/bin"

ネットワークインターフェースを取得する

19> inet:getifaddrs().
{ok,[{"lo",
      [{flags,[up,loopback,running]},
       {hwaddr,[0,0,0,0,0,0]},
       {addr,{127,0,0,1}},
       {netmask,{255,0,0,0}},
       {addr,{0,0,0,0,0,0,0,1}},
       {netmask,{65535,65535,65535,65535,65535,65535,65535,
                 65535}}]},
     {"eth0",
      [{flags,[up,broadcast,running,multicast]},
       {hwaddr,[10,150,197,9,125,48]},
       {addr,{172,31,21,248}},
       {netmask,{255,255,240,0}},
       {broadaddr,{172,31,31,255}},
       {addr,{65152,0,0,0,2198,50687,65033,32048}},
       {netmask,{65535,65535,65535,65535,0,0,0,0}}]}]}

'=:=' と '=='の区別

16> 1 =:= 1.0.
false
17> 1 == 1.0.
true
18> [65] =:= "A".
true

folds関数
foldl(Fun, Acc0, List) -> Acc1

2> lists:foldl(fun(X, Sum) -> X+Sum end, 3, [2,4,6,8]).
23

後ろのリスト一個一個のの要素に対して、関数を適応して行く
2番目のパラメータは3という初期のアキュミュレーター指定している


priv_dir(Name)はlib_dir(Name, priv)と一緒でライブラリNameのprivディレクトリを返す

11> code:lib_dir(mnesia, priv).
"/usr/local/lib/erlang/lib/mnesia-4.12.1/priv"
12> code:priv_dir(mnesia).
"/usr/local/lib/erlang/lib/mnesia-4.12.1/priv"
13> code:priv_dir(eunit).
"/usr/local/lib/erlang/lib/eunit-2.2.7/priv"
14> code:priv_dir(kernel).
"/usr/local/lib/erlang/lib/kernel-3.0.1/priv"

tupleのサイズはtuple_size/1で取得する
element/2でtupleのn個目の要素を取得する。

3> Tuple1 = {number, 42}.
{number,42}
4> tuple_size(Tuple1).
2
5> element(1, Tuple1).
number
6> element(2, Tuple1).
42
7> setelement(2, Tuple1, 43).
{number,43}
8> Tuple1.
{number,42}
9> Tuple2 = setelement(2, Tuple1, 43).
{number,43}
10> Tuple2.
{number,43}

K1の一個一個のtupleに対して、
keysearch()の場合は2個目の要素はk2とマッチングしていれば返す。

12> K1 = [{a, k1, a}, {b, k2, b}, {c, k3, c}, {e, k5, e}].
[{a,k1,a},{b,k2,b},{c,k3,c},{e,k5,e}]
13> lists:keysearch(k2, 2, K1).
{value,{b,k2,b}}
15> lists:keydelete(k3, 2, K1).
[{a,k1,a},{b,k2,b},{e,k5,e}]
16> lists:keyreplace(k1, 2, K1, {new, tuple}).
[{new,tuple},{b,k2,b},{c,k3,c},{e,k5,e}]

listsモジュールのsplit/2関数split(N, List1) -> {List2, List3}
List1の前N個と残りの要素、この二つのリストをtupleとして、返す

1> L = ["This","is", "a", "list"].
["This","is","a","list"]
2> lists:split(3, L).
{["This","is","a"],["list"]}

function_exported/3関数の意味はModuleはロードされて、そして、エクスポート(パラメータ数Arity)されている関数Fucntionがあれば、trueを返して、それ以外はfalseを返す

    erlang:function_exported(Module, Function, Arity) -> bool()

timerモジュールのsend_interval/3関数

    send_interval(Time, Pid, Message) -> {ok, TRef} | {error, Reason}

Time時間過ぎると

    Pid ! Message

を定期的に実行する。send_interval/2の場合はsend_interval(Time, self(), Message).と一緒である


一週間の間の曜日を調べるにはcalendarモジュールのday_of_the_week()関数を使う

1> calendar:day_of_the_week({2014,12,17}).
3

ETSテーブルはtupleを保存する。テーブルをスタートさせるためにets:new/2を使う
オプションの中にsetが使われているので、keyは重複しないテーブルを使う
tupleの一部だけを調べるときにlookup_element()関数を使う
下の例だとorangeはkeyではないのでクラッシュする

1> ets:new(ingredients, [set, named_table]).
6> ets:insert(ingredients, {orange, good, nice, delicious}).
7> ets:lookup_element(ingredients, orange, 2).
good
8> ets:lookup_element(ingredients, orange, 3).
nice
9> ets:lookup_element(ingredients, orange, 4).
12> ets:lookup_element(ingredients, orange, 1).
** exception error: bad argument
     in function  ets:lookup_element/3
        called as ets:lookup_element(ingredients,good,1)


orddict:new()は新しいKey-Valueペアの辞書を作る
orddictの作られている辞書はソートされている。
dictと同じインターフェースを提供している

store(Key, Value, Orddict1) -> Orddict2
find(Key, Orddict) -> {ok, Value} | error
fetch(Key, Orddict) -> Value
erase(Key, Orddict1) -> Orddict2
map(Fun, Orddict1) -> Orddict2

fetchの場合は

returns the value associated with Key in the dictionary Orddict. fetch assumes that the Key is present in the dictionary and an exception is generated if Key is not in the dictionary.

findの場合

This function searches for a key in a dictionary. Returns {ok, Value} where Value is the value associated with Key, or error if the key is not present in the dictionary.


日付不法であるかをチェックするためにcalendarモジュールのvalid_date()関数を使用する

valid_date(Date) -> boolean()
Date = date()

valid_date(Year, Month, Day) -> boolean()
Year = Month = Day = integer()

11> calendar:valid_date(2014,2,28).
true
12> calendar:valid_date({2014,2,28}).
true
13> calendar:valid_date(2014,2,29).
false
14> calendar:valid_date({2014,2,29}).
false


clash関数を使って、同じ名前のモジュールが衝突しているかをチェックする

1> code:clash().
** Found 0 name clashes in code paths
ok

code:lib_dirを使ってライブラリのパスを探す

1> code:lib_dir(mnesia).
"/usr/local/lib/erlang/lib/mnesia-4.12.1"
2> code:lib_dir(eunit).
"/usr/local/lib/erlang/lib/eunit-2.2.7"
3> code:lib_dir(kernel).
"/usr/local/lib/erlang/lib/kernel-3.0.1"
4>

-include_lib()を使うときにライブラリのバージョンを指定しなくてもよい

-include_lib("kernel/include/file.hrl").
-include_lib("eunit/include/eunit.hrl").

Erlangのバージョンを取得する方法

5> erlang:system_info(otp_release).
"17"

バイナリデータを連結する方法

1> B1 = <<1,2>>.
<<1,2>>
2> B2 = <<3,4>>.
<<3,4>>
3> B3 = <<B1/binary, B2/binary>>.
<<1,2,3,4>>

Erlangにreturn文がない理由

 Erlang has no statements, it only has expressions. All expressions
 return a value. So there is no need for a "return" instruction, the last
 expression executed gives the return value of the function.


文字列はダブルクオーテーションで囲まれて、Erlangのデータタイプではない, "hello"はただのリストである、[$h,$e,$l,$l,$o]、つまり[104,101,108,108,111].

> integer_to_list(123).  
"123"
> is_list(integer_to_list(323)).
true


Erlangシェルの中にcdコマンドを使って、移動する. pwd()は現在の場所を調べる

2> cd("/etc").
/etc
ok
3> pwd().
/etc
ok

Calling demonitor(MonitorRef, [flush]) is equivalent to the following, but more efficient:

demonitor(MonitorRef),
    receive
        {_, MonitorRef, _, _, _} ->
            true
    after 0 ->
            true
    end

This function returns the local time reported by the underlying operating system.
local_time() のリファレンスは

local_time()-> datetime()
datetime()データタイプはしたのように
datetime() = {date(), time()}
date() = {year(), month(), day()}
time() = {hour(), minute(), second()}
1> calendar:local_time().
{{2014,12,16},{11,22,27}}

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?