The following code prints nil in Ruby 2.2.0-preview1 but worked in all previous version of Ruby back to 1.8.7:
class Foo
def foo; "abc" end
# this default param should resolve at runtime to the #foo method call
def run(foo = foo)
p foo # print shadowed local var defaulting to attr value
end
end
puts "Testing #{RUBY_VERSION}:"
Foo.new.run
# Ruby 2.2.0-preview1
# => nil
# Ruby 1.x 2.x etc
# => "abc"
My guess is this is happening because "foo" in "foo = foo" is resolving to the argument variable "foo", which currently has the value of nil. It would be equivalent to setting "qux = qux" in a method body, which has been the expected behavior for a long time.
I understand that shadowing variables is something you should probably never do, but unfortunately this code was already written and working for quite a while, so I figured it would be wise to file a bug report for the following reasons:
This seems like a breaking change in Ruby 2.2.0-preview1 that was not announced in the changelog. My guess is this change may have been unintentional, but if it was we need a changelog entry at the very least.
If this is newly expected behavior, I wanted to chime in that I don't think it makes much sense. I can't think of any time when a user would expect the default value of a "foo = foo" argument to be the same foo argument itself. That would be tautologically nil. Arguably, it doesn't make much sense inside of a method body either when there is a shadowed method that could be called instead.
This seems like a breaking change in Ruby 2.2.0-preview1 that was not announced in the changelog. My guess is this change may have been unintentional, but if it was we need a changelog entry at the very least.
I agree. How about to show a warning?
If this is newly expected behavior, I wanted to chime in that I don't think it makes much sense. I can't think of any time when a user would expect the default value of a "foo = foo" argument to be the same foo argument itself. That would be tautologically nil. Arguably, it doesn't make much sense inside of a method body either when there is a shadowed method that could be called instead.
I think this change is to make same as method body ("foo = foo" in method body).
I'm not sure your proposal is natural or not (matz issue?).
I like current behavior because it is simple (define a local variable foo' after the sentence foo=').
In our large rails app, I only had to fix 5 function definitions, by adding parenthesis to 4 of them. The warnings made it very easy to find and fix the code.