Как я могу определить именованные функции в консоли Elixir, не получив ** (ArgumentError) не может вызвать 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 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?

Это вообще возможно?

Нужно ли мне создавать специальный модуль для использования в консоли «Эликсир»?


person Nathan Basanese    schedule 10.02.2015    source источник


Ответы (2)


Краткий ответ: нельзя.

Длинный ответ: весь код в Elixir существует внутри модулей, поскольку многие функции Elixir, такие как горячая замена кода, зависят от наличия модулей в качестве контейнера кода. Вот почему вы не можете определять функции вне модулей (нет глобального изменяемого пространства имен, в которое они могли бы быть добавлены).

person José Valim    schedule 10.02.2015
comment
Можно ли добавить в консоль Elixir модуль для определения функции? - person Nathan Basanese; 11.02.2015
comment
Да, вы можете просто вложить def в defmodule, как в файле exs. - person Patrick Oscity; 11.02.2015

Вы можете определить модуль в 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
person greggreg    schedule 11.02.2015
comment
Или, если вы не хотите определять весь модуль, вы можете использовать анонимные функции: transform = fn(myvar) -> 8 * myvar + 3 end, а затем transform.(5) - person tkowal; 11.02.2015