From: matt.larraz@... Date: 2015-12-16T00:38:20+00:00 Subject: [ruby-core:72165] [Ruby trunk - Bug #11816] Partial safe navigation operator Issue #11816 has been updated by Matt Larraz. My na��ve understanding is that `foo&.bar` should be a shorthand for `foo && foo.bar`, and therefore the `&.` operator should take the same level of precedence as the `&&` operator. Marc-Andre Lafortune wrote: > x = nil > x&.foo.bar # => nil > x&.foo[42] # => nil > x&.foo[42] = 43 # => nil > x&.foo * 42 # => nil > x&.foo + 42 # => nil > x&.foo << 42 # => nil > x&.foo < 42 # => nil > x&.foo == 42 # => false ### This is where the precedence of &. is higher > x&.foo || 42 # => 42 > x&.foo ? 1 : 2 # => 2 If you substitute `x&.foo` for `x && x.foo` in the above, they all evaluate the same except for one: ~~~ x && x.foo == 42 # => nil ~~~ This makes sense, since `==` is a method and not an operator. ---------------------------------------- Bug #11816: Partial safe navigation operator https://bugs.ruby-lang.org/issues/11816#change-55576 * Author: Marc-Andre Lafortune * Status: Open * Priority: Normal * Assignee: Yukihiro Matsumoto * ruby -v: preview 2 * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- I'm extremely surprised (and disappointed) that, currently: x = nil x&.foo.bar # => NoMethodError: undefined method `bar' for nil:NilClass To make it safe, you have to write `x&.foo&.bar`. But if `foo` is never supposed to return `nil`, then that code isn't "fail early" in case it actually does. `nil&.foo.bar` is more expressive, simpler and is perfect if you want to an error if `foo` returned `nil`. To actually get what you want, you have to resort using the old form `x && x.foo.bar`... In CoffeeScript, you can write `x()?.foo.bar` and it will work well, since it gets compiled to if ((_ref = x()) != null) { _ref.foo.bar; } All the discussion in #11537 focuses on `x&.foo&.bar`, so I have to ask: Matz, what is your understanding of `x&.foo.bar`? I feel the current implementation is not useful and should be changed to what I had in mind. I can't see any legitimate use of `x&.foo.bar` currently. -- https://bugs.ruby-lang.org/