web-dev-qa-db-ja.com

ElixirまたはErlangでコンパイルされたビームファイルを実行するにはどうすればよいですか?

Erlang/OTPとElixirをインストールし、次のコマンドを使用してHelloWorldプログラムをBEAMにコンパイルしました。

elixirc test.ex

Elixir.Hello.beamという名前のファイルが作成されました

このファイルを実行するにはどうすればよいですか?

25
Samuel Lampa

短い答え:ソースファイルの内容も知らなければ、確実に知る方法はありません:)

Elixirコードを実行するにはいくつかの方法があります。この回答は、Elixirで使用できるさまざまなワークフローの概要です。

始めたばかりで試してみたい場合は、iexを起動して式を1つずつ評価するのがよいでしょう。

iex(5)> Enum.reverse [1,2,3,4]
[4, 3, 2, 1]

iexでElixirモジュールと関数のヘルプを利用することもできます。ほとんどの関数のドキュメントに例があります。

iex(6)> h Enum.reverse

                        def reverse(collection)

Reverses the collection.
[...]

いくつかのコードをファイルに入れて後で再利用する場合、推奨される(そして事実上の標準)方法は、ミックスプロジェクトを作成し、そこにモジュールを追加することです。しかし、おそらく、コードのコンパイル、アプリケーションの起動などの一般的なタスクを実行するためにミックスに依存する前に、内部で何が行われているのかを知りたいと思うでしょう。それについて説明させてください。

いくつかの式をファイルに入れて実行する最も簡単な方法は、elixirコマンドを使用することです。

x = :math.sqrt(1234)
IO.puts "Your square root is #{x}"

上記のコードのフラグメントをsimple.exsという名前のファイルに入れ、elixir simple.exsで実行します。 .exs拡張子は、ファイルが評価されることを意図していることを示す規則にすぎません(これが私たちが行ったことです)。

これは、プロジェクトの構築を開始するポイントまで機能します。次に、コードをモジュールに編成する必要があります。各モジュールは関数のコレクションです。これは最小のコンパイル単位でもあります。各モジュールは.beamファイルにコンパイルされます。通常、ソースファイルごとに1つのモジュールがありますが、複数定義することもできます。単一のソースファイル内のモジュールの数に関係なく、各モジュールはコンパイル時に独自の.beamファイルになります。

defmodule M do
  def hi(name) do
    IO.puts "Hello, #{name}"
  end
end

単一の機能を持つモジュールを定義しました。 mymod.exという名前のファイルに保存します。複数の方法で使用できます。

  • iexを起動し、生成されたシェルセッションでコードを評価します。

    $ iex mymod.ex
    
    iex> M.hi "Alex"
    Hello, Alex
    :ok
    
  • 他のコードを実行する前に評価してください。たとえば、コマンドラインで単一の式を評価するには、elixir -e <expr>を使用します。その前に1つ以上のファイルを「要求」することができます(基本的に、評価およびロード)。

    $ elixir -r mymod.ex -e 'M.hi "Alex"'
    Hello, Alex
    
  • それをコンパイルし、VMのコード読み込み機能を見つけましょう

    $ elixirc mymod.ex
    $ iex
    iex> M.hi "Alex"
    Hello, Alex
    :ok
    

最後の例では、現在のディレクトリにElixir.M.beamという名前のファイルを生成するモジュールをコンパイルしました。その後、同じディレクトリでiexを実行すると、モジュールが最初に呼び出されたときにモジュールがロードされます。 elixir -e 'M.hi "..."'など、他の方法でコードを評価することもできます。 .beamファイルがコードローダーによって見つかる限り、モジュールが読み込まれ、その中の適切な関数が実行されます。


ただし、これはすべて、いくつかのコード例を試してみることに関するものでした。 Elixirでプロジェクトをビルドする準備ができたら、mixを使用する必要があります。 mixを使用したワークフローは、次のようになります。

$ mix new myproj
* creating README.md
* creating .gitignore
* creating mix.exs
[...]

$ cd myproj

# 'mix new' has generated a dummy test for you
# see test/myproj_test.exs
$ mix test

lib/ディレクトリに新しいモジュールを追加します。すべてのモジュール名の前にプロジェクト名を付けるのが通例です。したがって、上記で定義したMモジュールを取得してファイルlib/m.exに入れると、次のようになります。

 defmodule Myproj.M do
   def hi(name) do
     IO.puts "Hello, #{name}"
   end
 end

これで、Mixプロジェクトがロードされたシェルを開始できます。

 $ iex -S mix

上記を実行すると、すべてのソースファイルがコンパイルされ、_buildディレクトリに配置されます。 Mixは、コードローダーがそのディレクトリ内の.beamファイルを見つけられるように、コードパスも設定します。

ミックスプロジェクトのコンテキストで式を評価すると、次のようになります。

$ mix run -e 'Myproj.M.hi "..."'

この場合も、何もコンパイルする必要はありません。ほとんどのミックスタスクは変更されたファイルを再コンパイルするため、定義したモジュールは、それらから関数を呼び出すときに使用可能であると安全に想定できます。

mix helpを実行して使用可能なすべてのタスクを表示し、mix help <task>を実行して特定のタスクの詳細な説明を取得します。

39
Alexei Sholik

具体的に質問に対処するには:

$ elixirc test.ex

ファイルがHelloモジュールを定義している場合、Elixir.Hello.beamという名前のファイルが生成されます。

このファイルを含むディレクトリからelixirまたはiexを実行すると、モジュールが使用可能になります。そう:

$ elixir -e Hello.some_function

または

$ iex

iex(1)> Hello.some_function
12
Henrik N

次のようなElixirプログラムを作成するとします。

_defmodule PascalTriangle do
  defp next_row(m), do: for(x <- (-1..Map.size(m)-1), do: { (x+1), Map.get(m, x, 0) + Map.get(m, x+1, 0) } ) |> Map.new
  def draw(1), do: (IO.puts(1); %{ 0 => 1})
  def draw(n) do
    (new_map = draw(n - 1) |> next_row ) |> Map.values |> Enum.join(" ") |> IO.puts
    new_map
  end
end
_

モジュールPascalTriangleは次のように使用できます:PascalTriangle.draw(8)

elixircを使用してexファイルをコンパイルすると、Elixir.PascalTriangle.beamというファイルが作成されます。

コマンドラインから、次のようにビームファイルを実行できます:elixir -e "PascalTriangle.draw(8)"

写真のような出力を見ることができます: enter image description here

6