In Ruby, why does nil[1]=1 evaluate to nil?

2019-01-12 09:22发布

问题:

For example:

nil[1]     #=> NoMethodError
nil[1]=1   #=> nil

It's not just syntax, as it happens with variables too:

a = nil
a[1]       #=> NoMethodError
a[1]=1     #=> nil

Oddly:

nil.method(:[]=)   #=> NameError
[].method(:[]=)    #=> #<Method...>

Ruby 2.3.0p0

回答1:

Some random findings: [only in Ruby 2.3.0p0]

The method doesn't seem to exist:

nil.method(:[]=)      #=> NameError: undefined method `[]='
nil.respond_to?(:[]=) #=> false

And you can't invoke it using send:

nil.send(:[]=)        #=> NoMethodError: undefined method `[]='

Ruby evaluates neither the right hand side, nor the argument, i.e.

nil[foo]=bar

doesn't raise a NameError, although foo and bar are undefined.

The expression seems to be equivalent to nil:

$ ruby --dump=insns -e 'nil[foo]=bar'
== disasm: #<ISeq:<main>@-e>============================================
0000 trace            1                                               (   1)
0002 putnil
0003 leave

$ ruby --dump=insns -e 'nil'
== disasm: #<ISeq:<main>@-e>============================================
0000 trace            1                                               (   1)
0002 putnil
0003 leave