Trans
7/22/2006 1:59:00 PM
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.