gears

If you’re new to Elixir, hopefully this post can help knock out a few of the basic problems you’d encounter in your first few hours of trying elixir, in order to get to the more interesting stuff faster!

1. How to get out of the “shell-break” menu: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded

I can’t tell you the number of times I’ve thought to myself, “I have 10 minutes to kill, why not play with erlang/elixir?”, gotten stuck on this prompt, realized I had more pressing things to do, and moved on to another task. Fifteen times, maybe higher.

So you start typing some code, realize you’ve made a mistake. You hit ctrl-c to cancel what you’ve entered, and you’re given a strange prompt, which Erlang calls the “shell-break”:

1
2
3
4
iex(2)> x = fn (a, b) ->
...(2)>   c + b
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution

The only 2 options you need to care about are (c) and (a). (c)ontinue is the option that takes you back to the normal entry mode, but if you want to continue–and this is really not obvious–you have to hit enter twice. (a) will exit the repl.

This is pretty old behavior that is defined in BEAM, the virtual machine that interprets Elixir and Erlang code. The other option spews out a ton of information that is certain to come in handy, someday, if you’re debugging BEAM itself, but it’s overkill for now.

2. How to get information about a module in the repl

One of my favorite things in Ruby is how you can call methods on any object, and get back the list of methods the object supports. I found this to be invaluable when I was starting out with Ruby, and I still use it all the time.

So how do you do that in elixir? Module.module_info. Example:

1
2
3
4
5
6
7
8
# defined in foo/bar/awesome.ex
defmodule Awesome do
  def very_cool(arg) do
    # ...
  end

  def beast_is_the_best_of_the_x_men, do: true
end
1
2
iex(4) Awesome.module_info(:exports)
[:beast_is_the_best_of_the_x_men/0, :very_cool/1]

With no arguments, module_info returns a keyword list, with keys: [:module, :attributes, :compile, :native, :md5]. Any of those can be passed as arguments, to scope the return value.

There are also some things you can’t do in the Elixir repl, that you might expect, especially if you’re coming from ruby.

3. Defining functions in IEx

In Ruby’s repl you can define top-level functions (and this is true for almost every other language). But if you try something like this in IEX:

1
2
3
iex(9)> def square(x) do
...(9)>   x * x
...(9)> end

You’ll get:

1
2
3
4
5
** (ArgumentError) cannot invoke def/2 outside module
    (elixir) lib/kernel.ex:4297: Kernel.assert_module_scope/3
    (elixir) lib/kernel.ex:3299: Kernel.define/4
    (elixir) expanding macro: Kernel.def/2
             iex:9: (file)

There are 2 options. There are 2 options. You can define an anonymous function, but then you need to call it with a sorta weird syntax (which technically is valid in Ruby, but pretty obscure):

1
2
3
iex(8) square = fn (x) -> x * x end
iex(9) square.(20)
400

Or you can define an extra module. You’re probably better off doing it this way, or even starting to put the definitions in a file.

1
2
3
4
5
6
7
iex(10) defmodule Necessary do
...(10)   def square (x) do
...(10)     x * x
...(10)   end
...(10) end
iex(10) Necessary.square(20)
400

4. Compiling code in a file

Say that you’ve defined some code in a module. You can compile it with c followed by the path to the file:

1
2
iex(3)> c "foo/bar/awesome.ex"
[Awesome]

Any modules that are defined in awesome.ex will be available for use.

5. Add new functions to a module

Elixir’s modules aren’t open; if you try to defmodule AlreadyExistingModule ..., you’ll just redefine the module, so it’ll only have the functions you’ve specified in the new definition. This also means you can’t really monkeypatch a core module.

If you want to add a new function or redefine one, and the code is stored in a file, you can edit it, and recompile by enterering r ModuleName. This will rebuild the code, and any subsequent calls to the updated methods will have the new definition.

6. (Bonus): h to learn more about other available commands

The syntax and tooling are really similar to Ruby, but the language also has totally different properties. It’s exciting that there’s so much growing interest in Elixir. Go out and play around in the REPL!