Dans ce tuto nous allons apprendre à utiliser un proc.
Dans une vidéo Youtube
data = [{email: 'toto@gmail.com'}, {email: 'titi@gmail.com'}]
User = Struct.new(:email, keyword_init: true)
class UserBuilder
def initialize(data)
@data = data
end
def build
User.new(@data)
end
def self.to_proc
Proc.new {|data| new(data).build }
end
end
Il existe deux manières de créer des nouveaux utilisateurs qui sont similaires en termes de résultats.
data.map { |user_data| UserBuilder.new(user_data).build }
# [#<struct User email="toto@gmail.com">, #<struct User email="titi@gmail.com">]
data.map(&UserBuilder)
# [#<struct User email="toto@gmail.com">, #<struct User email="titi@gmail.com">]
Dans la seconde façon nous avons utilisé un proc appelé avec un esperluette.
data.map(&Builders::User)
Tout d’abord il faut savoir qu’un esperluette qui est passé en argument d’un énumérator va appeler par défaut la méthode to_proc
sur l’argument. Dans notre cas le Builders::User
.
Ensuite la méthode to_proc va retourner un proc qui est un block de code.
Un proc est une instance de la classe Proc
. C’est un objet qui peut être lié à une variable et réutilisé. Il se définit en appelant Proc.new ou proc suivi d’un block. Un proc va pouvoir récupérer des arguments pour les traiter.
Dans notre exemple il récupère le Hash avec les data des users pour ensuite instancier le builder et appeler la méthode build.
Pour aller plus loin sur les procs, il y’a cet excellent article toujours de RubyCademy.
Un proc peut aussi aider à rendre plus lisible un case
(switch statement) comme dans l’exemple ci-dessous.
def is_even
Proc.new {|x| x % 2 == 0 }
end
def is_odd
Proc.new {|x| x % 2 == 1 }
end
number = 4
case number
when is_even
puts "#{number} is even"
when is_odd
puts "#{number} is odd"
end
Une exemple de RubyCademy nous permet une utilation encore plus avancé des procs inspiré de la programmation fonctionnelle.
strip = proc { |email| email.strip }
downcase = proc { |email| email.downcase }
remove_alias = proc { |email| email.gsub(/\+.*@/, '@') }
email = " Test+alias@example.com "
(strip >> downcase >> remove_alias).call(email)
Publié le 01/10/2024