makes sense. but the approach didn't fit. rather i took a differnt more
general appraoch which i think works out better. take a look:
def bind(meth, proc=nil, &block)
proc = block unless proc
meth = meth.to_s
alias_meth = meth[-1]==61 ? "__#{meth[0..-2]}__=" : "__#{meth}__"
self.instance_eval {
@___procs___ = {} unless @___procs___
@___procs___[meth]=proc
}
return if self.respond_to? alias_meth
self.instance_eval <<-"EOS"
class << self
alias_method :#{alias_meth}, :#{meth}
def #{meth}(*args, &block)
return if $___trigger___ == [self, :#{meth}]
$___trigger___ = [self, :#{meth}] if $___trigger___ == nil
x = send(:#{alias_meth}, *args, &block)
@___procs___['#{meth}'].call(*args) # or x = here???
$___trigger___ = nil
return x
end
end
EOS
end
you can see i used a global variable, $___trigger___ to store the
original activator of the event/binding. if subsequent event/bindings
cause a loop back to the original it will stop there.
this works well, i think. and is general enough to include as a
modification to the Object class. but i have two concerns that i was
wondering if you had any thoughts on.
first, only a single binding will work. trying to add another cancels
out any previous. that's okay for my use, but thinking in terms of this
being a generally usable construct, could be problematic. that's one
advantage paul's and my original notion of how to do this has over
yours, but yours deals well with blocks, so i adopted yours.
secondly, there's the question of what to return. notice my remark in
the code. if you overide a method without returning what the original
method returns this could cause program breakage. but then again, the
override might specifically want for it to return something else. and
this problem is only worsened if the first problem mentioned above is
addressed.
does that make sense?
have any thoughts on these matters?
~transami
···
On Sun, 2002-07-28 at 17:47, Rich Kilmer wrote:
In the meantime, the simple way to fix your
infinite-loop problem is to NOT propagate updates from the binding
if what you are setting is already set.