2016-01-04 16 views
22

Poiché Ruby 2.3 introduce l'operatore di Navigazione sicura (&.), a.k.un operatore solitario, il comportamento sull'oggetto nil sembra strano.Operatore di navigazione sicura (&.) Per nil

nil.nil? # => true 
nil&.nil? # => nil 

È progettato per comportarsi in questo modo? O qualche astuccio che scivolava via quando si aggiungeva l'operatore solitario?

+1

Non chiaro perché ti sembra strano. – sawa

+0

Perché è meglio usare 'try' in Rails? – Jwan622

+0

@ Jwan622 Penso che questo sia ispirato a 'try'. –

risposta

28

foo&.bar è una scorciatoia per foo && foo.bar, così che cosa ci si può aspettare il risultato dell'espressione nil && nil.nil? di essere?

+18

In realtà, non è esattamente 'foo && foo.bar'. Piuttosto '(foo == nil)? nil: foo.bar', cioè controlla solo che il metodo ricevente sia 'nil'. Questo è rilevante quando 'pippo' è' falso'. – codener

5

Questo perché nil&.nil? è una scorciatoia per nil && nil.nil?. Ciò valuterà a nil && true, che è quindi nil.

(nil && x).nil? valuta sempre a true, per qualsiasi valore di x.

Mentre la sintassi ha il potere, questo caso specifico ha un certo potenziale per diventare un 'Gotcha' per uno sviluppatore:

(stuff&.things).nil? => Questo produce true se roba non esiste, o stuff.things rendimenti nil.

contro il caso qui di seguito:

stuff&.things&.nil? => Questo produce nil in tutti i casi, tranne il caso in cui stuff.things restituisce qualcosa di diverso nil, nel qual caso sarebbe tornato false.

A causa della difficoltà nella normale logica booleana di differenziare tra false e nil, è improbabile che ciò abbia senso nella logica normale.

+0

'nil && nil.nil?' Valuta direttamente 'nil', il' nil.nil? 'Non ha importanza. Prova 'nil && (mette 1)', niente stampa. – sbs

+0

@sbs corretto. Si chiama [valutazione del cortocircuito] (https://en.wikipedia.org/wiki/Short-circuit_evaluation). –

+3

Per evitare trucchi, evitare '& .nil?', Dato che sei sempre "sicuro" di chiamare '#nil?'. Fai 'roba e .things.nil? 'Invece. –