2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

外部パッケージ依存のあるElixir scriptを簡単に走らせる

Posted at

何が嫌か

Elixirで例えばHttPoisonやらJasonやらを使ってサクッとスクリプトを書いて実行したいのにサクッとならない。

mapをjsonにエンコードする以下のようなスクリプトを書いたとして

%{foo: "bar"}
|> Jason.encode!
|> IO.puts

これを普通にelixirコマンドで実行しようとすると

$ elixir foo.exs
** (UndefinedFunctionError) function Jason.encode!/1 is undefined (module Jason is not available)
    Jason.encode!(%{foo: "bar"})
    foo.exs:2: (file)
    (elixir) lib/code.ex:767: Code.require_file/2

怒られる。世知辛い世の中。

当然といえば当然で、プロジェクトマネージャたるMixを使うとパッケージはグローバルにインストールされることはない。というかできない。
これはこれでプロジェクトごとにパッケージがクリーンに保たれるので、某pythonみたいにvirtualenvなんてものを考える必要はない。
その点でelixirおよびmixは素晴らしいと言えるのだが、時々こういう感じで困る。

結局どうしたか

escriptにdependencyを全部ぶち込んでElixir scriptを動的に読み込んで実行することでだいたい解決できた。
以下にerunとして公開している(驚くほど実装の中身がない)。
s417-lama/erun

Jasonをdepsに指定すればさっきの例は以下のようにちゃんと実行される。

$ erun foo.exs
{"foo":"bar"}

使い方

(1) cloneする

git clone git@github.com:s417-lama/erun.git

(2) mix.exsをいじって好きなdepsを指定する

  defp deps do
    [
      {:super_package, "~> 1.0"},
      ...
    ]
  end

(3) deps.get

mix deps.get

(4) コンパイルしてインストール

mix escript.install

(5) 使ってみる

$ erun -e "IO.puts :hello"
hello

あと、地味にErun.args/0を呼ぶと引数を取得できる。

$ erun -e "IO.inspect Erun.args" foo bar 1
["foo", "bar", "1"]

何ができないか

iexでグローバルなパッケージを読み込みたいが、erunではできない(スクリプト限定)。
なにか良いアイデアはないでしょうか...?

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?