Oi, pessoal!
Recentemente fiz um vídeo sobre Pipes em Elixir. Como sei que nem todos gostam de ver vídeos (eu estou entre estas pessoas), vou escrever um pouco sobre o que falei lá.
Em primeiro lugar, preciso falar da Falácia do Espantalho. Um site muito bom sobre falácias lógicas é https://yourlogicalfallacyis.com/. Lá você encontra um texto sobre a falácia do espantalho que diz:
Por que eu disse isso? Porque quando você entra na página da Elixir School (que eu adoro) sobre o Operador Pipe está escrito "chamadas em funções podem ficar tão incorporadas a outras chamadas de função, tornando-se muito difícil de seguir" e aí eles dão o seguinte exemplo:
foo(bar(baz(new_function(other_function()))))
Bem, mesmo sem pipe dá pra deixar o código acima bem mais legível. Como? Assim:
valor = other_function()
nome_significativo_1 = new_function(valor)
nome_significativo_2 = baz(nome_significativo_1)
nome_significativo_3 = bar(nome_significativo_2)
foo(nome_significativo_3)
Ou seja, o código acima talvez fique, dependendo da escolha dos "nomes significativos" das variáveis, até mais legível do que o exemplo com pipe utilizado na Elixir School:
other_function() |> new_function() |> baz() |> bar() |> foo()
Ou seja, eu acho que o pessoal da Elixir School usou um pouco da falácia do espantalho para justificar o pipe.
Eu já sou meio chato em usar os pipes tudo numa mesma linha. OK, sei que no iex não tem muita escolha exceto fazer isto (colocar o pipe no fim da linha e pular para a próxima linha):
iex> "Elixir rocks" |>
String.upcase() |>
String.split()
Mas não vou escrever sobre o que não gosto e sim sobre o que gosto.
A tradução literal de pipe é cano e usando o operador pipe.
Na figura abaixo você pode ver como os dados fluem de uma função a outra através dos canos (pipes).
Neste exemplo eu mostrei como você pode usar IO.inspect para ver o que acontece após cada ação do pipe.
Enum.take(1..100, 10)
|> IO.inspect(label: "inicial")
|> Enum.map(fn x -> x * 2 end)
|> IO.inspect(label: "Após map")
|> Enum.filter(fn x -> x > 4 end)
|> IO.inspect(label: "Após filter")
|> Enum.sum()
|> IO.inspect(label: "Após sum")
Portanto, minha sugestão é: use o pipe sempre que possível em Elixir. Na minha opinião (é somente uma opinião, claro), o pipe deixa o código mais legível!
Cover Photo by Kyle Glenn on Unsplash.
Top comments (2)
Os "nomes significativos" nunca devem sumir, a diferença é que antes a gente colocava variáveis com esses nomes, agora a gente coloca funções (:
O pipe é um dos melhores recursos na minha opinião, é fantástico você conseguir encadear as chamadas de uma forma que elas fiquem mais legíveis!