牌語備忘録 -pygo

あくまでもメモです。なるべくオフィシャルの情報を参照してください。

牌語備忘録 -pygo

すごE本を読んでみたメモ -- 第2章

書籍『すごいErlangゆかいに学ぼう!/Learn You Some Erlang for great good! 』まとめ

第2章 モジュール

2.1 モジュールとは

  • モジュールは 1 つの名前で 1 つのファイルにまとめられた関数群

  • モジュール内に定義された他のすべての関数は、呼び出す形

    • 〔モジュール名〕:〔関数名〕(〔引数〕)
1> erlang:element(2, {a,b,c}).
b
2> element(2, {a,b,c}).
b
3> lists:seq(1,4).
[1,2,3,4]
4> seq(1,4).
** exception error: undefined shell command seq/2

2.2 モジュールを作る

  • モジュールで宣言できる2つ
    • 関数
    • 属性

属性は、モジュール名や外部に公 開する関数、コードの作者名などといった、モジュール自身の メタデータです。

  • すべてのモジュール属性は「-〔属性名〕(〔値〕).」

module 属性で定義したモジュール名とファイル名は一致しなければいけないこ とに注意してください。

  • -export([〔関数1〕/〔アリティ〕,〔関数2〕/〔アリティ〕, ..., 〔関数 N〕/〔アリティ〕]).
  • 関数の アリティ というのは引数の数
    • 例:add/2 や add/3 という形式

Erlang コミュニティでの規約では、モジュール全般にかかわるコメント(モジュールの用 途、ライセンスなど)やモジュール内の区切り(public なコード、private なコード、ヘル パー関数など)に関してはパーセント記号 3 つ(%%%)を使うことになっています。パーセ ント記号 2 つ(%%)の場合は、行コメントとして用いて、インデントは周りのインデントに 合わせます。パーセント記号 1 つ(%)は行末コメントに用いられます。

  • -import(〔モジュール〕, [〔関数1〕/〔アリティ〕,〔関数2〕/〔アリティ〕, ..., 〔関数 N〕/〔アリティ〕]).

useless.erl

-module(useless).
-export([add/2, hello/0, greet_and_add_two/1]).
add(A,B) ->
    A + B.
%% Shows greetings.
%% io:format/1 is the standard function used to output text.
hello() ->
    io:format("Hello, world!~n").
greet_and_add_two(X) ->
    hello(),
add(X,2).

2.3 コードをコンパイルする

  • コマンドライン
    • $ erlc〔フラグ〕file.erl
  • シェル内またはモジュール内
    • compile:file(〔ファイル名〕)
  • シェル
    • c()
  • シェルでディレクトリ移動
1> cd("/path/to/where/you/saved/the-module/").
"Path Name to the directory you are in"
ok
3> useless:add(7,2).
9
4> useless:hello().
Hello, world!
ok
5> useless:greet_and_add_two(-3).
Hello, world!
-1
6> useless:not_a_real_function().
** exception error: undefined function useless:not_a_real_function/0
  • Erlangの関数や式は 常に 何かを返さなければいけない。

コンパイラオプション

よく使うフラグ

  • -debug_info
  • -{outdir,〔ディレクトリ〕}
  • -export_all
  • -{d,〔マクロ〕}、 または -{d,〔マクロ〕,〔値〕}

コンパイル

7> compile:file(useless, [debug_info, export_all]).
{ok,useless}
8> c(useless, [debug_info, export_all]).
{ok,useless}

2.4 マクロを宣言する

  • Erlang のマクロは短い関数と定数の定義に使われる
  • コードが仮想マシン用にコンパイルされる前に置き換えられる
  • マジックバリューを避けるために主に使われる
  • マクロの定義
    • -define(〔MACRO〕, 〔値〕). -?〔MACRO〕 として使える
  • ある数字から別の数字を引く簡単なマクロの例
    • -define(sub(X,Y), X-Y).
  • 事前定義されたマクロの例
    • ?MODULE:現在のモジュール名のアトムに置換される
    • ?FILE:ファイル名の文字列に置換される
    • ?LINE:マクロが置かれた行番号に置換される
  • コード内で特定のマクロが宣言されているかどうかを確認・他のマクロを定義しているかどうか確認できる
    • -ifdef(〔MACRO〕).、-else.、-endif. という属性を使う
-ifdef(DEBUGMODE).
-define(DEBUG(S), io:format("dbg: "++S)).
-else.
-define(DEBUG(S), ok).
-endif.
  • テストマクロが定義されている場合にのみ存在するテストを定義する例
-ifdef(TEST).
my_test_function() ->
    run_some_tests().
-endif.

2.5 モジュールについてもっと詳しく

メタデータ

循環参照