Tobias Reif wrote:
> 
> Joel VanderWerf wrote:
> 
>  > I'd vote against it because of the performance cost of checking each
>  > attr assignment for a hook.
> 
> I see. But performance is not always the top priority, and users make
> the choice which constructs to use.

I was guessing that users wouldn't have a choice, because every "@x =
..." would have to be checked for a hook, because the hook on @x could
be turned on or off dynamically. Maybe that's not so bad, though.

>  > If I needed to do something like this, I'd
>  > use an AOP approach to intercepting the attr writer.
> 
> I would be very glad if you could provide an example :)

Here's a dull little example, but it shows what I meant by intercepting
the attr writer. It might be used to accept lines into a fixed length
text field.

  class LineStorage

    def initialize max
      @max = max
      @char_count = 0
      @ary = []
    end

    attr_reader :char_count

    def char_count= x
      raise "Overflow!" if x > @max
      @char_count = x
    end
    protected :char_count=

    def add_line line
      self.char_count += line.size
      @ary << line
    end

  end

  line_store = LineStorage.new 20

  line_store.add_line "First line"
  line_store.add_line "Second line"   # ==> Overflow!


What's more interesting is AOP (aspect oriented programming), which
would help you manage the hook code in one place even if it affected
many methods. I haven't tried it in this case, YMMV. See:

  http://www.ruby-lang.org/en/raa-list.rhtml?name=AspectR

You could also use a mixin to override the writer method. But both AOP
and mixin approaches require the methods of the original class
(LineStorage) to use the writer rather than directly accessing the
variable.