From: itsme213 Date: 2005-01-14T00:36:14+09:00 Subject: Re: Duck Typing as Pattern Matching "David A. Black" wrote in message > > >> The whole point of method_missing is that it catches missing methods. > > > > Sure. And if, after catching it, you do something which the (original) > > caller would consider a valid handling of the (original) request, then you > > should indicate the fact in your 'respond_to?'. Otoh, if your > > method_missing simply interposes some exception stuff, and perhaps then > > calls super, then you have not handled the client request. In that case you > > did not respond_to the client request. > > I don't agree that that's a necessary formula, or that nothing that > doesn't fit into it should exist. I did not claim either. But for something to work properly with code that does x.foo if (x.respond_to? :foo) # quite reasonable, you'll agree it must follow that rule. > A good example is OpenStruct, which > takes advantage of the open-endedness of method_missing. I would say that for each of the method o.m calls that OpenStruct handles via method_missing (I think those are #m(), and #m=(x), for any m), it _should_ return true o.respond_to?(:m). And without that, OpenStruct objects will not work properly with (if x.respond_to?) code. And since Ruby does not treat arity or arg-names as part of the method signature or selector (a whole other discussion), there is no way for respond_to to distinguish between x.foo and x.foo(y). Hence OpenStruct should have: def respond_to(x); true; end > >> You're not expected to enumerate them by name Correct. And #respond_to? does not enumerate by name, #methods does. If I implemented a proxy that simply forwarded all missing requests, I would do: class Proxy def init(real); @real = real; end def method_missing(*args); @real.send *args; end def respond_to?(x); super || @real.respond_to(x); end end > >> if the > >> object thinks it responds to them, then they're not missing. Correct. So it should reply true to respond_to? for those cases. > (Of course you could just do: > > def respond_to?(m) > true > end > > to mirror the flexibility of method_missing :-) Which would be OK if (and only if) a client call, x.foo for *any* foo, was actually handled by your method_missing to behave as that client would expect. See proxy or openstruct example above. No prob if this thread is wound down ... I don't mind talking to myself, occaisonally I might even listen :-)