昨日紹介したROXMLを

 Railsで製作中のシステムに入れてみようとして、派手にコケる。エラーメッセージをたどっていくと、どうもroxml.rbの

    412         def assert_accessor(name)
    413             @tag_accessors = [] unless @tag_accessors
    414             raise "Accessor #{name} is already defined as XML accessor in class #{self}" if @tag_accessors.include?(name)
    415             @tag_accessors << name
    416         end

 これが原因らしい。1回目のアクセス時は良くても、2回目以降にアクセスしたときに同じ定義をすることになるので、「ちょっと待て、お前はもうこれを定義してるぞ」ということらしい。とにかく、この@tag_accessorsの中身がユニーク(重複ナシ)であればいいっぽいので、

    412         def assert_accessor(name)
    413             @tag_accessors = [] unless @tag_accessors
    414             @tag_accessors << name unless @tag_accessors.include?(name)
    415         end

 に変更。
 とりあえずアドホック的に解決したけど、恐らくこの作者さん、RailsみたいなWebアプリで動かすことを想定してないんだろうなぁ…。
(追記)
 上で挙げた方法だと、万が一定義が重複してた時のエラーが出せなくなる。つーことで、その辺の修正も施したものとオリジナルのdiffをとってみた。アドホックさはまだ抜けないけど、モジュールが呼び出されたときにインスタンス変数(ここでは@tag_accessors)が初期化されればいいので、とりあえずの動作に問題はないだろう。

--- roxml.rb
+++ roxml.rb
@@ -401,7 +401,13 @@
         def tag_refs
             @xml_refs || []
         end
-
+
+        #initialize this flag when ROXML module is included
+        def clear
+            @@flag = 0
+        end
+        module_function :clear
+
         private

         def add_ref(xml_ref)
@@ -410,7 +416,8 @@
         end

         def assert_accessor(name)
-            @tag_accessors = [] unless @tag_accessors
+            @tag_accessors = [] unless @tag_accessors && @@flag == 1
+            @@flag = 1
             raise "Accessor #{name} is already defined as XML accessor in class #{self}" if @tag_accessors.include?(name)
             @tag_accessors << name
         end
@@ -444,6 +451,7 @@
         #
         def included(klass)
             super
+            ROXML_Class.clear#initialize flag
             klass.__send__(:extend, ROXML_Class)
         end
     end