Elixir notes Appendix – IEx

Background art by Dmitry Burmak

When you start to use Elixir, one of the first thing that you use or see people using is IEx, let’s understand its main features and how it can help you.

IEx which stands for Interactive Elixir it’s a core part of Elixir, it can be seen as Elixir’s REPL(Read–eval–print loop) if you’re coming for other modern languages. It’s helpful when you’re developing your application, and know how to use it can save you time.

Evaluating Expressions

IEx already comes with Elixir, so, if you have elixir installed (Or inside a docker container please) you just need to type iex and you’ll enter.

Erlang/OTP 22 [erts-10.4.1]  [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]              

Interactive Elixir (1.8.2) - press Ctrl+C to exit (type h() ENTER for help)                               
iex(1)>

At interactive mode any Elixir expression will be evaluated, for example:

iex(1)> 1 + 1
2

It sounds like ship ice to Antarctica for people coming from scripting languages with built-in REPL like Ruby or Python, but it’s worth knowing how to use IEx to be a powerful tool in your development.

It’s important to remember that any expression in IEx will be evaluated and not compiled, so, it’s not recommended to run benchmarks (or something like that) inside IEx.

Different from many similar applications IEx can’t be closed by typing ctrl + d or sending SIGINT signal (ctrl + c), if you type ctrl+c an interesting menu will be displayed:

iex(2)>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
       (v)ersion (k)ill (D)b-tables (d)istribution

For now, everything that you need to know is that if you type a and press enter you’ll close IEx, but one great people make a nice shortcut: Press ctrl+c two times and you’ll close it too.

Multi Line

It suports multi line expressions too:

iex(1)> fn (a, b) ->
...(1)> a + b
...(1)> end
#Function<13.91303403/2 in :erl_eval.expr/5>

If you want to copy and paste a multi line valid expression:

[1, [2], 3]
|> List.flatten()

Sometimes it won’t work, for example:

iex(1)> [1, [2], 3]
[1, [2], 3]
iex(2)> |> List.flatten()
** (SyntaxError) iex:2: syntax error before: '|>'

In these cases a nice tip is to place your multi line expression inside parentheses.

iex(2)> (
...(2)> [1, [2], 3]
...(2)> |> List.flatten()
...(2)> )
[1, 2, 3]

If you get stuck into a multi-line statement and doesn’t know how to get out of this, is just type #iex:break:

iex(3)> ["12
...(3)> c"
...(3)> 3 + 3
...(3)> 2 / 3
...(3)> \
...(3)> "
...(3)> ]
...(3)>
...(3)>
...(3)>
...(3)> #iex:break
** (TokenMissingError) iex:3: incomplete expression

Autocomplete

IEx comes with autocomplete too, and it works very fast, just type tab and it will show your options.

iex(1)> List.
Chars                 ascii_printable?/1    ascii_printable?/2
delete/2              delete_at/2           duplicate/2
first/1               flatten/1             flatten/2
foldl/3               foldr/3               improper?/1
insert_at/3           keydelete/3           keyfind/3
keyfind/4             keymember?/3          keyreplace/4
keysort/2             keystore/4            keytake/3
last/1                myers_difference/2    myers_difference/3
pop_at/2              pop_at/3              replace_at/3
starts_with?/2        to_atom/1             to_charlist/1
to_existing_atom/1    to_float/1            to_integer/1
to_integer/2          to_string/1           to_tuple/1
update_at/3           wrap/1                zip/1

iex(1)> List.

And if you type List.del it will complete for you offcourse, just press tab like you do on Linux.

Compiling

If you write a module:

defmodule Hello do
  def hello do
    IO.puts "Hello World"
  end
end

You can compile it inside your IEx, and then, use it.

iex(1)> c "test.ex"
[Hello]
iex(2)> Hello.hello
Hello World
:ok

Now if you change your module message to be “Hello Universe”, it won’t reload your module automatically, you need to recompile it using r/1 or compiling it again with c/1:

iex(4)> r Hello
warning: redefining module Hello (current version defined in memory)
  test.ex:1

{:reloaded, Hello, [Hello]}
iex(5)> Hello.hello
Hello Universe
:ok

A important thing to know is that if your file its a interpreted file of type exs, it will not be compiled and just interpreted.

Getting Past Expressions

It’s common to have a way to get the value of the past expressions, IEx you just need to use v:

iex(8)> 3 + 3
6
iex(9)> v
6

Shell history and history search

I love to use terminals, and I love to search throughout the history for a command that I made last year just typing Ctrl + r, inside IEx it’s possible to do the same just typing Ctrl + r too:

iex(1)> 1 + 2
3
iex(2)> 11 + 3
14
iex(3)> 1 + 3
4
(search)`11': 11 + 3

IEx doesn’t preserve your shell history if you close your session, but you can keep it by just setting one env var, can you imagine doing history search across all command that you ever typed?

export ERL_AFLAGS="-kernel shell_history enabled"

If you want to configure something about IEx, you can use configure/1, it has a lot of options of customization like colors, and you can setup things like history size too, I recommend you read about it here.

Debugging

One of the most loved thing to any developer it’s a debugger, with debugger you can develop more easily, find bugs and much more. Elixir happily has its debugger too, and to use it’s very simple, just paste require IEx; IEx.pry where you want that your application stop, let’s see an example with our Hello module, to see it working let’s add our message to one variable:

defmodule Hello do
  def hello do
    message = "Hello World"
    require IEx; IEx.pry
    IO.puts message
  end
end

After this, just call hello method inside our iex:

iex(1)> c "test.ex"
[Hello]
iex(2)> Hello.hello
Break reached: Hello.hello/0 (test.ex:4)

    2:   def hello do
    3:     message = "Hello World"
    4:     require IEx; IEx.pry
    5:     IO.puts message
    6:   end

pry(1)> message
"Hello World"
pry(2)> continue
Hello World
:ok

Elixir has many ways to debug your applications, this one is the simplest along with IO.inspect, and can be very helpful when you’re starting to study Elixir or dealing with simple bugs inside your app.

Displaying Help and Information

If you want to read docs about some module you just need to use helper h/1, it will display all the documentation shipped with the module like h Map, you can use the same helper to know about one method, for example h Map.keys (I’ll not paste here the output because its too long).

If you want to get information about any Elixir term, just use the i/1, example:

iex(7)> i Map
Term
  Map
Data type
  Atom

... ... 

You can get information about types defined inside module to:

iex(1)> t(Enum)
@type default() :: any()

@type index() :: integer()

@type element() :: any()

@type acc() :: any()

@type t() :: Enumerable.t()

Conclusions

IEx can help you when studying or developing Elixir, it has many beautiful features, in this post I don’t cover everyone but the principal ones, I think that all you need to start developing Elixir is here. In future posts I can return to IEx to talk about otherr features like connecting in remote nodes.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares@gmail.com), pm me on my Twitter or comment on this post!

Follow my blog to get notified every new post:

One thought on “Elixir notes Appendix – IEx

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: