Mastering Elixir
eBook - ePub

Mastering Elixir

Build and scale concurrent, distributed, and fault-tolerant applications

André Albuquerque, Daniel Caixinha

Buch teilen
  1. 574 Seiten
  2. English
  3. ePUB (handyfreundlich)
  4. Über iOS und Android verfügbar
eBook - ePub

Mastering Elixir

Build and scale concurrent, distributed, and fault-tolerant applications

André Albuquerque, Daniel Caixinha

Angaben zum Buch
Buchvorschau
Inhaltsverzeichnis
Quellenangaben

Über dieses Buch

Leverage the power of Elixir programming language to solve practical problems associated with scalability, concurrency, fault tolerance, and high availability.

Key Features

  • Enhance your Elixir programming skills using its powerful tools and abstractions
  • Discover how to develop a full-fledged file server
  • Understand how to use Phoenix to create a web interface for your application.

Book Description

Running concurrent, fault-tolerant applications that scale is a very demanding responsibility. After learning the abstractions that Elixir gives us, developers are able to build such applications with inconceivable low effort. There is a big gap between playing around with Elixir and running it in production, serving live requests. This book will help you fll this gap by going into detail on several aspects of how Elixir works and showing concrete examples of how to apply the concepts learned to a fully fledged application. In this book, you will learn how to build a rock-solid application, beginning by using Mix to create a new project. Then you will learn how the use of Erlang's OTP, along with the Elixir abstractions that run on top of it (such as GenServer and GenStage), that allow you to build applications that are easy to parallelize and distribute. You will also master supervisors (and supervision trees), and comprehend how they are the basis for building fault-tolerant applications. Then you will use Phoenix to create a web interface for your application. Upon fnishing implementation, you will learn how to take your application to the cloud, using Kubernetes to automatically deploy, scale, and manage it. Last, but not least, you will keep your peace of mind by learning how to thoroughly test and then monitor your application.

What you will learn

  • Use Elixir tools, including IEx and Mix
  • Find out how an Elixir project is structured and how to create umbrella applications
  • Discover the power of supervision trees, the basis for fault-tolerance
  • Create a Domain-Specifc Language (DSL) that abstracts complexity
  • Create a blazing-fast web interface for your application with Phoenix
  • Set up an automatic deployment process for the cloud
  • Monitor your application and be warned if anything unexpected happens

Who this book is for

Mastering Elixir is for you if you have experience in Elixir programming and want to take it to the next level. This Elixir book shows you how to build, deploy, and maintain robust applications, allowing you to go from tinkering with Elixir on side projects to using it in a live environment. However, no prior knowledge of Elixir is required to enjoy the complex topics covered in the book.

Häufig gestellte Fragen

Wie kann ich mein Abo kündigen?
Gehe einfach zum Kontobereich in den Einstellungen und klicke auf „Abo kündigen“ – ganz einfach. Nachdem du gekündigt hast, bleibt deine Mitgliedschaft für den verbleibenden Abozeitraum, den du bereits bezahlt hast, aktiv. Mehr Informationen hier.
(Wie) Kann ich Bücher herunterladen?
Derzeit stehen all unsere auf Mobilgeräte reagierenden ePub-Bücher zum Download über die App zur Verfügung. Die meisten unserer PDFs stehen ebenfalls zum Download bereit; wir arbeiten daran, auch die übrigen PDFs zum Download anzubieten, bei denen dies aktuell noch nicht möglich ist. Weitere Informationen hier.
Welcher Unterschied besteht bei den Preisen zwischen den Aboplänen?
Mit beiden Aboplänen erhältst du vollen Zugang zur Bibliothek und allen Funktionen von Perlego. Die einzigen Unterschiede bestehen im Preis und dem Abozeitraum: Mit dem Jahresabo sparst du auf 12 Monate gerechnet im Vergleich zum Monatsabo rund 30 %.
Was ist Perlego?
Wir sind ein Online-Abodienst für Lehrbücher, bei dem du für weniger als den Preis eines einzelnen Buches pro Monat Zugang zu einer ganzen Online-Bibliothek erhältst. Mit über 1 Million Büchern zu über 1.000 verschiedenen Themen haben wir bestimmt alles, was du brauchst! Weitere Informationen hier.
Unterstützt Perlego Text-zu-Sprache?
Achte auf das Symbol zum Vorlesen in deinem nächsten Buch, um zu sehen, ob du es dir auch anhören kannst. Bei diesem Tool wird dir Text laut vorgelesen, wobei der Text beim Vorlesen auch grafisch hervorgehoben wird. Du kannst das Vorlesen jederzeit anhalten, beschleunigen und verlangsamen. Weitere Informationen hier.
Ist Mastering Elixir als Online-PDF/ePub verfügbar?
Ja, du hast Zugang zu Mastering Elixir von André Albuquerque, Daniel Caixinha im PDF- und/oder ePub-Format sowie zu anderen beliebten Büchern aus Computer Science & Programming in Ruby. Aus unserem Katalog stehen dir über 1 Million Bücher zur Verfügung.

Information

Jahr
2018
ISBN
9781788472241

Metaprogramming – Code That Writes Itself

We will now analyze how we can develop code that writes code for us, before being finally transformed into BEAM bytecode. This will let us extend Elixir, inject new code into existing modules, and even write a domain-specific language to simplify our media pipeline definitions.
What you will see through this chapter is only possible due to the incredible tools Elixir gives us to manipulate the abstract syntax tree just before it is turned into bytecode. Let's jump right into it!
In this chapter, we'll cover the following:
  • What is an abstract syntax tree and how to access it?
  • Using the special forms quote/2 and unquote/1
  • Macro hygiene and the caller and macro contexts
  • Applying use and its __using__/1 function
  • Using module attributes to collect information about the caller module
  • Creating a domain-specific language with macros

The abstract syntax tree

You may have already heard about Abstract Syntax Trees (ASTs) in other languages. As the name indicates, these are tree-like data structures that represent the code syntax. In Elixir, we call these representations quoted expressions.
If we try to obtain the quoted expression of simple expressions, such as single atoms, strings, integers or floats, lists or two element tuples, we'll see their quoted representation doesn't change when compared to their normal representation. These elements are called literals because we get the same value after quoting them. Take a look at the following code:
iex> quote do: :"Funky.Atom"
:"Funky.Atom"

iex> quote do: ["a", "b", "c", "z"]
["a", "b", "c", "z"]

iex> quote do: 1.88
1.88

iex> quote do: "really big string but still simple"
"really big string but still simple"

iex> {:elixir, :rocks} == quote do: {:elixir, :rocks}
true
The tree form of the quoted expressions is created by nesting three-element tuples and can be seen for complex snippets of code, which are composed by more than just Elixir literals:
iex> quoted_case = quote do
...> case 1 == 2 do
...> true -> "it seems 1 == 2 is true"
...> _ -> IO.puts "1 == 2 isn't true after all"
...> end
...> end
{:case, [],
[
{:==, [context: Elixir, import: Kernel], [1, 2]},
[
do: [
{:->, [], [[true], "it seems 1 == 2 is true"]},
{:->, [],
[
[{:_, [], Elixir}],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
["1 == 2 isn't true after all"]}
]}
]
]
]}
In the preceding example, we are obtaining the quoted representation of a case statement. Each three-element tuple is usually composed by an atom (or another three-element tuple) for the function name, a list with metadata, and an arguments list. If the tuple represents a variable, the last element of the tuple will instead be an atom.
To evaluate a quoted expression, we can use the Code.eval_quoted/3 function. If we evaluate the previous quoted_case representation, we will get a two-element tuple, with the evaluation result and the value of the passed bindings after evaluation (the :ok atom is the return value of calling IO.puts/1):
iex> Code.eval_quoted quoted_case
1 == 2 isn't true after all
{:ok, []}
Our quoted case expression didn't have any variables, so we weren't able to observe how bindings work. Let's now see what bindings are for with the following quoted expression using a variable x:
iex> quoted_case_with_vars = quote do
...> case x == 2 do
...> true -> "it seems x == 2"
...> _ -> IO.puts "x == 2 isn't true after all"
...> end
...> end
{:case, [],
[
{:==, [context: Elixir, import: Kernel], [{:x, [], Elixir}, 2]},
[
do: [
{:->, [], [[true], "it seems x == 2"]},
{:->, [],
[
[{:_, [], Elixir}],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
["x == 2 isn't true after all"]}
]}
]
]
]}
If you compare this quoted expression with the previous one, besides the minimal changes to the strings we're using, you can observe that the only change is, instead of having the 1 on the case equality comparison, we have the quoted representation of getting the value of x.
However, if we evaluate the quoted_case_with_vars expression with an explicit [x: 3] binding, it won't yield the expected result:
iex> Code.eval_quoted quoted_case_with_vars, [x: 3]
warning: variable "x" does not exist and is being expanded to "x()", please use parentheses to remove the ambiguity or change the variable name
nofile:1

** (CompileError) nofile:1: undefined function x/0
(stdlib) lists.erl:1354: :lists.mapfoldl/3
The behavior we're seeing here is deliberate, and the main reason for it is to spare ourselves from headaches further down the road; by default, these expressions are evaluated on a separate context and aren't able to access external variables (even if in this case we're passing x). If we want our expressions to access an outer value, like x, we have to wrap the x with a call to var!/1:
iex> quoted_case_with_external_vars = quote do
...> case var!(x) == 2 do
...> true -> "it seems x == 2"
...> _ -> IO.puts "x == 2 isn't true after all"
...> end
...> end
{:case, [],
[
{:==, [context: Elixir, import: Kernel],
[{:var!, [context: Elixir, import: Kernel], [{:x, [], Elixir}]}, 2]},
[
do: [
{:->, [], [[true], "it seems x == 2"]},
{:->, [],
[
[{:_, [], Elixir}],
{{:., [], [{:__aliases__, [alias: false], [:IO]}, :puts]}, [],
["x == 2 isn't true after all"]}
]}
]
]
]}
This way, our case expression finally has access to the bindings we set on the Code.eval_quoted/2 call:
iex> Code.eval_quoted quoted_case_with_external_vars, [x: 2]
{"it seems x == 2", [x: 2]}
The previous examples highlighted a very important aspect of metaprogramming in Elixir: the final quoted expressions generated by us, are only able to access variables outside their context if we explicitly said so through var!/1.
This inability to access the outer context by default is called macro hygiene and is the safeguard that keeps things separate, without leaking into the context of the caller. The decision of accessing (and possibly changing) the outer context should be fully considered by the developer, and this separation by default rule helps keeps things sane.
After lo...

Inhaltsverzeichnis