Tools to help Elixir Exercism.IO Mentors

I have been mentoring Elixir on Exercism.IO for about 6 months.

Over that time I have started to build a collection of tools to help with the mentoring.

This is the major trick that I use to help find problems:

grep -v @tag *_test.exs > test.exs && elixir test.

I also have my notes for mentoring:

https://devrants.blog/useful-elixir-links/

I have now found that you can install credo to run globally (apparently this is contentious – it can cause problems if you have different versions installed locally and globally):

git clone git@github.com:rrrene/bunt.git

cd bunt

mix archive.build

mix archive.install

cd –

git clone git@github.com:rrrene/credo.git

cd credo

mix deps.get

mix archive.build

mix archive.install

Once you have that then you can now use:

mix credo *.exs –verbose –strict

It’s also useful if students are having trouble with documentation to submit pull requests to:

  • elixirschool.com – Elixir training
  • elixir-lang – Elixir documentation
  • elixir – Hex docs

Getting Started With Phoenix 1.4 (Part 3)

Continuing the way through the book.

Now have reached the end of Chapter 6.

This adds video to use associations. It includes some of the clever techniques that Phoenix uses to allow the templates to be customised.

By adding an action method you can customise the parameters passed to the various utility methods:

def action(conn, _) do args = [conn, conn.params, conn.assigns.current_user] apply(__MODULE__, action_name(conn), args) end

This allows details from the conn to be decomposed and passed as a parameter.

https://github.com/chriseyre2000/rumbl_1_4

Elixir Supervisor Introduction

This is a simple introduction to OTP in Elixir.

The sample is based heavily upon Introducing Elixir.

This will demonstrate how Elixir keeps a server alive across code recompilation, and restores a server after it has crashed.

This assumes that you have installed Elixir.

On a mac you can install this with (there are other solutions on other platforms):

brew install elixir

Start by cloning the repo:

git clone https://github.com/chriseyre2000/drop_server.git

Change directory into the drop_server folder.

Type

iex -S mix

This will start the application running inside the interactive Elixir REPL.

This application has a DropServer.Worker being monitored by a supervisor.

First you can calculate the velocity after falling a distance in meters:

(Type the bit after the iex> prompts):

iex(1)> DropServer.Worker.calculate_drop(40)

{“ok”, 28.0}

iex(2)> DropServer.Worker.calculate_drop(41)

{“ok”, 28.347839423843222}

iex(3)> DropServer.Worker.calculate_drop(42)

{“ok”, 28.691462144686877}

iex(4)> DropServer.Worker.how_many_calls

So far calculated 3 velocities.

:ok

You can even recompile the DropServer.Worker while it is running:

iex(5)> c(“lib/drop_server/drop_server.ex”)

warning: redefining module DropServer.Worker (current version loaded from _build/dev/lib/drop_server/ebin/Elixir.DropServer.Worker.beam)

lib/drop_server/drop_server.ex:1

warning: redefining module DropServer.Worker.State (current version loaded from _build/dev/lib/drop_server/ebin/Elixir.DropServer.Worker.State.beam)

lib/drop_server/drop_server.ex:4

[DropServer.Worker, DropServer.Worker.State]

This even maintains the state:

iex(6)> DropServer.Worker.how_many_calls

So far calculated 3 velocities.

:ok

Now if you give it some invalid data Elixir will do the classic Erlang thing and let it crash!

iex(7)> DropServer.Worker.calculate_drop(-1)

21:49:21.278 [error] GenServer DropServer.Worker terminating

** (ArithmeticError) bad argument in arithmetic expression

(stdlib) :math.sqrt(-19.6)

(drop_server) lib/drop_server/drop_server.ex:44: DropServer.Worker.fall_velocity/1

(drop_server) lib/drop_server/drop_server.ex:20: DropServer.Worker.handle_call/3

(stdlib) gen_server.erl:661: :gen_server.try_handle_call/4

(stdlib) gen_server.erl:690: :gen_server.handle_msg/6

