When Using method_missing, Update respond_to
Because Ruby is dynamically typed, respond_to? is an important method. Although sometimes is_a? will creep into code, respond_to? should always be considered first.
We don't care if it's a duck, we only care if it quacks.
A problem arises when developers start to use method_missing to implement methods. Let's say a developer did something like this:
For arbitrary rationale, this would allow the duck to quack any of the following ways:
However, we've created a problem with respond_to?.
We have now limited our ability to use dynamic typing. We cannot depend on respond_to? telling us if our object can quack. Therefore, when using method_missing, remember to update respond_to?
Although method_missing can still be problematic, this makes it a little less painful.
# Instead of def my_method(input) input.quack if input.is_a?(Duck) end # We want def my_method(input) input.quack if input.respond_to?(:quack) end
We don't care if it's a duck, we only care if it quacks.
A problem arises when developers start to use method_missing to implement methods. Let's say a developer did something like this:
class Duck def method_missing(method, *args, &block) if method.to_s =~ /^quack/ puts "quack!" else super end end end
For arbitrary rationale, this would allow the duck to quack any of the following ways:
duck.quack duck.quack! duck.quack_loudly
However, we've created a problem with respond_to?.
duck.respond_to?(:quack) #=> false duck.quack #=> 'quack!'
We have now limited our ability to use dynamic typing. We cannot depend on respond_to? telling us if our object can quack. Therefore, when using method_missing, remember to update respond_to?
class Duck QUACK_METHOD = /^quack/ def respond_to?(method) return true if method =~ QUACK_METHOD super end def method_missing(method, *args, &block) if method.to_s =~ QUACK_METHOD puts "quack!" else super end end end
Although method_missing can still be problematic, this makes it a little less painful.
Posted on 2007-05-16 | permalink | del.icio.us
Blog Archive
