Project

General

Profile

Actions

Bug #17348

closed

Shadowed method can not be evaluated on the line that it is shadowed

Added by d-snp (Tinco Andringa) 6 months ago. Updated 6 months ago.

Status:
Rejected
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
[ruby-core:101101]

Description

I encountered this in the code a junior Rubyist wrote. Rewriting to more logical code solved our problem, but in my opinion it should not have been an error. I reduced the code to this:

def a
  ""
end
a = a[0]
puts a.inspect

Expected: nil
Got:

Traceback (most recent call last):
shadowed.rb:4:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)

Note that:

a = ""
a = a[0]
puts a.inspect

Does work as expected, so it is specifically when a method is shadowed that this unexpected behaviour occurs.

Updated by jeremyevans0 (Jeremy Evans) 6 months ago

  • Status changed from Open to Rejected

This isn't a bug. It's expected that Ruby scans code and as soon as it encounters a local variable definition (the left hand side of =) it adds it to the local variable table. Changing this to not set the local variable until after the completion of the assignment expression would break code such as:

sum = lambda do |x, *v|
  return x if v.empty?
  x + sum[*v] 
end
sum[1, 2, 3, 4]
# => 10

You can compare to the equivalent that didn't set the local variable until after:

_sum = lambda do |x, *v|
  return x if v.empty?
  x + sum[*v]
end
sum = _sum
sum[1, 2, 3, 4]
# NameError

Updated by marcandre (Marc-Andre Lafortune) 6 months ago

In Ruby 3, you can write a[0] => a and that works :-)

Actions

Also available in: Atom PDF