Erlangシェルの起動停止, ロードパスの調整, コンパイルと実行などのメモ。
Win:
DOS> erl
UNIX:
$ erl
1> q().
又は
1> init:stop().
1> help().
結果(Eshell V5.6.3):
** shell internal commands ** b() -- display all variable bindings e(N) -- repeat the expression in query <N> f() -- forget all variable bindings f(X) -- forget the binding of variable X h() -- history history(N) -- set how many previous commands to keep results(N) -- set how many previous command results to keep v(N) -- use the value of query <N> rd(R,D) -- define a record rf() -- remove all record information rf(R) -- remove record information about R rl() -- display all record information rl(R) -- display record information about R rp(Term) -- display Term using the shell's record information rr(File) -- read record information from File (wildcards allowed) rr(F,R) -- read selected record information from file(s) rr(F,R,O) -- read selected record information with options ** commands in module c ** bt(Pid) -- stack backtrace for a process c(File) -- compile and load code in <File> cd(Dir) -- change working directory flush() -- flush any messages sent to the shell help() -- help info i() -- information about the system ni() -- information about the networked system i(X,Y,Z) -- information about pid <X,Y,Z> l(Module) -- load or reload module lc([File]) -- compile a list of Erlang modules ls() -- list files in the current directory ls(Dir) -- list files in directory <Dir> m() -- which modules are loaded m(Mod) -- information about module <Mod> memory() -- memory allocation information memory(T) -- memory allocation information of type <T> nc(File) -- compile and load code in <File> on all nodes nl(Module) -- load module on all nodes pid(X,Y,Z) -- convert X,Y,Z to a Pid pwd() -- print working directory q() -- quit - shorthand for init:stop() regs() -- information about registered processes nregs() -- information about all registered processes xm(M) -- cross reference check a module y(File) -- generate a Yecc parser ** commands in module i (interpreter interface) ** ih() -- print help for the i module true
コード(=モジュール, モジュール名.beam)のロードパスを確認:
1> code:get_path(). [".","c:/PROGRA~1/ERL56~1.3/lib/kernel-2.12.3/ebin", "c:/PROGRA~1/ERL56~1.3/lib/stdlib-1.15.3/ebin", "c:/PROGRA~1/ERL56~1.3/lib/xmerl-1.1.9/ebin", "c:/PROGRA~1/ERL56~1.3/lib/webtool-0.8.3.2/ebin", "c:/PROGRA~1/ERL56~1.3/lib/typer-0.1.3/ebin", [...]|...].
ロードされている全モジュールの一覧を確認:
1> code:all_loaded(). [{io,"c:/PROGRA~1/ERL56~1.3/lib/stdlib-1.15.3/ebin/io.beam"}, ...
ロードパスの先頭に追加:
code:add_patha(Dir) or $ erl -pa Dir1 -pa Dir2 ...
ロードパスの末尾に追加:
code:add_pathz(Dir) or $ erl -pz Dir1 -pz Dir2 ...
Erlang起動時に、以下の優先順位で ".erlang" ファイルが読み込まれErlangコードとして実行される。
もしもホームディレクトリに置いたつもりなのに実行されない場合は、Erlangが認識するホームディレクトリを確認し、そちらに置いてみる。
Erlangが認識するホームディレクトリはinit:get_argument(home)で取得できる。
1> init:get_argument(home). {ok,[["C:\\Documents and Settings\\FengJing"]]}
サンプルで使うプログラム:hello.erl
-module(hello). -export([start/0]). start() -> io:format("Hello, Erlang!~n").
DOS> erl Eshell V5.6.3 (abort with ^G) 1> ls(). ... hello.erl ... ok 2> c(hello). {ok,hello} 3> ls(). ... hello.beam hello.erl ... ok 4> hello:start(). Hello, Erlang! ok
Erlangシェルを起動せず、OSのコマンドプロンプトだけで完結させる。
DOS> erlc hello.erl DOS> erl -noshell -s hello start -s init stop
initモジュールのマニュアル(Kernel Reference Manual, init)を読むと"-run"も使える事が分かる。
DOS> erl -noshell -run hello start -run init stop
解説自体も一緒。ただし"-s"の方にだけ次の一文がある。(erl5.6.3/lib/kernel-2.12.3)
Due to the limited length of atoms, it is recommended that -run be used instead.
内部処理の違いかも知れないが、"-run"の方がオススメらしい。"-s"はapply()を使うようだが、それと関連しているのだろうか。
"-noshell"は、"-pa", "-pz"によるロードパス調整と併せて、シェルスクリプト中で活用できる。
hello.erls:
#!/usr/bin/env escript main(Arg) -> io:format("Argument is ~p~n", [Arg]), lists:map(fun(X) -> io:format("~p~n", [X]) end, init:get_plain_arguments()), io:format("Hello, Erlang!~n").
DOS> escript hello.erls Argument is [] "hello.erls" Hello, Erlang! DOS> escript hello.erls a b c Argument is ["a","b","c"] "hello.erls" "a" "b" "c" Hello, Erlang!
ちなみに、Windowsだからといってシェバン行を省略し、1行目からmain/1を書くと
DOS> escript hello.erls hello.erls:2: syntax error before: ':' escript: There were compilation errors.
と怒られます。1行目はコメント又は空行にしておく必要が有るみたいです。普通にシェバン行にして置いた方が無難でしょう。
ちなみに拡張子の".erls"は適当につけただけです。escript用の拡張子の標準って・・・あるのかな?
escriptの例でコマンドライン引数を受け取ってみたが、実際に何パターンか試してみる。
get_arsg.erl:
-module(get_args). -export([hello/1]). hello(Arg) -> io:format("Argument is ~p~n", [Arg]), lists:map(fun(X) -> io:format("~p~n", [X]) end, init:get_plain_arguments()), io:format("Hello, Erlang!~n").
DOS> erl a b c Eshell V5.6.3 (abort with ^G) 1> get_args:hello(foo). Argument is foo Hello, Erlang! ok
"-run"では引数も追加で指定できるので、次のように関数への引数として、コマンドライン引数を渡す事が出来る。
DOS> erl -noshell -run get_args hello foo -run init stop Argument is ["foo"] Hello, Erlang!
ただしこの場合、init:get_plain_arguments/0 は空っぽとなる。
"--"に続けると、erl自体のオプションとはならず、init:get_plain_arguments/0 で取得できる。
DOS> erl -noshell -run get_args hello foo -run init stop -- a b c d Argument is ["foo"] "a" "b" "c" "d" Hello, Erlang!
このページを書く時に調べた code, init モジュールのドキュメントは次の順序で辿る。
"Basic Applications" -> "kernel" -> "Kernel Reference Manual"
erlコマンドやerlcコマンドのヘルプについては次の順序で辿る。
"Basic Applications" -> "erts" -> "ERTS Reference Manual"
ioやlistsモジュールなど、標準ライブラリのモジュールについては次の順序で辿る。
"Basic Applications" -> "stdlib" -> "STDLIB Reference Manual"