Chcolatey パッケージマネージャでインストール。
cinst erlang -y
プロジェクト管理ツール(ビルドツール、パッケージマネージャも兼ねる)として rebar3 がよく使われているが、別添のようだ(上記と同じ方法でインストールしておくといい)。(R)
Elixir については(やはり同様に)
cinst elixir -y
開発元から直接ダウンロードする。
ここから辿り(Erlang)、 自分のマシンに応じたファイル(Windows 32bit または 64bit)を見つけること。
REPL上で式を対話的に評価させる
Erlangの場合:
erl
Elixir なら、
iex
Elixir用のGUI版REPLは werl内で使える。以下のように起動する。
iex --werl
REPL上で関数定義はできないので、ファイルに、以下のように定義しておいて (ファイル名を test.erl とすると)、
-module(test).
-export([sum/2]).
sum(A,B)->A+B.
REPL内で
c(test). %% これでコンパイル(したものを読み込み)しておいて
test:sum(1,2). %% モジュール名:関数名 で実行する
使うことができる。
または、erlコマンドの引数にソースファイル名を与えると、
erl test.erl
そのファイルを読み込んだ上で、REPLに入る。
なお、(こういったコマンドからのファイル参照の際には常に必要な配慮だが) ファイルが置いてある(保存された)フォルダ(場所)を確認し、その場所から コマンドプロンプトを起動するか、
その場所にCDコマンドで移動してからREPLを起動するか、 REPLの中で(同様のコマンドで)移動してから c(test)
などの呼出でファイルを参照すること。
またはファイル名ではなくパス名で参照してもいい(詳しい解説は笑楽する)。
ファイル(に作成したソースファイル)を、REPLを使わず実行するためには、
コンパイルしてから実行する。コンパイルするコマンドは、erlc (Javaに対する javacコマンド等と同様の命名)。
erlc test.erl
erl -noshell -s test hello -s init stop
のように呼び出す。なおこの呼出しは、モジュール名(およびファイル名;Erlangでは ファイル名とモジュール名が一致していることが必要)がtestで、
-module(test).
-export([hello/0]).
hello()->io:format("hello~n").
のように、引数0の関数 hello を定義(およびexport)しているという前提。
-noshell オプションが、REPLモードに入らないという指示。
REPLで対話的に入力する代わりに、-s オプションに、実行すべき動作を、 「モジュール名 関数名」を並べて指定する。
コンパイルを行うと、ソースと同名で拡張子が .beam であるファイル(バイトコード仮想機械の実行形式)が生成される。
Erlangのプログラムは、自動的には停止しないので、hello関数を実行したあと、 プログラムが停止するように、もう1つ -s オプションをつけて、 init モジュールの stop 関数を呼び出すよう指示しておく。
或いはその代わりに、上記ソースコードで hello 関数定義に追加して、
% 変更箇所のみ示す。改行やインデントは、してもしなくてもいい。
hello()->
io:format("hello~n"),
init:stop().
のようにソースコード内で明示的に init:stop() を呼ばせてもいい。
なお、一般には(他の言語でもよく見かけるように)関数名として main/0 (または main/1)を export することが多い(先に示したコードの 関数名 hello を main に置き換えた形)。
プログラム起動時に引数(コマンドラインパラメータ)を渡したいことがある。 このときは、関数 main/1(引数を1つとる関数) を用意してexport するといい。
-module(test).
-export([main/1]).
main(Args)-> % コマンドラインパラメータが文字列のリストとしてArgsに渡される
io:format("hello ~p ~n",Args). % ~pの場所にArgsがリストとして表示される
init:stop().
こんな感じのプログラムになる。呼出は(コンパイル方法は省略する)、
erl -noshell -s test hello a b c -s init stop
%=> hello [a,b,c] のように表示される
main/1 を呼び出すソースファイルは、.beam ファイルの生成をスキップして実行することもできる(この呼び方が一番手軽だろう)。
escript test.erl a b c % 引数を渡さない呼び方をしても構わない
他に、オンラインで実行できるサイトもいくつか提供されている (など)が、ここでは詳細は省略する。
REPL (EShell あるいは Erlang Shell と呼ばれる)について、公式にはドキュメントに書かれているが、日本語のガイドとしては、たとえばここを参照。
Erlang では変数は再代入はできない(正確には「代入」ではなく「束縛」と呼び、一度束縛された値は変更できないルール)。 そのため、REPLで不便を感じることが多いので、 以下のEshellコマンドは知っておこう。
b(). % 束縛状態の表示
f(). % 束縛された全変数を開放
f(V). % 指定された変数(ここでは V)を開放
q(). % シェルの終了
## このソースのファイル名は何でもいい
defmodule A do
def greet1 (), do: IO.puts "hello"
end
defmodule B do
def greet2 (name) do
say(name)
end
defp say(name), do: :io.format("hello ~s~n",name)
end
上記ソースをファイル、例えば greet.ex とし、REPL(iex)の中で、
c "greet.ex" # c はコンパイルさせるコマンド(関数)
A.greet1 # 定義した関数を呼び出す
B.greet2 "john" # こちらは引数付きで呼ぶ
このようにコンパイルしてから関数を(モジュール名.関数 として)呼び出す ことができる。
iex コマンドの引数として(下のように)ソースファイルを指定すると、 そのソースを読み込んだ上で REPLの対話モードに入るので、 REPLから 上と同様に関数を呼び出す。
iex greet.ex
ファイルの拡張子を(.exではなく).exs とし、
上記の .exファイルにあるような モジュール(と関数)の定義の後ろに、 A.greet1
等の呼出も含めてソースファイルに書き込んでおき、
elixir greet.exs
のように呼び出す。
役に立つサイトをいくつかあげておく。
REPLの終了
q().
%% あるいは
init.stop(). % でも終了する(プログラムを終了させる一般的な方法)
それ以外の方法もこの記事に紹介されている。
REPLの基本的な使い方(R)
式を入力すると値を表示する (というのが言語を問わずREPLの基本動作)。
式を入力したら、式の終わりを示す記号 .
(ピリオド)を入れて Enter。
REPL独自のいくつかの機能も、関数の形で提供されていて、式の入力と同様の作法で扱う。
カレントディレクトリの取得、移動も可能
file:get_cwd().
file:set_cwd("subdir").
:init.stop
または :init.stop()
になる。h
とだけ叩くと、ヘルプメッセージが表示される(IExヘルパーと呼ばれている)。.
(ピリオド)は不要。原則として一行で式が完結すると見なされるので Enter を押すと応答が返ってくる(入力した式が「評価」される)。
" "
、' '
、( )
、{ }
、do ~ end などの 囲み記号が完結していない状態では、Enterを押しても評価は開始されず、 継続行の入力が求められる。 囲み記号が完結した状態でEnterをして初めて式の評価が始まる (これがRubyやElixirやJavaScriptで複数行に渡る式を書く時の文法)。#iex:break
と入力する(ブレークトリガー)と、 これまでに入力中の式はキャンセルされ、 式をあらためて最初から入力できる (iexで打ち間違えた行の中断方法と終了方法(Qiitaの記事)などを参照)。h
も含めて、REPLに内蔵される機能も関数の形で提供されており、 (Rubyと同様に)引数(があれば)を括弧で囲んでも囲まなくてもいい。 また、空の括弧は省略してもいい(つまり h
でもh()
でもOK).
(ピリオド)で終わる。
.
が現れるまでは文や式が継続する。,
(カンマ)区切りで複数の式を並べることもできる。 最後の(カンマ以降の)式の値がその式全体の値となる。;
(セミコロン)は、文が複数の節から成る時に、節の区切りとして使われる。,
は意味的には AND(順々に)、;
は、OR(マッチしたいずれかの節が選ばれる) だと理解すると分りやすい。%
から行末まではコメントとして読み飛ばされる。
%%
が好んで使われることが多いようだ。=
で、代入に似た操作が行える。 ただし、再代入はできない(代入と呼ばず、「束縛」と呼ばれる所以)。例(REPL(erlコマンドの中)で入力して確認してみて下さい。):
abc. % アトム
"abc". % 文字列
’abc'. % これもアトム
1,2,3. % 値 3 を返す
A=1. % 変数に束縛(代入に近い概念だが再代入できない)
A. % 変数に束縛された値が返される
A=2. % 再代入を試みる
式(文)は行末で完結する(のが原則)。
コメント記号は(Rubyと同じく)#
。単行のみ。
変数名、関数名などは(Erlangとは逆に)小文字から始まる。
:
をつけたもの (これもRubyと同様)。関数定義(長い形式)はキーワード(事前定義されたキーワード)def から始まり、 以下のような文法で書く。
def | defp 関数名 [ (引数リスト) ] do 式 ... end
これも Rubyに似てているが、do が入る点だけ違う(次の defmodule も同様)。
関数定義は、defmodule モジュール名 do ~ end によるモジュール宣言の 中に書かれる必要がある。
関数定義のうち短いものは
def | defp 関数名 [ (引数リスト) ] , do: ...
という形式で(1行で完結する必要がある)書くこともできる。
,
カンマが入るdef で定義された関数は、エクスポートされたものとして、モジュール外から (REPLからの呼出も含めて)参照できるもの。一方、defp で定義されたもの は、外部からの参照・使用は不可(モジュールにプライベートな関数、と呼ぶ)。