Tout d'abord, vous devez savoir si ce code viole le Law of Demeter. Si tel est le cas, la solution correcte à ce problème est pas écrire le code de cette façon.
Comment pourriez-vous savoir si c'est la rupture? Here est un article qui tente d'expliquer comment cela s'applique au langage Ruby.
Dans votre cas, vous le diviseriez en plusieurs appels, avec des clauses de garde autour. Dans l'appel one.two.three.four
, nous pouvons supposer que four
est une propriété de three
(plutôt, l'objet retourné par three
). Et three
serait une propriété de two
. Donc, vous devez ajouter une méthode dans two
:
# Note: This is an over-simplified example
def three_four
return unless three
three.four
end
Et one
vous auriez:
def two_three_four
return unless two
two.three_four
end
Un exemple plus pertinent:
invoice.customer.primary_address.zipcode
Alors vous auriez Customer#primary_address_zipcode
et Invoice#customer_primary_address_zip_code
(Ou un meilleur nom abrégé, cela aurait plus de sens)
Comment écrire ceci: a = one.two.three (param) [: c] – Jonas
-1. Je dirais que «essayer», lorsqu'il est utilisé dans une chaîne de méthode comme celle-ci, est une odeur de code. Bien que ce soit * une * solution * pour appeler en toute sécurité les méthodes *, l'idée d'appeler en toute sécurité des méthodes enchaînées comme OP a publié n'est pas juste, IMO. – Swanand
N'essayez pas une méthode de rails? –