読者です 読者をやめる 読者になる 読者になる

もやもやエンジニア

IT系のネタで思ったことや技術系のネタを備忘録的に綴っていきます。フロント率高め。

Elixir 入門 その13 - Module attributes

  • ElixirのModuleのattributeは次の3つの目的をかなえる
    • ユーザーやVMによって使用されるためのモジュールの説明をつける
    • 定数として動く
    • コンパイルの間に使われるためテンポラリ領域として動く

As annotations

defmodule Math do
  # モジュールのバージョンを定義する属性
  @vsn 2

  # モジュールの説明を定義する属性
  @moduledoc """
  Provides math-related functions.

  ## Examples

      iex> Math.sum(1, 2)
      3

  """
  # ここまでモジュールの説明

  # 関数やMacroの説明
  @doc """
  Calculates the sum of two numbers.
  """
  def sum(a, b), do: a + b
end

As constants

  • attributeは定数としても使われ、必ず属性名と値を設定する
  • ランタイムに動いているのではなくコンパイル時に登録される(Module.register_attribute/3)
defmodule MyServer do
  @initial_state %{host: "147.0.0.1", port: 3456}
  IO.inspect @initial_state
end

As temporary storage

defmodule PlugSample do
  use Plug.Builder

  # plug/1 を呼ぶことで @plugs attributeに指定したplugが追加される
  # コンパイル前にcall/2が走ってhttp requestを受けたときに実行される処理として登録したplugを順番に実行するように作られる
  # なので例えば先に:send_ok を定義するとsend_respの後にheaderをセットしようとするので死ぬ
  plug :set_header
  plug :send_ok

  def set_header(conn, _opts) do
    IO.puts "ここがはじめにうごく"
    put_resp_header(conn, "x-header", "set")
  end

  def send_ok(conn, _opts) do
    IO.puts "ここがつぎにうごく"
    send_resp(conn, 200, "ok")
  end
end

IO.puts "Running PlugSample with Cowboy on http://localhost:4000"
Plug.Adapters.Cowboy.http PlugSample, []
> mix run --no-halt lib/plug_sample.ex
Running PlugSample with Cowboy on http://localhost:4000
# http://localhost:4000 で ok が返るようになる
  • 詳しいことはメタプロの章で