Issue #11816 has been updated by Joan Blackmoore.


I can understand the intention behind the proposal, but would like to express a (strong) disagreement with it.

The thing is that it would break language's consistency and is in contradiction to declared behavior.

"safe navigation operator" serves, by accepted feature request [#11537](https://bugs.ruby-lang.org/issues/11537), as an alternate way of method invocation. The only difference to standard method sending is ignoring passed argument if target object is *nil*. This means, expression may result either in a value of expected type or *nil* and programmer need count with this eventuality.

This bug report, or rather feature request, asks for change of existing role of *&.* as a "safe" methods chain navigator and make it later/last resort objects combinator.
Lowering operator's precedence would result in much harder to understand code, in figuring out at which moment it would be applied and what would be its argument. In comparison to unambiguous situation, when it has the highest implicit precedence, like the standard dot method call.

Setting an explicit precedence by parens would remedy the situation but, as already mentioned by Nobu, it would clash with existing *.()* syntax, a very unfortunate design decision introduced into the language as a parse-time way of writing Proc/Method#call . Confusing with standard method arguments passing,  enforcing eval precedence, optional dot at operator methodsí─ Unless widely used, its removal in Ruby 3.0 would be highly welcomed.

I'd suggest keep the existing behavior or possibly extend with `#respond_to?` method check and get rid of exception to the rule when applied to *NillClass* instance, like `nil&.nil?` resulting in `true`.

It may also be taken into the consideration a little inconsistency when followed by operator method:

optional dot omitted
`40+2  # 42`
`40&.+2  # 42`

vs

`40.+2 # 42` 
`40&..+2  # syntax error`


----------------------------------------
Bug #11816: Partial safe navigation operator
https://bugs.ruby-lang.org/issues/11816#change-58117

* 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:

```ruby
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

```js
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/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>