Writing a command line application in Elixir
During the last days I got the chance to spend a bit of time playing around with Elixir. Elixir is, compared to other languages still a very new one. It has a Ruby-like syntax and compiles to Erlang VM bytecode. It is available for all major Linux distributions, Mac OS X and Windows.
For install instructions, please check their guide here.
At first, check your installed version:
$ elixir -v
Elixir 1.0.3
Everything >= 1.0 is fine.
We start with a scaffold by running mix new
. mix
basically does the job of Ruby’s bundler
and rake
.
mix new
creates a folder structure and places some files in there which are necessary to build an Elixir application.
$ mix new example
This creates a new folder example
with the following structure:
$ tree example
example
├── README.md
├── config
│ └── config.exs
├── lib
│ └── example.ex
├── mix.exs
└── test
├── example_test.exs
└── test_helper.exs
3 directories, 6 files
There is a lib
folder which contains all application code. mix.exs
holds the metadata and dependencies of your application.
Now run mix
to compile your app the first time.
Elixir uses escript
to build an executable. Its only dependency is Erlang installed on your machine. Elixir is not necessary, since escript
embedds
Elixir into the compiled app. At first we need to set the main_module
in mix.exs
by extending the existing function:
def project do
[app: :example,
version: "0.0.1",
elixir: "~> 1.0",
escript: [main_module: Example], # <- add this line
deps: deps]
end
This require a main
function in your main module:
defmodule Example do
def main(args) do
IO.puts "Hello world"
end
end
The main
function gets some args
containing all arguments passed from the command line. args
is a list holding all passed arguments or in case the
user didn't pass anything, it's empty. Elixir ships with builtin support for option parsing. The module is called OptionParser
:
defp parse_args(args) do
{options, _, _} = OptionParser.parse(args,
switches: [foo: :string]
)
options
end
This function is also defined in the Example
module. It takes the command line arguments and parses them. We need to tell OptionParser
what switches we
expect. parse/2
returns a tuple containing three values where we're only interested in the first one.
The second element holds remaining arguments and the last one invalid options.
options
is a Keyword list containing all options converted to atoms with their associated value.
The following example handles a name
option and prints out a greeting if given or another string if not.
defmodule Example do
def main(args) do
args |> parse_args |> process
end
def process([]) do
IO.puts "No arguments given"
end
def process(options) do
IO.puts "Hello #{options[:name]}"
end
defp parse_args(args) do
{options, _, _} = OptionParser.parse(args,
switches: [name: :string]
)
options
end
end
Then create an executable and run it with an argument:
$ mix escript.build
$ ./example --name=Jan
The main function of the module takes all arguments, parses them and outputs a string to stdout
.
The functions use pattern matching to determine if option name
is available or not and prints a string accordingly.