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.