Feature #14548
openAllow some_array&.[1] to be a valid syntax
Description
Currently, Ruby allows accessing an array's index while testing whether the array is not nil with this syntax: my_array&.[](1). I've always found this awkward but didn't mind about suggesting anything to improve this.
I was just reading about how JavaScript is probably going to support myArray?.[1] and found that it read good enough for me.
So I'd like to propose about the same syntax, replacing ?. with the Ruby equivalent &. instead. How does that look like to you?
        
          
          Updated by nobu (Nobuyoshi Nakada) over 7 years ago
          
          
        
        
      
      
    
        
          
          Updated by znz (Kazuhiro NISHIYAMA) about 7 years ago
          
          
        
        
      
      - Description updated (diff)
 
        
          
          Updated by matz (Yukihiro Matsumoto) over 6 years ago
          
          
        
        
      
      - Status changed from Open to Rejected
 
And it's too confusing.  ary&.[] and ary&.[]() for example.
        
          
          Updated by hsbt (Hiroshi SHIBATA) almost 4 years ago
          
          
        
        
      
      - Project changed from 14 to Ruby
 
        
          
          Updated by knu (Akinori MUSHA) almost 2 years ago
          
          
        
        
      
      - Status changed from Rejected to Open
 - Assignee set to matz (Yukihiro Matsumoto)
 
Can we reconsider this? JavaScript already introduced this syntax a while ago and we are already getting pretty much used to it.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining#syntax
obj.val?.prop
obj.val?.[expr]
obj.func?.(args)
I know ary&.[] is ambiguous, but it's extremely rare to call [] with no arguments, so let's just keep the compatibility and allow it to swallow the following arguments if any.
        
          
          Updated by Eregon (Benoit Daloze) almost 2 years ago
          
          
        
        
      
      What about using dig for this like array_or_nil.dig(index) and adding class NilClass; def dig(*) = nil; end?
There is also nothing wrong with array_or_nil && array_or_nil[index].
IMO these ?.[ look too cryptic.
        
          
          Updated by zverok (Victor Shepelev) almost 2 years ago
          
          
        
        
      
      What about using
dig
Actually, many codebases are already using dig in those cases (and it is clearer without redefinition on nil, telling the reader "we are aware there might be nil here"):
array_or_nil&.dig(index)
...but using the proposed solution is shorter and cleaner.
There is also nothing wrong with
array_or_nil && array_or_nil[index].
...until it is part of the message chain:
# bad
calculate_some_value(with, some, arguments) && calculate_some_value(with, some, arguments)[index]
# wordy, requires inventing new names:
intermediate = calculate_some_value(with, some, arguments) 
intermediate && intermediate[index]
Though, even if there is already a variable, foo && foo[bar] is already non-DRY and impends reading.
IMO these
?.[look too cryptic.
I honestly don't see how it is more cryptic than &.foo(. For the codebases that use &. where appropriate, an attempt to write foo&.[bar] is what less experienced programmers always try to do, and "why it doesn't work" is more cryptic than if it would.
Those are somewhat more confusing, too:
# I tried to use foo&.[bar], it failed, I know [] is a method and I write this:
foo&.[](bar)
# I find the above ugly, and I switch to dig:
foo&.dig(bar)
...but it is kind of non-standar to use dig with one argument, and needs to be remembered as a separate idiom.
        
          
          Updated by hsbt (Hiroshi SHIBATA) over 1 year ago
          
          
        
        
      
      - Status changed from Open to Assigned