# Live to\_s calls for rexml attribute

**URL:** <https://www.ruby-forum.com/t/live-to-s-calls-for-rexml-attribute/68317>\
**Category:** Ruby\
**Created:** [September 11, 2006, 6:22pm UTC](https://www.ruby-forum.com/t/live-to-s-calls-for-rexml-attribute/68317 "2006-09-11T18:22:40Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![phrogz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/2acd7d/32.png) [@phrogz](https://www.ruby-forum.com/u/phrogz)\
**Post date:** [September 11, 2006, 6:22pm UTC](https://www.ruby-forum.com/t/live-to-s-calls-for-rexml-attribute/68317/1 "2006-09-11T18:22:40Z")

</div>

## 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/](http://raa.ruby-lang.org/project/ruby-svg/)
