Elixirの対話モードで関数の動作を確認してみた

# 概要
Elixirの対話モードで関数の動作を確認してみました。以下のページを参考にしました。

https://elixirschool.com/ja/lessons/basics/functions

# 対話モードで実行
```
$ iex
Erlang/OTP 24 [erts-12.2.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit]

Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> sum = fn (a, b) -> a + b end
#Function<43.65746770/2 in :erl_eval.expr/5>
iex(2)> sum.(2, 3)
5
iex(3)> sum = &(&1 + &2)
&:erlang.+/2
iex(4)> sum.(2, 3)
5
iex(5)> handle_result = fn
...(5)> {:ok, result} -> IO.puts "Handling result..."
...(5)> {:ok, _} -> IO.puts "This would be never run as previous will be matched beforehand."
...(5)> {:error} -> IO.puts "An error has occurred!"
...(5)> end
warning: variable "result" is unused (if the variable is not meant to be used, prefix it with an underscore)
  iex:6

#Function<44.65746770/1 in :erl_eval.expr/5>
iex(6)> some_result = 1
1
iex(7)> handle_result.({:ok, some_result})
Handling result...
:ok
iex(8)> handle_result.({:error})
An error has occurred!
:ok
iex(9)> defmodule Greeter do
...(9)> def hello(name) do
...(9)> "Hello, " <> name
...(9)> end
...(9)> end
{:module, Greeter,
 <<70, 79, 82, 49, 0, 0, 5, 80, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 153,
   0, 0, 0, 16, 14, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:hello, 1}}
iex(10)> Greeter.hello("Sean")
"Hello, Sean"
iex(11)> defmodule Greeter do
...(11)> def hello(name), do: "Hello, " <> name
...(11)> end
warning: redefining module Greeter (current version defined in memory)
  iex:11

{:module, Greeter,
 <<70, 79, 82, 49, 0, 0, 5, 76, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 153,
   0, 0, 0, 16, 14, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:hello, 1}}
iex(12)> defmodule Length do
...(12)> def of([]), do: 0
...(12)> def of([_ | tail]), do: 1 + of(tail)
...(12)> end
{:module, Length,
 <<70, 79, 82, 49, 0, 0, 5, 0, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 137, 0,
   0, 0, 15, 13, 69, 108, 105, 120, 105, 114, 46, 76, 101, 110, 103, 116, 104,
   8, 95, 95, 105, 110, 102, 111, 95, 95, ...>>, {:of, 1}}
iex(13)> Length.of []
0
iex(14)> Length.of [1, 2, 3]
3
iex(15)> defmodule Greeter2 do
...(15)> def hello(), do: "Hello, anonymous person!"
...(15)> def hello(name), do: "Hello, " <> name
...(15)> def hello(name1, name2), do: "Hello, #{name1} and #{name2}"
...(15)> end
{:module, Greeter2,
 <<70, 79, 82, 49, 0, 0, 7, 92, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 184,
   0, 0, 0, 18, 15, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 50, 8, 95, 95, 105, 110, 102, 111, ...>>, {:hello, 2}}
iex(16)> Greeter2.hello()
"Hello, anonymous person!"
iex(17)> Greeter2.hello("Fred")
"Hello, Fred"
iex(18)> Greeter2.hello("Fred", "Jane")
"Hello, Fred and Jane"
iex(19)> defmodule Greeter1 do
...(19)> def hello(%{name: person_name}) do
...(19)> IO.puts "Hello, " <> person_name
...(19)> end
...(19)> end
{:module, Greeter1,
 <<70, 79, 82, 49, 0, 0, 5, 172, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 174,
   0, 0, 0, 19, 15, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 49, 8, 95, 95, 105, 110, 102, 111, ...>>, {:hello, 1}}
iex(20)> fred = %{
...(20)> name: "Fred",
...(20)> age: "95",
...(20)> favorite_color: "Taupe"
...(20)> }
%{age: "95", favorite_color: "Taupe", name: "Fred"}
iex(21)> Greeter1.hello(fred)
Hello, Fred
:ok
iex(22)> Greeter1.hello(%{age: "95", favorite_color: "Taupe"})
** (FunctionClauseError) no function clause matching in Greeter1.hello/1    
    
    The following arguments were given to Greeter1.hello/1:
    
        # 1
        %{age: "95", favorite_color: "Taupe"}
    
    iex:20: Greeter1.hello/1
iex(22)> defmodule Greeter2 do
...(22)> def hello(%{name: person_name} = person) do
...(22)> IO.puts "Hello, " <> person_name
...(22)> IO.inspect person
...(22)> end
...(22)> end
warning: redefining module Greeter2 (current version defined in memory)
  iex:22

{:module, Greeter2,
 <<70, 79, 82, 49, 0, 0, 6, 0, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 182, 0,
   0, 0, 20, 15, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116, 101,
   114, 50, 8, 95, 95, 105, 110, 102, 111, ...>>, {:hello, 1}}
iex(23)> Greeter2.hello(fred)
Hello, Fred
%{age: "95", favorite_color: "Taupe", name: "Fred"}
%{age: "95", favorite_color: "Taupe", name: "Fred"}
iex(24)> Greeter2.hello(%{name: "Fred"})
Hello, Fred
%{name: "Fred"}
%{name: "Fred"} 
iex(25)> Greeter2.hello(%{age: "95", favorite_color: "Taupe"})
** (FunctionClauseError) no function clause matching in Greeter2.hello/1    
    
    The following arguments were given to Greeter2.hello/1:
    
        # 1
        %{age: "95", favorite_color: "Taupe"}
    
    iex:23: Greeter2.hello/1
iex(25)> defmodule Greeter3 do
...(25)> def hello(person = %{name: person_name}) do
...(25)> IO.puts "Hello, " <> person_name
...(25)> IO.inspect person
...(25)> end
...(25)> end
{:module, Greeter3,
 <<70, 79, 82, 49, 0, 0, 6, 0, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 182, 0,
   0, 0, 20, 15, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116, 101,
   114, 51, 8, 95, 95, 105, 110, 102, 111, ...>>, {:hello, 1}}
iex(26)> Greeter3.hello(fred)
Hello, Fred
%{age: "95", favorite_color: "Taupe", name: "Fred"}
%{age: "95", favorite_color: "Taupe", name: "Fred"}
iex(27)> defmodule Greeter do
...(27)> def hello(name), do: phrase() <> name
...(27)> defp phrase, do: "Hello, "
...(27)> end
warning: redefining module Greeter (current version defined in memory)
  iex:27

{:module, Greeter,
 <<70, 79, 82, 49, 0, 0, 5, 112, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 159,
   0, 0, 0, 17, 14, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:phrase, 0}}
iex(28)> Greeter.hello("Sean")
"Hello, Sean"
iex(29)> Greeter.phrase
** (UndefinedFunctionError) function Greeter.phrase/0 is undefined or private
    Greeter.phrase()
iex(29)> defmodule Greeter do
...(29)> def hello(names) when is_list(names) do
...(29)> names = Enum.join(names, ", ")
...(29)> hello(names)
...(29)> end
...(29)> def hello(name) when is_binary(name) do
...(29)> phrase() <> name
...(29)> end
...(29)> defp phrase, do: "Hello, "
...(29)> end
warning: redefining module Greeter (current version defined in memory)
  iex:29

{:module, Greeter,
 <<70, 79, 82, 49, 0, 0, 6, 52, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 176,
   0, 0, 0, 19, 14, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:phrase, 0}}
iex(30)> Greeter.hello ["Sean", "Steve"]
"Hello, Sean, Steve"
iex(31)> defmodule Greeter do
...(31)> def hello(name, language_code \\ "en") do
...(31)> phrase(language_code) <> name
...(31)> end
...(31)> defp phrase("en"), do: "Hello, "
...(31)> defp phrase("es"), do: "Hola, "
...(31)> end
warning: redefining module Greeter (current version defined in memory)
  iex:31

{:module, Greeter,
 <<70, 79, 82, 49, 0, 0, 6, 176, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 159,
   0, 0, 0, 17, 14, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:phrase, 1}}
iex(32)> Greeter.hello("Sean", "en")
"Hello, Sean"
iex(33)> Greeter.hello("Sean")      
"Hello, Sean"
iex(34)> Greeter.hello("Sean", "es")
"Hola, Sean"
iex(35)> defmodule Greeter do
...(35)> def hello(names, language_code \\ "en") when is_list(names) do
...(35)> names = Enum.join(names, ", ")
...(35)> hello(names, language_code)
...(35)> end
...(35)> def hello(name, language_code \\ "en") when is_binary(name) do
...(35)> phrase(language_code) <> name
...(35)> end
...(35)> defp phrase("en"), do: "Hello, "
...(35)> defp phrase("es"), do: "Hola, "
...(35)> end
warning: redefining module Greeter (current version defined in memory)
  iex:35

** (CompileError) iex:40: def hello/2 defines defaults multiple times. Elixir allows defaults to be declared once per definition. Instead of:

    def foo(:first_clause, b \\ :default) do ... end
    def foo(:second_clause, b \\ :default) do ... end

one should write:

    def foo(a, b \\ :default)
    def foo(:first_clause, b) do ... end
    def foo(:second_clause, b) do ... end

    iex:40: (module)
iex(35)> defmodule Greeter do
...(35)> def hello(names, language_code \\ "en")
...(35)> def hello(names, language_code) when is_list(names) do
...(35)> names = Enum.join(names, ", ")
...(35)> hello(names, language_code)
...(35)> end
...(35)> def hello(name, language_code) when is_binary(name) do
...(35)> phrase(language_code) <> name
...(35)> end
...(35)> defp phrase("en"), do: "Hello, "
...(35)> defp phrase("es"), do: "Hola, "
...(35)> end
warning: redefining module Greeter (current version defined in memory)
  iex:35

{:module, Greeter,
 <<70, 79, 82, 49, 0, 0, 7, 128, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 176,
   0, 0, 0, 19, 14, 69, 108, 105, 120, 105, 114, 46, 71, 114, 101, 101, 116,
   101, 114, 8, 95, 95, 105, 110, 102, 111, 95, ...>>, {:phrase, 1}}
iex(36)> Greeter.hello ["Sean", "Steve"]
"Hello, Sean, Steve"
iex(37)> Greeter.hello ["Sean", "Steve"], "es"
"Hola, Sean, Steve"
iex(38)>
```

# まとめ
何かの役に立てばと。