Summary
--------------------------
I want an elegant way to add an object instance as an attribute of an
REXML::Element, and have the result of the #to_s method of the instance
used for the value when the Element has to_s/write called on it, NOT
when the assignment occurs.

  class Foo
    attr_accessor :bar
    def to_s; "--#{bar}--"; end
  end

  require 'rexml/document'
  d = REXML::Document.new
  d << REXML::Element.new( 'root' )

  f = Foo.new
  f.bar = 'old value'
  d.root.attributes[ 'foo' ] = f
  f.bar = 'new value'
  puts d
  #=> <root foo='--old value--'/>
  #                ^^^^^^^^^ I want 'new value' here



Options
--------------------------
One option would be to beg the author or REXML to redo REXML do support
lazy evaluation (possibly as an option). 

Another would be to subclass REXML::Element, find all the existing
methods where the to_s is invoked on attributes, and override those
methods to delay the evaluation.

Another is to subclass the element, assign 'f' as an instance variable,
subclass the #write method and add it to the attribute list right before
calling the super #write. (This is what I'm doing right now, but I
really don't like it.)

  class Bar < REXML::Element
    attr_accessor :foo
    def write( *args )
      self.attributes[ 'foo' ] = @foo if @foo
      output = super
      self.attributes[ 'foo' ] = nil if @foo
	output
    end
  end



Motivation
--------------------------
I'm writing my own SVG library (intended to be API-compatible with
ruby-svg[1]) where every element is based off of REXML::Element. (I'm
doing this because I like the power of document manipulation that REXML
provides, because ruby-svg doesn't emit svg that Firefox likes, and
because ruby-svg could be taken further than 'just' convenience methods
for attributes.)

In ruby-svg, there is an SVG::Style element which provides convenient
access to style attributes by name. For example:

  circle = SVG::Circle.new(0,0,10){
    self.style = SVG::Style.new( :opacity => 0.5 )
    self.style.stroke = "red"
  }
  circle.style.fill = '#ff6'
  puts circle
  #=> <circle cx="0" cy="0" r="10" style="fill:#ff6; opacity:0.5;
stroke:red;" />

ruby-svg gets away with this because it rolls all its own classes and
to_s methods, and calls to_s on the Style class only when serializing
the document. 

Since my Circle class ultimately inherits from REXML::Element, I'm
getting all the benefits of REXML's built-in to_s methods...but at the
same time I'm limited by them.

I will need to do this for other instances as well (I envision allowing
complex transform objects, descriptions of paths, etc.), so I want a
cleaner way than adding and removing items during serialization. 


Thoughts?


[1] http://raa.ruby-lang.org/project/ruby-svg/