April 28, 2014
I recently conducted a workshop about Contributing to Open-Source at first-ever Rubyconf Philippines. In its introductory talk, I spoke about how Aaron Patterson, fixed a 6 year old bug about Optional Arguments, that existed in Rails.
Let's try a small program.
class Lab
def day
puts 'invoked'
'sunday'
end
def run
day = day
end
end
puts Lab.new.run
What do you think would be printed on your terminal when you run the above program.
If you are using ruby 2.1 or below then you will see nothing. Why is that ? That's because of a bug in ruby.
This is bug number 9593 in ruby issue tracker.
In the statement day = day
the left hand side variable assignment is stopping the call to method day
. So the method day
is never invoked.
class Lab
def day
puts 'invoked'
'sunday'
end
def run( day: day)
end
end
puts Lab.new.run
In the above case we are using the keyword argument feature added in Ruby 2.0 . If you are unfamiliar with keyword arguments feature of ruby then checkout this excellent video by Peter Cooper.
In this case again the same behavior is exhibited. The method day
is never invoked.
You might be thinking that I would never write code like that. Why would you have a variable name same as method name.
Well Rails had this bug because rails has code like this.
def has_cached_counter?(reflection = reflection)
end
In this case method reflection
never got called and the variable reflection
was always assigned nil.
Nobu fixed this bug in ruby 2.2.0. By the way Nobu is also known as "ruby patch-monster" because of amount of patches he applies to ruby.
So this bug is fixed in ruby 2.2.0. What about the people who are not using ruby 2.2.0.
The simple solution is not to omit the parameter. If we change the above code to
def has_cached_counter?(reflection = reflection())
end
then we are explicitly invoking the method reflection
and the variable reflection
will be assigned the output of method reflection
.
And this is how Aaron Patterson fixed six years old bug.
If this blog was helpful, check out our full blog archive.