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] [source] [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 comment