2016-03-10 11 views
18

In Rails können Sie hash.try(:[], :key) tun, die hilft, wenn hash möglicherweise nil ist. Gibt es eine gleichwertige Version für die Verwendung des neuen sicheren Navigationsoperators Ruby 2.3 &. mit []?Sichere Navigation entspricht Rails versuchen für Hashes

+0

Mögliche Duplikat [Rubin - Zugriff auf multidimensionale Hash und vermeiden Zugang nil Objekt] (https://stackoverflow.com/questions/10130726/ruby-access-multidimensionales-hash-and-avoid-access-nil-objekt) – kolen

Antwort

22

&. nicht gleichwertig Rails' ist try zurückkehren würde, aber Sie können &. für Hashes verwenden. Benutze es einfach, nichts besonderes.

hash[:key1]&.[](:key2)&.[](:key3) 

Obwohl ich das nicht tun würde.

+2

Guter Punkt, wenn '& .' und' try' anders sind. Ich dachte nur, dass 'hash'' nil' ist. Was ich am Ende benutzt habe, war 'hash &. [] (: Key)' –

+0

Dies funktioniert nur für Ruby 2.3+? – bbozo

+0

@bbozo Ja. '& .' wurde in Ruby 2.3 eingeführt. – sawa

2

akzeptierte Antwort nicht wird berücksichtigen, wenn hash Null ist ...

Sie können neu schreiben, was Sie vor dem .try den sicheren nav Betreiber haben verwenden und dass

hash&.try(:[], :key)

aber Sie arbeiten kann auch verwendet werden:

http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig

A w ay Sie können dies auch auf einen Hash ist, indem Sie ...

hash&.dig(:key1, :key2 ...) 

die Null zurück, wenn eine beliebige Taste, holen nicht vorhanden ist.

{ key1: { key2: 'info' } } 

zurückkehren würde 'info'

{ key1: { wrong_key: 'info' } } 

nil

20

Pre Rubin 2.3

Ich hatte in der Regel so etwas wie dieser Put in meine intializer:

Class Hash 
    def deep_fetch *args 
     x = self 
     args.each do |arg| 
     x = x[arg] 
     return nil if x.nil? 
     end 
     x 
    end 
end 

und dann

response.deep_fetch 'PaReqCreationResponse', 'ThreeDSecureVERes', 'Message', 'VERes', 'CH', 'enrolled' 

in einem verrückten Fall.

Der allgemeine Konsens in der Gemeinschaft scheint &.

Rubin 2.3 und später

Es gibt Hash#dig Methode das bedeutet, dass gerade jetzt zu vermeiden, beide versuchen, und der einsame Betreiber zu sein:

Ermittelt das Wertobjekt, das den einzelnen Schlüsselobjekten wiederholt entspricht.

h = { foo: {bar: {baz: 1}}} 

h.dig(:foo, :bar, :baz)   #=> 1 
h.dig(:foo, :zot)     #=> nil 

http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig

+1

Sieht in Anwendungsfällen verdächtig ähnlich zu "graben", in 2.3 nur als "&." Eingeführt. Irgendwelche Unterschiede? –

+0

In der Tat, danke! :) – bbozo

+4

IMHO sollte dies die akzeptierte Antwort sein. –

1

Während hash&.[](:key) zu dem trainierten rubyist elegant ist, würde ich nur hash && hash[:key] wie es besser liest und intuitiver für den Programmierer nach mir kommt, die nicht so vertraut sind mit die Feinheiten von Rubin. Einige zusätzliche Zeichen in der Codebasis können manchmal eine Menge Googling für jemand anderen speichern.

(In Anbetracht der Kontext Sie dies nutzen wollen, ist in einer bedingten Anweisung, natürlich.)

Verwandte Themen