Basics

 

  • Mix
  • Hex
  • IEx
  • ExUnit
  • ExDoc
  • Immutable data and variable rebinding
  • Processes
  • Dogmatic
  • Influenced by ruby
$ elixir -v
Erlang/OTP 20 [erts-9.0] [source] [64-bit] ...
Elixir 1.4.5

Elixir Phoenix

[info] Sent 200 in 43ms
[info] Sent 200 in 178µs

Ruby on Rails

Completed 200 OK in 199ms
Completed 200 OK in 9ms

Mix

  • mix.exs like Gemfile / Rakefile
  • https://hex.pm
  • https://hexdocs.pm
  • mix deps.get
  • mix test
  • mix hex.publish
  • mix compile
  • rebar3

 

defmodule Plug.Mixfile do
  use Mix.Project

  @version "1.4.0-dev"

  def project do
    [app: :plug,
     version: @version,
     elixir: "~> 1.3",
     deps: deps(),
     package: package(),
     description: "A specification and conveniences for composable " <>
                  "modules between web applications",
     name: "Plug",
     xref: [exclude: [:ranch, :cowboy, :cowboy_req, :cowboy_router]],
     docs: [extras: ["README.md"], main: "readme",
            source_ref: "v#{@version}",
            source_url: "https://github.com/elixir-lang/plug"]]
  end

  # Configuration for the OTP application
  def application do
    [applications: [:crypto, :logger, :mime],
     mod: {Plug, []},
     env: [validate_header_keys_during_test: true]]
  end

  def deps do
    [{:mime, "~> 1.0"},
     {:cowboy, "~> 1.0.1 or ~> 1.1", optional: true},
     {:ex_doc, "~> 0.15", only: :docs},
     {:hackney, "~> 1.2.0", only: :test}]
  end

  defp package do
    %{licenses: ["Apache 2"],
      maintainers: ["José Valim"],
      links: %{"GitHub" => "https://github.com/elixir-lang/plug"}}
  end
end

IEx

iex(10)> h Enum.map

                            def map(enumerable, fun)

Returns a list where each item is the result of invoking fun on each
corresponding item of enumerable.

For maps, the function expects a key-value tuple.

## Examples

    iex> Enum.map([1, 2, 3], fn(x) -> x * 2 end)
    [2, 4, 6]

    iex> Enum.map([a: 1, b: 2], fn({k, v}) -> {k, -v} end)
    [a: -1, b: -2]

* access documentation
iex(6)> i :atom
Term
  :atom
Data type
  Atom
Reference modules
  Atom
Implemented protocols
  IEx.Info, Inspect, List.Chars, String.Chars

Help, Info and IEx.pry

ExUnit

defmodule MyApp.MyController do
  @twitter_api Application.get_env(:my_app, :twitter_api)

  def show(conn, %{"username" => username}) do
    @twitter_api.get_username(username) #...
  end
end

# In config/test.exs
config :my_app, :twitter_api, MyApp.Twitter.InMemory
# In config/prod.exs
config :my_app, :twitter_api, MyApp.Twitter.HTTPClient

defmodule MyApp.MyControllerTest do
  use MyApp.ConnCase

  setup do
    {:ok, username: "josevalim"}
  end

  describe "GET /twitter", context do
    test "returns the user's twitter handle" do
      conn = get(context[:conn], "/twitter")
      result = Poison.Parser.parse!(conn.resp_body)

      assert result["username"] == context[:username]
    end
  end
end

Elixir Processes

for num <- 1..100000, do: spawn fn -> num * 2 end;System.halt
# 1.2 seconds

Elixir Processes

defmodule Example do
  def listen do
    receive do
      {:ok, "hello"} -> IO.puts "World"
    end

    listen
  end
end

iex> pid = spawn(Example, :listen, [])
#PID<0.108.0>

iex> send pid, {:ok, "hello"}
World
{:ok, "hello"}

iex> send pid, :ok
:ok

Erlang Interop

# mix.exs
defmodule Test.Mixfile do
  use Mix.Project

  # included for inclusion in release
  def application do
    [mod: {Test, []},
     applications: [:phoenix, :phoenix_html, :cowboy, :logger,
                    :gettext, :phoenix_ecto, :phoenix_pubsub,
                    :mariaex, :httpoison, :eldap]]
  end
end


# elsewhere, charlist instead of string
:eldap.open('kissmetrics.com', [{:port, 389}, {:ssl, false}])

Deployment

  • https://github.com/bitwalker/distillery
  • https://github.com/bitwalker/conform
  • include ERTS
  • hot upgrades
#!/bin/sh
set -e

MIX_ENV=prod mix do deps.get, compile

# refresh release config
rm -f config/app.conf
# generate sys.config for erlang
# and conf file
MIX_ENV=prod mix conform.configure

# compile assets
npm install
npm run compile

# run digest *after* npm compiles
MIX_ENV=prod mix phoenix.digest

# matching architecture
MIX_ENV=prod mix release
Made with Slides.com