From: transfire@... Date: 2006-07-22T22:58:50+09:00 Subject: Re: Meta-Meta-Programming, revisited Erik Veenstra wrote: > > I don't think the reciever of the wrap should be an argument. > > Instead just let it be ther reciever of the pre_ call. For > > example Instead of: > > > > pre_condition(Module, :method_added) do |*args| > > > > Module.pre_condition(:method_added) do |*args| # NOT THE SAME > > Module is not the receiver! The argument Module is just an > indicator (stupid abuse), so pre_condition knows that is has to > wrap a module method (with "class << self" in > wrap_module_method) instead of an instance method. > > I should have called it pre_module_condition. (Like > wrap_module_method instead of wrap_method.) I was just sick of > creating more methods... ;] Sorry, I misprepresnted what I meant. Use "aModule" instead of "Module". -- You created a special method: #wrap_module_method for doing #wrap_method external to the a module/class, but you could just make it public (or use send): aModule.wrap_method And likewise aModule.pre_condition aModule.post_condition > > Also, #wrap_method seems like it could do with some > > simplification. Taking that to the furthest case, is their a > > reason the the following definition isn't enough? > > > > def wrap_method( sym, &blk ) > > raise ArgumentError, "method does not exist" unless method_defined?( sym ) > > old = instance_method(sym) > > define_method(sym) { |*args| blk.call(old.bind(self), *args) } > > end > > Well, life isn't that easy... (Have a look at the code below.) > First thoughts: > > * You definitely want to pass the block from the original > invocation to the original definition... Really... (In Ruby > 1.9, this could be done your way, since blocks do get blocks. > But not in Ruby 1.8.) > > * I wanted to be able to wrap non-existing methods. > > * When wrapping :initialize in Bar, your wrap_method complains > with "method does not exist". I see. I'm recall considering this before. Obviously I had gone the other direction, becuase then hwy use def at all, alwasy use #wrap_method (closure issues not with standing). That reminds me of an older notaiotn of mine where 'def' itself would actually wrap a prexisting method automatically and you'd use #super to call it. But I digress... > * When wrapping methods in both the class and the superclass, > going up and down, you can't (at wrap-time) determine the > order in which the blocks are to be executed (at run-time). > If I run the code below with your wrap_method (after removing > the "method does not exist" check), this :wrap_Foo is gone! > It's not what _I_ expected... ;] (See [1] for a more > complicated example. I'll try to make a diagram.) Owww! Nice catch. I hadn't though of that. > It's complicated stuff... I tried to hide this complexity for > the user, by providing a clean interface (wrap_method) and an > even cleaner interface (pre_condition). I hope you find them > easy to use. Indeed. I'm going to work with this see what I can incoprate into Facets', if that's cool with you. Thanks, T.