The Safe Navi­ga­tion Opera­tor (&.) in Ruby


The most inter­es­ting addi­tion to Ruby 2.3.0 is the Safe Navi­ga­tion Opera­tor(&.). A simi­lar opera­tor has been present in C# and Groovy for a long time with a slightly different syntax – ?.. So what does it do?

— Georgi Mitrev, via Pascal

Ruby ayant déjà la possi­bi­lité d’avoir des ? dans le nom des méthodes, il n’y avait pas de syntaxe super classe. Les discus­sions que j’avais vu tour­naient autour de a.?b mais ça deve­nait moche si la méthode termi­nait déjà par ? : a.?b?.

Au final nous aurons trois syntaxes :

a && a.b && a.b.c
a.try(:b).try(:c)
a&.b&.c

La première est ultra verbeuse et retour­nera false si a ou b retourne false. Sauf à ruser avec des variables tempo­raires, on finit par appe­ler a trois fois et b deux fois.

La seconde méthode est plus sympa, mais longue assez moche à la lecture. Elle est aussi ultra tolé­rante et n’échouera pas même si rien ne retourne nil ou false mais que les méthodes b ou c n’existent pas.

La dernière née est donc plus stricte. Elle ne sert que si a ou b retournent nil, et dans aucun autre cas. Restera à s’ha­bi­tuer à la syntaxe.

Atten­tion, nil&.nil? retourne nil. L’opé­ra­teur & a donc la prio­rité sur ce qui suit. C’est logique, mais c’est un coup à se plan­ter si on en fait pas atten­tion.

Sinon, spéci­fique­ment pour les Hash, même logique avec la méthode dig, là aussi bien­ve­nue :

a[:b] && a[:b][:c] && a[:b][:c][:d]
a[:b].try(:[], :c).try(:[], :d)
a.fetch(:b, []).fetch(:c, []).fetch(:d, nil)
a.fetch(:b, nil)&.fetch(:c, nil)&.fetch(:d, nil)
a.dig(:b, :c, :d)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.