It's really quite rare that a new realease of Ruby changes a behavior, and by "rare", I mean really rare. But, there's one change in Ruby 2.0 that is definitely breaking some code.
Let's have a look at this example:
class Lolcat
protected
def serious?
false
end
private
def ohai
puts "ohai"
end
end
Lolcat.new.tap do |lolcat|
puts lolcat.respond_to?(:serious?)
puts lolcat.respond_to?(:ohai)
end
Running this code with Ruby 1.9.3:
ruby lolcat.rb
# true
# false
Running this code with Ruby 2.0:
ruby lolcat.rb
# false
# false
What is happening here ?
From Ruby 2.0, respond_to?
behavior changed to check only public methods.
Before that, public and protected methods were checked.
This change makes actually perfect sense, but it can break some code when running 2.0:
respond_to?
respond_to?
takes a second argument to check against all methods (protected and private). By
default, this second argument is false.
Lolcat.new.tap do |lolcat|
puts lolcat.respond_to?(:serious?, true)
puts lolcat.respond_to?(:ohai, true)
end
Running this code with Ruby 1.9.3:
ruby lolcat.rb
# true
# true
Running this code with Ruby 2.0:
ruby lolcat.rb
# true
# true
The other way of making this code run as expected would be to declare this
method as public. But, sometimes, you do not want a particular method to be
public, and yet, you want to call respond_to
, like for instance in an
ActiveRecord callback.