In this book, I show a terminal session like this:
| $ echo Hello, World |
| Hello, World |
The terminal prompt is the dollar sign, and the stuff you type follows. (On your system, the prompt will likely be different.) Output from the system is shown without highlighting.
To test that your Elixir installation was successful, let’s start an interactive Elixir session. At your regular shell prompt, type iex.
| $ iex |
| Erlang/OTP 20 [erts-9.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] |
| [async-threads:10] [hipe] [kernel-poll:false]h |
| Interactive Elixir (x.y.z) - press Ctrl+C to exit (type h() ENTER for h |
| elp) |
| iex(1)> |
(The various version numbers you see will likely be different—I won’t bother to show them on subsequent examples.)
Once you have an IEx prompt, you can enter Elixir code and you’ll see the result. If you enter an expression that continues over more than one line, IEx will prompt for the additional lines with an ellipsis (…).
| iex(1)> 3 + 4 |
| 7 |
| iex(2)> String.reverse "madamimadam" |
| "madamimadam" |
| iex(3)> 5 * |
| ...(3)> 6 |
| 30 |
| iex(4)> |
The number in the prompt increments for each complete expression executed. I’ll omit the number in most of the examples that follow.
There are several ways of exiting from IEx—none are tidy. The easiest two are typing Ctrl-C twice or typing Ctrl-G followed by q and Return. On some systems, you can also use a single Ctrl-\.
IEx has a number of helper functions. Type h (followed by Return) to get a list:
| iex> h |
| IEx.Helpers |
| |
| Welcome to Interactive Elixir. You are currently seeing the documentation |
| for the module IEx.Helpers which provides many helpers to make Elixir's |
| shell more joyful to work with. |
| |
| This message was triggered by invoking the helper h(), usually referred to |
| as h/0 (since it expects 0 arguments). |
| |
| You can use the h/1 function to invoke the documentation for any Elixir |
| module or function: |
| |
| iex> h(Enum) |
| iex> h(Enum.map) |
| iex> h(Enum.reverse/1) |
| |
| You can also use the i/1 function to introspect any value you have in the |
| shell: |
| |
| iex> i("hello") |
| |
| There are many other helpers available, here are some examples: |
| |
| • b/1 - prints callbacks info and docs for a given module |
| • c/1 - compiles a file into the current directory |
| • c/2 - compiles a file to the given path |
| • cd/1 - changes the current directory |
| • clear/0 - clears the screen |
| • exports/1 - shows all exports (functions + macros) in a module |
| • flush/0 - flushes all messages sent to the shell |
| • h/0 - prints this help message |
| • h/1 - prints help for the given module, function or macro |
| • i/0 - prints information about the last value |
| • i/1 - prints information about the given term |
| • ls/0 - lists the contents of the current directory |
| • ls/1 - lists the contents of the specified directory |
| • open/1 - opens the source for the given module or function |
| in your editor |
| • pid/1 - creates a PID from a string |
| • pid/3 - creates a PID with the 3 integer arguments passed |
| • ref/1 - creates a Reference from a string |
| • ref/4 - creates a Reference with the 4 integer arguments |
| passed |
| • pwd/0 - prints the current working directory |
| • r/1 - recompiles the given module's source file |
| • recompile/0 - recompiles the current project |
| • runtime_info/0 - prints runtime info (versions, memory usage, stats) |
| • v/0 - retrieves the last value from the history |
| • v/1 - retrieves the nth value from the history |
| |
| Help for all of those functions can be consulted directly from the command |
| line using the h/1 helper itself. Try: |
| |
| iex> h(v/0) |
| |
| To list all IEx helpers available, which is effectively all exports |
| (functions and macros) in the IEx.Helpers module: |
| |
| iex> exports(IEx.Helpers) |
| |
| This module also includes helpers for debugging purposes, see IEx.break!/4 |
| for more information. |
| |
| To learn more about IEx as a whole, type h(IEx). |
In the list of helper functions, the number following the slash is the number of arguments the helper expects.
Probably the most useful is h itself. With an argument, it gives you help on Elixir modules or individual functions in a module. This works for any modules loaded into IEx (so when we talk about projects later on, you’ll see your own documentation here, too). For example, the IO module performs common input/output functions. For help on the module, type h(IO) or h IO:
| iex> h IO # or... |
| iex> h(IO) |
| |
| Functions handling IO. |
| |
| Many functions in this module expect an IO device as argument. An IO device |
| must be a PID or an atom representing a process. For convenience, Elixir |
| provides :stdio and :stderr as shortcuts to Erlang's :standard_io and |
| :standard_error.... |
This book frequently uses the puts function in the IO module, which in its simplest form writes a string to the console. Let’s get the documentation:
| iex> h IO.puts |
| def puts(device \\ :stdio, item) |
| |
| Writes item to the given device, similar to write/2, but adds a |
| newline at the end. |
| |
| By default, the device is the standard output. It returns :ok if it |
| succeeds. |
| |
| ## Examples |
| |
| IO.puts "Hello, World!" |
| #=> Hello, World! |
| |
| IO.puts :stderr, "error" |
| #=> error |
Another informative helper is i, which displays information about a value:
| iex> i 123 |
| Term |
| 123 |
| Data type |
| Integer |
| Reference modules |
| Integer |
| Implemented protocols |
| IEx.Info, Inspect, List.Chars, String.Chars |
| |
| iex> i "cat" |
| Term |
| "cat" |
| Data type |
| BitString |
| Byte size |
| 3 |
| Description |
| This is a string: a UTF-8 encoded binary. It's printed surrounded by |
| "double quotes" because all UTF-8 encoded codepoints in it are printable. |
| Raw representation |
| <<99, 97, 116>> |
| Reference modules |
| String, :binary |
| Implemented protocols |
| IEx.Info, Collectable, Inspect, List.Chars, String.Chars |
| |
| iex> i %{ name: "Dave", likes: "Elixir" } |
| Term |
| %{likes: "Elixir", name: "Dave"} |
| Data type |
| Map |
| Reference modules |
| Map |
| Implemented protocols |
| IEx.Info, Collectable, Enumerable, Inspect |
| |
| iex> i Map |
| Term |
| Map |
| Data type |
| Atom |
| Module bytecode |
| bin/../lib/elixir/ebin/Elixir.Map.beam |
| Source |
| lib/elixir/lib/map.ex |
| Version |
| [234303838320399652689109978883853316190] |
| Compile options |
| [] |
| Description |
| Use h(Map) to access its documentation. |
| Call Map.module_info() to access metadata. |
| Raw representation |
| :"Elixir.Map" |
| Reference modules |
| Module, Atom |
| Implemented protocols |
| IEx.Info, Inspect, List.Chars, String.Chars |
IEx is a surprisingly powerful tool. Use it to compile and execute entire projects, log in to remote machines, and access running Elixir applications.
And, if you happen to include the occasional bug in your code (deliberately, of course), IEx has a simple debugger. We’ll talk about it when we look at tooling.
You can customize IEx by setting options. For example, I like showing the results of evaluations in bright cyan. To find out how to do that, I used this:
| iex> h IEx.configure |
| def configure(options) |
| |
| Configures IEx. |
| |
| The supported options are: :colors, :inspect, :default_prompt, |
| :alive_prompt and :history_size. |
| |
| Colors |
| |
| A keyword list that encapsulates all color settings used by the shell. See |
| documentation for the IO.ANSI module for the list of supported colors and |
| attributes. |
| |
| The value is a keyword list. List of supported keys: |
| |
| • :enabled - boolean value that allows for switching the coloring |
| on and off |
| • :eval_result - color for an expression's resulting value |
| • :eval_info - … various informational messages |
| • :eval_error - … error messages |
| • :stack_app - … the app in stack traces |
| • :stack_info - … the remaining info in stack traces |
| • :ls_directory - … for directory entries (ls helper) |
| • :ls_device - … device entries (ls helper) |
| |
| . . . |
I then created a file called .iex.exs in my home directory, containing
| IEx.configure colors: [ eval_result: [ :cyan, :bright ] ] |
If your IEx session looks messed up (and things such as [33m appear in the output), it’s likely your console does not support ANSI escape sequences. In that case, disable colorization using
| IEx.configure colors: [enabled: false] |
You can put any Elixir code into .iex.exs.
Once you tire of writing one-line programs in IEx, you’ll want to start putting code into source files. These files will typically have the extension .ex or .exs. This is a convention—files ending in .ex are intended to be compiled into bytecodes and then run, whereas those ending in .exs are more like programs in scripting languages—they are effectively interpreted at the source level. When we come to write tests for our Elixir programs, you’ll see that the application files have .ex extensions, whereas the tests have .exs because we don’t need to keep compiled versions of the tests lying around.
Let’s write the classic first program. Go to a working directory and create a file called hello.exs.
| IO.puts "Hello, World!" |
That example shows how most of the code listings in this book are presented. The bar before the code itself shows the path and file name that contains the code. If you’re reading an ebook, you’ll be able to click on this to download the source file. You can also download all the code by visiting the book’s page on our site and clicking on the Source Code link.[2]
Source file names are written in lowercase with underscores. They will have the extension .ex for programs that you intend to compile into binary form, and .exs for scripts that you want to run without compiling. Our “Hello, World” example is essentially throw-away code, so we used the .exs extension for it.
Having created our source file, let’s run it. In the same directory where you created the file, run the elixir command:
| $ elixir hello.exs |
| Hello, World! |
We can also compile and run it inside IEx using the c helper:
| $ iex |
| iex> c "hello.exs" |
| Hello, World! |
| [] |
| iex> |
The c helper compiled and executed the source file. The [] that follows the output is the return value of the c function—if the source file had contained any modules, their names would have been listed here.
The c helper compiled the source file as freestanding code. You can also load a file as if you’d typed each line into IEx using import_file. In this case, local variables set in the file are available in the IEx session.
As some folks fret over such things, the Elixir convention is to use two-column indentation and spaces (not tabs).