On Mon, Jan 15, 2007 at 10:52:37PM +0900, Juozas Gaigalas wrote:
> I'm looking for a simple and short solution/library that does this:
> 
> a = []
> 
> def a.modified
> puts "Array a changed"
> end
> 
> a << 'x'
> puts a
> a[0] = 'y'
> puts a
> 
> ----OUTPUT----
> Array a changed
> x
> Array a changed
> y

You can sort of do this, but an object does not know what variable(s) it is
assigned to, so you will never be able to get the "Array a changed" message
from it directly. Try the following, however:

module ArrayWatch
  def is_modified?
    @modified
  end

  def reset_modified
    @modified = false
  end

  def []=(k, v)
    @modified = true
    super(k, v)
  end

  def <<(v)
    @modified = true
    super(v)
  end

  def concat(v)
    @modified = true
    super(v)
  end

  def push(*v)
    @modified = true
    super(*v)
  end

  def unshift(*v)
    @modified = true
    super(*v)
  end

  def replace(v)
    @modified = true
    super(v)
  end

  def slice!(*v)
    @modified = true
    super(*v)
  end

  def compact!
    @modified = true
    super
  end

  def sort!(&block)
    @modified = true
    super &block
  end

  def uniq!
    @modified = true
    super
  end

  def reverse!
    @modified = true
    super
  end

  def flatten!
    @modified = true
    super
  end

  def collect!(&block)
    @modified = true
    super &block
  end

  def map!(&block)
    @modified = true
    super &block
  end

  def delete_at(i)
    @modified = true
    super(i)
  end

  def delete(v, &block)
    @modified = true
    super(v, &block)
  end

  def delete_if(&block)
    @modified = true
    super &block
  end

  def reject!(&block)
    @modified = true
    super &block
  end

  def shift
    @modified = true
    super
  end

  def pop
    @modified = true
    super
  end

end

a = []
a.extend ArrayWatch

def a.to_s
  "a #{ is_modified? ? 'is' : 'is not' } modified"
end

puts a 
a << 'x'
puts a
a.reset_modified
puts a
a[0] = 'y'
puts a

--Greg