(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

Last message (from #PID<0.133.0>): -1

State: %DropServer.Worker.State{count: 3}

Client #PID<0.133.0> is alive

(stdlib) gen.erl:169: :gen.do_call/4

(elixir) lib/gen_server.ex:921: GenServer.call/3

(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

(elixir) src/elixir.erl:265: :elixir.eval_forms/4

(iex) lib/iex/evaluator.ex:249: IEx.Evaluator.handle_eval/5

(iex) lib/iex/evaluator.ex:229: IEx.Evaluator.do_eval/3

(iex) lib/iex/evaluator.ex:207: IEx.Evaluator.eval/3

(iex) lib/iex/evaluator.ex:94: IEx.Evaluator.loop/1

** (exit) exited in: GenServer.call(DropServer.Worker, -1, 5000)

** (EXIT) an exception was raised:

** (ArithmeticError) bad argument in arithmetic expression

(stdlib) :math.sqrt(-19.6)

(drop_server) lib/drop_server/drop_server.ex:44: DropServer.Worker.fall_velocity/1

(drop_server) lib/drop_server/drop_server.ex:20: DropServer.Worker.handle_call/3

(stdlib) gen_server.erl:661: :gen_server.try_handle_call/4

(stdlib) gen_server.erl:690: :gen_server.handle_msg/6

(stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3

(elixir) lib/gen_server.ex:924: GenServer.call/3

However only the state is lost:

iex(7)> DropServer.Worker.how_many_calls

So far calculated 0 velocities.

:ok

iex(8)> DropServer.Worker.calculate_drop(10)

{“ok”, 14.0}

iex(9)> DropServer.Worker.how_many_calls

So far calculated 1 velocities.

:ok

The supervisor has restarted the server.

In a real service the state would have been kept in a distinct service possibly with some form of persistence.

Elixir Metaprogramming : the basics

Elixir has a very small core language. Most of what is thought of as the syntax is actually written using macros.

Elixir makes it ridiculously easy to get at the Abstract Syntax Tree (AST) of the code that you are using.

How to get the AST of some code:

iex(1)> quote do: 1 + 1
{:+, [context: Elixir, import: Kernel], [1, 1]}

Httpoison on windows

I have been having trouble getting the Httpoison library working on my windows development machine. I had put this down to portability issues in the past.

Last weekend I spent some time trying to track down the bug so that I could send a patch to the appropriate project.

During this investigation I found that I had been using a fairly old version of Erlang (10) which seemed to work everywhere else but had a problem with the crypto checking that HTTPoison performs. I had installed Erlang when studying 7 languages in 7 weeks over 6 years ago.

Moral of the story: don’t blame the tools, try to fix them and you may find the source of the problem.

Phoenix for Rails Developers – Part 1

I was lucky enough to win a copy of Phoenix for Rails Developers.

(Thanks to @plataformatec)

This gives me one more thing to study!

Oddly I am not a Rails developer (but have worked on a number of frameworks that were inspired by Rails).

So far I am working through the main examples and will post them here:

https://github.com/chriseyre2000/storex

I am developing this using Visual Studio Code.

Typically I also have two terminal tabs open.

The first is to run the application in:

mix phx.server

or

iex -S phx.server

The second is used for generator or to update git.

I am working with Elixir 1.6.4

So far the book is a gentle introduction to Phoenix. The language is introduced as needed.

It has stayed away from more complex Elixir topics (OTP).

When I have made typos the Elixir compiler will always tell you exactly where you have made the mistake, although it is not always obvious what the mistake was. The live reloading of the web application does allow for very rapid feedback. You do need to remember to restart the app on non-website changes.

The only catch that I have had so far is setting up Postgres locally. All other details have been clearly explained.

Equivalent Ecosystems: Groovy vs Elixir

Given that a little over two years ago I was a C# developer I have had to learn the JVM way of doing things fairly rapidly. Java does has many ways of solving things but these are those that I am familiar with:

Here is a map between the Java world and the Elixir world

JVM => BEAM

Gradle => Mix

https://search.maven.org/ => https://hex.pm

JUnit => ExUnit

JavaDoc => ExDoc

Dropwizard (or web framework of choice) => Phoenix

Jooq => Ecto

More Elixir on Windows

I am still working my way through the Programming Elixir book.

This time I am trying to get the sample issues app to work on Windows.

Elixir is fine on windows – its the HTTPoison library – it has dependencies that fail silently at compile time. Known issue

However the HTTPotion library does seem to work on windows. I have adapted the sample and have a github repo with this applied.

This is a similar problem to the Javascript/NPM world. Windows is treated as a second class citizen by some of the libraries which creates artificial constraints. Windows can be used as a development platform for more portable development (I use windows at home, ubuntu in the office and have a mac work laptop – I need portability).