Take this class:
class Foo
def method_missing(m, *args)
m.to_s
end
end
irb(main):006:0> Foo.new.foo
=> "foo"
irb(main):007:0> Foo.respond_to? :foo
=> false
This obviously just returns the name of any method that doesn't exist
for the object. So if you can send the object any message and get a
result, why doesn't it respond_to those messages?
Pat
Think about it from an implementation perspective. How is respond_to? to know
what method_missing is going to do?
If you define a method_missing method, and you need your object's respond_to?
to reflect your method_missing magic, it is up to you to write a respond_to
method that will do so.
Kirk Haines
···
On Monday 05 June 2006 5:39 am, Pat Maddox wrote:
This obviously just returns the name of any method that doesn't exist
for the object. So if you can send the object any message and get a
result, why doesn't it respond_to those messages?
Pat Maddox wrote:
Take this class:
class Foo
def method_missing(m, *args)
m.to_s
end
end
irb(main):006:0> Foo.new.foo
=> "foo"
irb(main):007:0> Foo.respond_to? :foo
=> false
This obviously just returns the name of any method that doesn't exist
for the object. So if you can send the object any message and get a
result, why doesn't it respond_to those messages?
Pat
The respond_to method can't know what method_missing is doing with
missing methods, so it's the up to the class author to provide a version
of respond_to that agrees with method_missing.
···
--
Posted via http://www.ruby-forum.com/\.
More to the point, if you do this:
# foo.rb
class Foo
def method_missing(m, *args)
eval "def self.#{m}; '#{m}'; end"
self.__send__(m)
end
end
__END__
irb(main):001:0> require 'foo'
=> true
irb(main):002:0> f = Foo.new
=> #<Foo:0x1cd438>
irb(main):003:0> f.respond_to? :foo
=> false
irb(main):004:0> f.foo
=> "foo"
irb(main):005:0> f.respond_to? :foo
=> true
irb(main):006:0>
You've now defined a 'foo' method and further invocations of f.foo will go to the newly minted method rather than method_missing each time.
-Rob
···
On Jun 5, 2006, at 8:23 AM, Tim Hunter wrote:
Pat Maddox wrote:
Take this class:
class Foo
def method_missing(m, *args)
m.to_s
end
end
irb(main):006:0> Foo.new.foo
=> "foo"
irb(main):007:0> Foo.respond_to? :foo
=> false
This obviously just returns the name of any method that doesn't exist
for the object. So if you can send the object any message and get a
result, why doesn't it respond_to those messages?
Pat
The respond_to method can't know what method_missing is doing with
missing methods, so it's the up to the class author to provide a version
of respond_to that agrees with method_missing.
In my example where the object responds to everything, sure. It was
just an example though, and of course not every class is going to act
like this.
I guess the key is to write a predicate and stick it in both methods.
class Foo
def method_missing(m, *args)
valid_method?(m) ? m.to_s : super
end
def respond_to?(m)
valid_method?(m)
end
private
def valid_method?(m)
true
end
end
Of course it's not particularly useful here, but you could change
valid_method? to
def valid_method?(m)
[ :foo, :bar ].include? m
end
Guess I just thought Ruby would automatically pick it up. However, I
don't see how it'd be able to, short of creating a copy of the object
in memory and calling the method on the object to see if it returns a
result. If the copy gives a method missing error, then respond_to?
would return false. Obviously it would suck to create a copy and
actually call the method just to see if an object responds to it.
Pat
···
On 6/5/06, dblack@wobblini.net <dblack@wobblini.net> wrote:
Hi --
On Mon, 5 Jun 2006, Pat Maddox wrote:
> Take this class:
>
> class Foo
> def method_missing(m, *args)
> m.to_s
> end
>
> irb(main):006:0> Foo.new.foo
> => "foo"
> irb(main):007:0> Foo.respond_to? :foo
> => false
>
> This obviously just returns the name of any method that doesn't exist
> for the object. So if you can send the object any message and get a
> result, why doesn't it respond_to those messages?
Maybe because that would render #respond_to? essentially useless
David
--
David A. Black (dblack@wobblini.net)
* Ruby Power and Light, LLC (http://www.rubypowerandlight.com)
> Ruby and Rails consultancy and training
* Author of "Ruby for Rails" from Manning Publications!
> Ruby for Rails
Pat Maddox wrote:
Guess I just thought Ruby would automatically pick it up. However, I
don't see how it'd be able to, short of creating a copy of the object
in memory and calling the method on the object to see if it returns a
result. If the copy gives a method missing error, then respond_to?
would return false. Obviously it would suck to create a copy and
actually call the method just to see if an object responds to it.
Pat
Not to mention the problems that could occur when Ruby tries calling a
method just to see if it works:
class War
def start(type=:nuclear)
...
end
end
war = War.new
war.respond_to? :start
···
--
Posted via http://www.ruby-forum.com/\.