You need to note that sometime you need to edit the code *before* running the ecto.migrate command that prompts you in the console.
The new structure of a Phoenix app is much cleaner. Keeping the domain and the site in the same project helps. The scaffolding is amazing.
For those that don’t know, Phoenix is Elixir’s answer to Ruby On Rails.
That means that it is both an MVC Framework and an associated set of code generators that allow scaffolding of the site. It defaults to using Postgres as a database, but given that the data access uses the wonderful Ecto framework you get migrations and a data access layer.
This is a very odd resemblance, but the feel of adding a form to Liveview resembles the simplicity of good old Delphi. You get a single place where you can define the layout and the actions (achieving high coherence) without the concerns getting in each others way.
The Elixir iex shell is a very powerful tool in itself.
I have recently found a trick that makes it much easier to use. If you get stuck in a line that you just can’t complete just type :break + return and it will cancel that line.
This is an investigation of what you get out of the box.
Lets start with the processes that exist in an empty iex session:
That means that there are 33 named processes started with iex and 23 anonymous ones.
Here are the named ones:
Elixir.IEx.Broker - GenServer, communicates with other components.
Elixir.IEx.Config - Agent, handles .iex.config file
Elixir.IEx.Pry - GenServer, Handles Pry debugging
Elixir.IEx.Supervisor - Supervisor for the above three Services.
Elixir.Logger, Service for logging, works with logger.
Elixir.Logger.BackendSupervisor, Supervises the backend for the logger
Elixir.Logger.Supervisor - Supervisor for the logger components
application_controller - GenServer, handles loaded applications
code_server - Erlang code server
elixir_code_server - GenServer that manages loaded code in ets
elixir_config - GenServer that stores config in ets
elixir_sup - Supervisor for the above two GenServers
erl_prim_loader
erl_signal_server
erts_code_purger
file_server_2
global_group
global_name_server
inet_db
init
kernel_refc
kernel_safe_sup
kernel_sup
logger - Erlang logger service, used by Elixir.Logger
logger_handler_watcher
logger_proxy
logger_sup
rex
socket_registry
standard_error
standard_error_sup
user
user_drv
We have the following applications loaded:
iex > :application_controller.loaded_applications
[
{:logger, 'logger', '1.10.4'},
{:iex, 'iex', '1.10.4'},
{:compiler, 'ERTS CXC 138 10', '7.6.2'},
{:elixir, 'elixir', '1.10.4'},
{:stdlib, 'ERTS CXC 138 10', '3.13'},
{:kernel, 'ERTS CXC 138 10', '7.0'}
]
You can find out more using :observer.start
This is the Elixir Application TreeHere is the IEx Application TreeThis is the Elixir Logger Supervisor treeHere is the Erlang Kernel supervisor tree
This week I am giving a training session in Elixir internally at my employer. It will be interesting to see how people will react to an introduction to Elixir as a general purpose language. I am going to defer explaining OTP and processes to a later session.
This is a refactoring exercise, starting with this:
defmodule FooBar do
def foo(a) do
if a < 0 do
bar(a, -1)
else
bar(a, 1)
end
end
defp bar(a, b) do
IO.inspect(a * b)
end
end
Transform it into canonical Elixir.
The article linked to moves heavily into pipelines but there are alternatives, here this notes that if is an expression:
defmodule FooBar do
def foo(a) do
bar(a, (if a < 0, do: -1, else: 1))
end
defp bar(a, b) do
IO.inspect(a * b)
end
end
Also bar is symmetrical:
defmodule FooBar do
def foo(a) do
if a < 0, do: -1, else: 1 |> bar(a)
end
defp bar(a, b) do
IO.inspect(a * b)
end
end
Pattern matching and guards is also typical Elixir, more so than an if:
defmodule FooBar do
def foo(a) do
a
|> calculate()
|> bar(a)
end
defp calculate(a) when a < 0, do: -1
defp calculate(a), do: 1
defp bar(a, b) do
IO.inspect(a * b)
end
end
Only one role out of the basic game to implement before I start on a UI. The domain model is still working despite the essential complexity of the domain.
The operations expert has an ability that can only be used once per turn. This required recording introducing a concept of setting up a player for the start of their turn.
The only complex item that I am concerned about are the actions that can be played at any time. This may mean that some of the automated actions may need to be slowed down (airlift during infect cities?)