Quando falamos de pattern matching em Elixir a ordem importa!

Rode o iex e crie o módulo a seguir:

defmodule MyModule do
    def print(text), do: IO.puts "text"
    def print(:my_atom_text), do: IO.puts "my_atom_text"
end

Agora execute a função print passando o atom para garantir o matching na segunda função:

iex(2) > MyModule.print(:my_atom_text)
text
:ok

Isso pode parecer inesperado porque o resultado é text e não my_atom_text. Isso ocorre porque o matching acontece com a primeira função do módulo que é genérica. O mecanismo de matching procura a função mais próxima e quando ele acha será ela mesma a executada.

Para ter o comportamento esperado, redeclare o módulo com as funções mais específicas primeiro. Veja:

defmodule MyModule do
    def print(:my_atom_text), do: IO.puts "my_atom_text"
    def print(text), do: IO.puts "text"    
end

Agora execute a função print novamente. O resutado será outro.

iex(2) > MyModule.print(:my_atom_text)
my_atom_text
:ok

Aprendi isso com um bug dentro de uma aplicação em um cenário bem complicado de enxergar a ordem das coisas. Então lembre-se: a ordem importa quando estamos falando de pattern matching em Elixir.