web-dev-qa-db-ja.com

**(ArgumentError)を取得せずにElixirコンソールで名前付き関数を定義するにはどうすればよいですか?モジュールの外部でdef / 2を呼び出すことはできませんか?

モジュールで名前付き関数を問題なく定義できますが、iex>またはex>コンソールで使用するためのコツをまだ持っていません。

Defコマンドを実行しようとすると、次のエラーが発生し続けます。

(ArgumentError) cannot invoke def/2 outside module

pprime.exs

IO.puts "initial division test"

defmodule Expand do
    def transform(myvar) do
        8 * myvar + 3;
    end
end

div2 = fn inputnum ->
  [:a, inputnum/2.0, inputnum/3, inputnum/5.0, inputnum/7]
end

output = div2.(20.1)

次のように、これをelixirで問題なく実行できます。

$ elixir pprime.exs

ただし、コンソールでは、そのようなことはできないようです。

Erlang/OTP 17 [erts-6.3] [source] [64-bit] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.0.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> def transform(myvar) do 8 * myvar + 3; end
** (ArgumentError) cannot invoke def/2 outside module
    (elixir) lib/kernel.ex:3556: Kernel.assert_module_scope/3
    (elixir) lib/kernel.ex:2816: Kernel.define/4
    (elixir) expanding macro: Kernel.def/2
    (elixir) iex:1: :elixir_compiler.__FILE__/2

Elixirコンソールで名前付き関数を定義するにはどうすればよいですか?

これも可能ですか?

Elixirコンソールで使用するための特別なモジュールを作成する必要がありますか?

22
Nathan Basanese

簡単な答え:できません。

長い答え:ホットコードスワッピングなどの多くのElixir機能は、コードコンテナーとしてモジュールを持つことに依存しているため、Elixirのすべてのコードはモジュール内に存在します。そのため、モジュールの外部で関数を定義することはできません(追加できるグローバルで変更可能な名前空間はありません)。

22
José Valim

モジュールはiexで定義できます。コピーアンドペーストは問題なく機能します。

iex(1)> defmodule Expand do
...(1)>     def transform(myvar) do
...(1)>         8 * myvar + 3;
...(1)>     end
...(1)> end
iex(2)> Expand.transform(12)
99
iex(3)> defmodule Expand do
...(3)>     def transform(myvar) do
...(3)>         3 * myvar + 5
...(3)>     end
...(3)> end
iex:3: warning: redefining module Expand
iex(4)> Expand.transform(12)
41
21
greggreg