From: Mark Hubbart Date: 2005-02-18T02:53:10+09:00 Subject: Re: adding a dynamic method handler? (long post) On Thu, 17 Feb 2005 17:19:54 +0900, Robert Klemme wrote: > > "Mark Hubbart" schrieb im Newsbeitrag > news:de63abca050216125273686a45@mail.gmail.com... > > On Wed, 16 Feb 2005 18:19:50 +0900, Robert Klemme > wrote: > > > > > > "Mark Hubbart" schrieb im Newsbeitrag > > > news:de63abca0502152303763354f7@mail.gmail.com... > > > > Hi, > > > > > > > > I've been using method_missing overly much in my code lately, and > it's > > > > prompted me to think a lot about it's limitations. > > > > > > > > > > > > > So, any thoughts? > > > > > > I'm wondering in which situation you need this. Although I understand > the > > > benefits of your approach I don't see the use case for this. > > > > Basically this is for any time that you want the code re-use and ease > > of implementation afforded by method_missing, but the benefits of > > still having the methods behave mostly as if they were actually > > defined, rather than handled dynamically. This is useful for quickly > > defining wrapper objects, or objects that delegate to multiple other > > objects. > > > > The idea is that this would be a way of dynamically creating methods > > for an object, without resorting to relatively permanent methods like > > "class << self; define_method(:foo){...}; end". > > I'm sorry if I am being stubborn (or dump), but this is still pretty much > abstract. I'd like to know which concrete use case made this behavior > necessary. Maybe stubborn, but that's not always a bad thing. There are many things I'm very glad Matz is stubborn about :) I don't think I ever implied that this behavior was *necessary*. You can implement similar functionality with what is currently available. It's just a pain in the neck to do it; You either have to break down and def a bunch of methods, or override respond_to? and method in your class. And sometimes neither of those is the *best* solution. I did give a specific use case where it would be very useful, though. When wrapping a class, or doing runtime refactoring (like what pathname does, which is, for the most part, a refactored wrapper for File and Dir), this could be very handy. Like method_missing, it would allow you to handle large amounts of similar methods at once, letting you condense code; while still getting almost all the benefits of actually defining each individual method. class DirectoryItem def initialize(path) @path = path end [...] def dynamic_method(name) @@file_methods = (File.methods - Object.methods).map{|s|s.to_sym} @@dir_methods = (Dir.methods - Object.methods).map{|s|s.to_sym} if @@file_methods.include? name if File.method(name).arity == 1 lambda{ File.send(name, @path) } elsif name == :truncate lambda{|len| File.send(name, @path, len) } elsif File.method(name).arity == 2 lambda{|path| File.send(name, @path, path) } end elsif @@dir_methods.include? name # handle Dir methods here end end end The equivalent portion of code using 'def' would be much, much longer, and very repetitive. The equivalent code using method_missing would be about the same length, but if anyone tried to check it's capabilities, it would seem to almost be an empty object. cheers, Mark