Live to_s calls for rexml attribute

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
#=>

^^^^^^^^^ 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
#=>

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/