Erlang ‘One Weird Trick’ Goodiebag
I’ve asked the Erlang twittersphere what they think every Erlang developer should know about. The result is this Erlang random goodiebag. I would love to hear your ‘One weird trick’ in the comments!
etop – Erlang Top
Erlang Top, etop
is an Erlang application for presenting information about erlang processes similar to the information presented by top
in UNIX.
You start it with the following command:
1
|
|
(Replace node@host
with the correct node name).
Output shows you the CPU load, memory allocation and more:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
More information about etop
can be found in the docs
h/t to @mmzeeman
Erlang Remote Shell
As you can ssh
into another server, you can also connect to the shell of a remote Erlang node. This allows you to inspect the live state of the system. Very powerful.
Below an example session where stop the mnesia
application on the live node from the remote shell
Start up the ‘live’ node and start the mnesia
application:
1 2 3 4 5 6 7 |
|
In another terminal window, connect to the live shell and try to start mnesia again. Notice it is already started, and we can stop the application.
1 2 3 4 5 6 7 8 9 |
|
Notice the info report on the previous terminal:
1 2 3 4 5 6 |
|
h/t to @aeden
Throw As Default Value
Erlang, and OTP, is build on the coding philosophy “Let It Crash”. The view is that you don’t need to program defensively. If there are any errors, the process is automatically terminated, and this is reported to any processes that were monitoring the crashed process. In fact, defensive programming in Erlang is frowned upon.
Record fields that are not given a value, are initialized with the value undefined
. Like null
in other programming languages, undefined
is considered a hack.
So to prevent undefined
field values in records, why not just make throw the default?
Example module:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Output:
1 2 3 4 5 6 |
|
h/t to @lambdadmitry
List Comprehension without generators
A typical list comprehension expression, like Xs = [X ||| X <- [1,2,3]]
, contains the generator X <- [1,2,3]
. But a list comprehension is not required to contain one or more generators.
This allows you to rewrite this case expression:
1 2 3 4 |
|
Into this short list comprehension: Z = [X || Y > 2]
.
A real world example of this pattern can be found in the OTP code base:
https://github.com/erlang/otp/..src/compile.erl#L1713-1714 https://github.com/erlang/otp/..src/v3_codegen.erl#L970-973
h/t to @nokusu
Inspecting process status in remote shell
With sys:get_status
you can quickly inspect the process status on your live node through a remote shell.
Below we inspect the status of a sample test_foo_ser
process, which implements the gen_server
behaviour. Among the information we get the callback module’s state {“State”,{state,”bar”,”oranges”}
. A gen_fsm
process returns information such as its current state name and state data, and a gen_event
process returns information about each of its registered handlers.
1 2 3 4 5 6 7 8 9 10 11 |
|
h/t to @OliverFerrigni
Recon, dialyzer, quickcheck & use iolists to save memory
A bunch of good tips by @zkessin:
- Recon (docs, github) aims “to be a set of tools usable in production to diagnose Erlang problems or inspect production environment safely”. Safely, as you don’t want to endanger the uptime of a live node.
- Dialyzer: In the past, very smart people tried to come up with a good static type system for Erlang. They couldn’t create one without throwing away some of Erlang’s magic, like hot code loading. Bummer, dude. Instead you can add type-annotations to your code, and check them with a tool called Dialyzer. It’s a sweet alternative to a static type system.
- Quickcheck: Unit testing is nice, but it has a big weakness for which Quickcheck is the solution. I’ve tried to explain this issue in a previous post Continuous Integration for Erlang With Travis-CI. Also, @zkessin just published a Testing Erlang With Quickcheck e-book that you might want to check out.
- Using iolists to save memory. //TODO