Skip to content

Instantly share code, notes, and snippets.

@aruprakshit
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aruprakshit/b205806a81c592988025 to your computer and use it in GitHub Desktop.
Save aruprakshit/b205806a81c592988025 to your computer and use it in GitHub Desktop.
respond_to? vs respond_to_missing?
# First check is always #respond_to? , if it returns false, then #respond_to_missing? will be called, otherwise #respond_to_missing?
# will never be called. For all regular methods( which has been created by def, define_method, in C-implementation etc), thus we get
# false, while we pass the method name to the #respond_to_missing?. Because, first check has been done inside #respond_to?, and it
# returns true. That's why second output is [true, false]. Because, #foo is a regular method.
# Now why the second output is [true, true] ? The reason, I already explained, again #baz is not a regular method, so first check in
# #respond_to? return false, thus check goes to #respond_to_missing?. As I implemented it, so as per the implementations it is giving
# true, which in turn caused #respond_to? method to returns to true.
#!/usr/bin/env ruby
class Foo
def foo
12
end
def method_missing(meth, *args, block)
if meth.to_s.start_with? "ba"
"#{meth} has been created by #{__method__}"
else
super
end
end
def respond_to_missing?(meth, include_all)
if meth.to_s.start_with? "ba"
true
else
super
end
end
end
begin
p [Foo.new.respond_to?(:baz),Foo.new.send(:respond_to_missing?, :baz, true)]
p [Foo.new.respond_to?(:foo),Foo.new.send(:respond_to_missing?, :foo, true)]
rescue Exception
puts "#{$!} (#{$!.class})"
$stdout.flush
raise $!
end
# >> [true, true]
# >> [true, false]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment