Elixirアプリケーションを実行する方法は?


84

Elixirアプリケーションを実行する正しい方法は何ですか?

私は次の方法で簡単なプロジェクトを作成しています。

mix new app

その後、私はできる:

mix run

これは基本的に私のアプリを一度コンパイルします。だから私が追加すると:

IO.puts "running"

lib/app.ex、私が見る"running"だけで初めて、それぞれの連続は、runいくつかの変更がない限り何もしません。生成されたもので次に何ができapp.appますか?

もちろん、私は私ができることを知っています:

escript: [main_module: App]

mix.exs、提供def main(args):してから:

mix escript.build
./app

でも、私の意見ではちょっと面倒です。

次のようなものもあります:

elixir lib/app.exs

しかし、それはmix.exs明らかにカウントされませんapp。これは、私のの依存関係に必要です。


2
Elixirスクリプト(.exsファイル)を実行したいが、ミックスアプリのコンテキストで実行したい場合は、を実行できますmix run <script>。詳細についてはmix help run、を参照してください。
ミシェルティリー2015年

回答:


106

mix runあなたのアプリを実行します。それはあなたが単に置くときだけということだIO.puts "something"行のみコンパイル時に評価されていることをファイルに、それは実行時に何もしません。アプリの起動時に何かを開始したい場合は、でそれを指定する必要がありますmix.exs

通常、Application開始するトップレベルが必要です。これを実現するには、次のmodオプションを追加しますmix.exs

def application do
  [
    # this is the name of any module implementing the Application behaviour
    mod: {NewMix, []},
    applications: [:logger]
  ]
end

そして、そのモジュールで、アプリケーションの起動時に呼び出されるコールバックを実装する必要があります。

defmodule NewMix do
  use Application

  def start(_type, _args) do
    IO.puts "starting"
    # some more stuff
  end
end

startコールバックは、実際にセットアップあなたのトップレベルのプロセスや監督のツリーのルートべきであるが、この場合、あなたはすでにそれはあなたが使用するたびに呼び出されたことがわかりますmix runエラーが続くものの、。

def start(_type, _args) do
  IO.puts "starting"
  Task.start(fn -> :timer.sleep(1000); IO.puts("done sleeping") end)
end

この場合、コールバックで1秒間スリープしてから何かを出力する単純なプロセスを開始しています。これは、startコールバックのAPIを満たすのに十分ですが、表示されません"done sleeping"。これはmix run、コールバックの実行が終了すると、デフォルトで終了するためです。これが発生しないようにするには、を使用する必要mix run --no-haltがあります。この場合、VMは停止しません。

アプリケーションを起動するもう1つの便利な方法は、次のとおりです。iex -S mixこれは、コードや実行中のアプリケーションと対話できるシェルをmix run --no-halt開くのと同じようにiex動作します。


5
さて、それはほとんど私が必要としたものです!もう一つは、あなたがこの説明することができますreturned a bad value: :okがありますいない場合にエラーをTask、かAgentまたはSupervisorその他?それはどのように機能し、なぜ別のプロセスが必要なのですか?必要なものを実行するスクリプトを実行できないのはなぜですか?
カミルレロネック2015年

19
アプリケーションコールバックは、監視ツリーを返す必要があります。返却しないと失敗します。実際、Pawełによって示された最後の式を次のように置き換えることもできますSupervisor.start_link [], strategy: :one_for_one。シャットダウンするタスクを返すと、スリープ後にアプリケーションが失敗する可能性があります。
ホセヴァリム2015年

1
@squixyアプリケーションを使用して定義することの利点のいくつかは、ここで説明されていますstackoverflow.com/questions/30422184/...
ホセ・Valim

2
長時間実行されるアプリケーションを構築している場合は、ほとんどの場合、が必要ですSupervisor。私はTaskちょうど最小の正しいプログラムを持っているために使用しましたが、ホセが述べたように-あなたはそこであなたの監督ツリーを始めたいと思っています。
パヴェルObrok

1
素晴らしい答えです!ただし、1つの質問です。IO.puts "something"ファイルを挿入しただけで、その行はコンパイル時にのみ評価され、実行時には何も実行されない」と書いています。これは私が見ているものに対応しているようですが、私はこれの論理を理解していませんか?なぜそれがそのように機能するのですか?
user2104969 2016

10

Mix.Task代わりにモジュールにインポートすることでタスクを実行できますmix run

これがあなたが探しているものだと思います。

その上、の代わりにmix <task.run>、単に実行mixしてデフォルトのタスクを実行できます。単に追加default_task: "bot.run"のリストにdef project do [..] endの中でmix.exsこちらをご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.