Des pipes Elixir-like en Ruby
Si vous utilisez le langage elixir (et le framework Phoenix), vous avez déjà dû vous émerveiller plus d’une fois sur la beauté et la puissance des pipelines |>. Par exemple :
"String"
|> ajoute("est un type courant")
|> IO.puts
# => "String est un type courant"
En ruby, on peut obtenir le même mécanisme à l’aide de la méthode yield_self :
"String"
.then {|s| s.concat("est un type courant") }
.then {|s| puts s }
Soit. Sauf que ce que je trouve beau dans Elixir, c’est qu’on n’a pas besoin de passer la valeur précédente de façon explicite… Le put tout seul sait qu’il doit prendre en premier paramètre le résultat de ce qui précède.
Je voudrais obtenir le même comportement en ruby.
Ou au moins supprimer l’usage redondant de |sujet|.
⚠️ 💣💀😱 Pour ce faire, je vais sacrifier l’opérateur Kernel |et l’utiliser à mes fins.
module Kernel
def |(&block)
instance_eval(&block)
end
end
Et maintenant, j’obtiens presque la même magie, il me suffit d’utiliser le terme self pour désigner le résultat précédent :
"Mon string"
.| { "#{self} est une valeur de type String" }
.| { puts self }
Ne pas sacrifier l’opérateur |
Pour ne pas sacrifier l’opérateur |, nous allons utiliser le “refining” :
# Dans un fichier 'pipeline.rb'
module Pipeline
refine Kernel do
def |(&block)
instance_eval(&block)
end
end
end
Et maintenant, pour pouvoir utiliser cette facilité, on fait :
require 'pipeline'
using Pipeline
"Mon string"
.| { "#{self} est une valeur de type String" }
.| { puts self }