Search code examples
elixirnamed

How can I define named functions in the Elixir console without getting ** (ArgumentError) cannot invoke def/2 outside module?


I can define named functions in modules just fine, but I haven't yet got the hang of it for use in the iex> or ex> consoles.

I keep getting the following error when I try to run the def command:

(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)

I can run this with elixir just fine, as follows:

$ elixir pprime.exs

However, in the console, I can't seem to do any such thing:

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

How can I define a named function in the Elixir console?

Is this even possible?

Do I need to create a special module for using in the Elixir console?


Solution

  • You can't define a named function in the Elixir console.

    At least not without wrapping it in a defmodule. See greggreg's alternative answer

    Long answer: All code in Elixir exist inside modules since many Elixir features, like hot code swapping, relies on having modules as the code container. That's why you can't define functions outside modules (there is no global, mutable namespace they could be added to).

    An alternative would be to use an anonymous function which does not need a module:

    mylambda = fn(x) -> x + 1 end

    And then calling it like mylambda.(2) resulting in 3. Remember the dot.