On Sun, 2002-08-04 at 07:32, Harry Ohlsen wrote:
> Yep. The issue is that in order to get the level of transparency I'd like to 
> achieve, I don't want the user to have to write any code.
> 
> I thought I might be able to maybe write my own versions of attr_writer and 
> attr_accessor that created a special version of field=() that included the 
> processing I want, but the following example shows that won't work.
> 
>     class Fred
>        def a=(a)
>            $stderr.puts "Setting @a to #{a}"
>            @a = a
>        end
> 
>        def initialize(a)
>            @a = a
>        end
>    end
> 
>    f = Fred.new(123)
> 
>    f.a = 456
> 
> When you run this, it prints "Setting @a to 456".  The initial setting of @a 
> in initialize doesn't get caught.  Ie, a=() doesn't seem to come into effect 
> until AFTER the instance variable has been created.

tru'nuff. that won't do it.

just a wild guess, but my problem was fianlly solved with this (thank
rich kilmer for this particular variation)

class Object
  # utility method for dynamically overriding a method
  # to addtionally call a proc/block --Rich Kilmer
  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
          $___trigger___ = self if $___trigger___ == nil
          send(:#{alias_meth}, *args, &block)
          x = @___procs___['#{meth}'].call(*args)
          $___trigger___ = nil
          return x
        end
      end
    EOS
  end
end

it may tak a bit to "decode" this, but perhaps a reworking of or
something like this might help?

-- 
~transami