Digging & Safe navigation
Objectif : éviter du code de contrôle pour récupérer des données sur recherche, map/reduce, nesting
Digging
Recherche dans un nested Hash qui potentiellement peut ne pas être défini.
Version non robuste
$mydata = {:config => { :environments => { :developement => {:key => "value"}, :production => {:key => "value"}}}}
p $mydata
def get_config(data: $mydata,environment: :developement)
return data[:config][:environments][environment][:key]
rescue Exception => e
puts e.message
end
p get_config
p get_config environment: :staging
Remarque : On constate qu'un méthode est comparable à un bloc en certain aspect et donc pas besoin de faire unbegin
/end
pourrescue
l'exception
Voir : Bonnes pratiques
Sortie :
{:config=>{:environments=>{:developement=>{:key=>"value"}, :production=>{:key=>"value"}}}}
"value"
undefined method `[]' for nil:NilClass
nil
Quand l’environnement est défini tout va bien, mais sinon on lève une exception car on utilise une méthode d'un Array
sur un Objet NilClass
Version "Ugly"
def ugly_get_config(data: $mydata,environment: :developement)
if data[:config][:environments].include? environment
return data[:config][:environments][environment][:key]
end
end
p ugly_get_config
p ugly_get_config environment: :staging
Sortie :
"value"
nil
Limite: si en plus le champs key n'est pas présent dans la définition d'un environement une lève encore une exception
Version "Safe"
On utilise #dig
, qui propose un parcours deep nesting du hashage et renvoi nil
si il ne trouve pas de path
def get_safe_config(data: $mydata, environment: :developement)
return data[:config][:environments].dig(environment, :key)
end
p get_safe_config
p get_safe_config environment: :staging
Safe Navigation
Version non robuste
Soit une recherche sur Array
$list_names = ["romain","pierre","camille"]
def get_pattern(data: $list_names, pattern: /.*/)
return data.select {|item| item =~ pattern}.first.capitalize
end
p get_pattern
begin
p get_pattern pattern: /hass/
rescue Exception => e
puts e.message
end
Sortie :
"Romain"
undefined method `capitalize' for nil:NilClass
first
peut renvoyer un tableau vide, donc first
peu renvoyer un object nil
.
=> la méthode capitalize
n'existe pas sur NilClass
.
Version "Ugly"
def ugly_get_pattern(data: $list_names, pattern: /.*/) res = data.select {|item| item =~ pattern}
return res.first.capitalize unless res.empty?
end
p ugly_get_pattern pattern: /hass/
p ugly_get_pattern
Sortie :
nil
Romain
Version "Safe"
def pretty_get_pattern(data: $list_names, pattern: /.*/) return data.select {|item| item =~ pattern}.first&.capitalize
end
p pretty_get_pattern pattern: /hass/
p pretty_get_pattern
Remarque : on utilise &.
qui permet la safe navigation
Sortie :
nil
Romain