動かざることバグの如し

近づきたいよ 君の理想に

Elixirで関数呼び出し時にドットを付ける/付けないの違い

環境

  • Elixir 1.x

結論

  • 無名関数の場合はドット(.)が必要
  • 名前付き関数の場合は不要

違いについて

他の言語やったあとにElixirやってると以下のようなエラーをよく起こす。

iex(1)> add = fn a, b -> a + b end
#Function<12.99386804/2 in :erl_eval.expr/5>
iex(2)> add(1, 2) 
** (CompileError) iex:2: undefined function add/2

実際には以下が正しい。

iex(2)> add.(1, 2)                
3

つまり関数呼び出し時にドットが抜けてたのだが、ドットを付けない場合もある。どういう違いがあるのか気になった。

利害は結構単純で、fnからendのキーワードを使って定義された関数は無名関数と呼ばれ、名前の通り関数名がない。

一方、defからendのキーワードで定義された関数は普通?の関数、名前付き関数になり、名前付き関数を呼び出す場合はドットを付けない。

defmodule Mymodule do
  def add(a, b) do
    a + b
  end
end

IO.puts Mymodule.add(1, 2)

逆にドットを付けて実行するとエラーになる。気をつけよう

Mymodule.add.(1, 2)

** (UndefinedFunctionError) function Mymodule.add/0 is undefined or private. Did you mean one of:

      * add/2

    Mymodule.add()
    hoge.exs:28: (file)
    (elixir) lib/code.ex:677: Code.require_file/2