From: Trans Date: 2007-08-31T22:49:40+09:00 Subject: Re: python-style decorators On Aug 30, 4:18 pm, "Keith Rarick" wrote: > On 8/30/07, Trans wrote: > > > Cool. It will be interesting to see how it turns out. > > Well, I've hit a snag as a result of two properties of ruby: > > 1. If you write "def foo.bar() end", bar is guaranteed to be a > singleton method on something regardless of the value of foo. (You can > verify this on lines 1695-1709 of parse.y and lines 3919-3950 of > eval.c.) > > 2. An unbound method (such as what you get by calling > foo.method(:bar).unbind) can only be bound to an object of the same > type as the original receiver. For singleton methods, this means that > they can only be bound to the very same object. > > Put these together and it means that once bar has been defined in this > way it can never become an instance method. > > If only there were some way to get the body of an unbound method as a > string I could eval it again in the appropriate context. Short of > that, I see no way to make this notation work. So you've hit the same wall I did with module inheritance. That's unfortunate. Though in some ways I'm glad you have. Maybe you'll give some consideration to a long standing opinion of mine, that either the distinction between class and module should just be torn down, or that singleton classes should be "singleton modules" instead. After all, we can't subclass singleton classes, so why not allow us to include them instead? That would solve both issues in one stroke, and I dare say, improve Ruby's meta-programming by leaps and bounds (pun intended ;) However, even though I think such a change is a good thing to pursue (I'm even tempted to revive Suby just to offer this one distinct feature), I offer this: class X class Foo def initialize(klass) @klass = klass end def singleton_method_added(meth) return if meth == :singleton_method_added m = method(meth) @klass.send(:define_method, meth, m.to_proc) end end def self.fooized @foo ||= Foo.new(self) end def fooized.try 10 + 3 end end p X.new.try Honestly, I half-expect I'm delusional, b/c I'm not sure how this manges to work, but it seems to do so. Maybe you can use it as a jumping board. Yours, T.