Thanks! Now it looks great, succinct and very maintainable, as there is no need to keep the atoms synced between message_types
and the functions.
Here’s the final code with the correct syntax, using Kernel.apply/3
as suggested by @Qqwy
defmodule Test do
@message_types [
{~r/hi/, :fn_hi},
{~r/bye/, :fn_bye}
]
def reply(msg) do
{_, func} = Enum.find(@message_types,
{nil, :fn_unknown},
fn {reg, _} -> String.match?(msg, reg) end
)
Kernel.apply(Test, func, [msg])
end
def fn_hi(msg), do: "Hello! you said " <> msg
def fn_bye(msg), do: "Bye! you said " <> msg
def fn_unknown(msg), do: "I didn't understand you. You said: " <> msg
end
To test it:
$ iex -r test.ex
Erlang/OTP 18 [erts-7.3] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Interactive Elixir (1.2.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Test.reply("hi")
"Hello! you said hi"
iex(2)> Test.reply("ok bye!")
"Bye! you said ok bye!"
iex(3)> Test.reply("other")
"I didn't understand you. You said: other"