# Mixin classes (continuning from the last post)

**URL:** <https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159>\
**Category:** Ruby\
**Created:** [March 17, 2007, 10:11pm UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159 "2007-03-17T22:11:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 17, 2007, 10:11pm UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/1 "2007-03-17T22:11:02Z")

</div>

Although I am a seasoned C/C++ programmer(+10 years), I am relatively  
new to the ruby (about 2 days) despite having some reservations(ruby  
debugger should be theslowest thing in the world) i am otherwise very  
impressed with the language, I intend to use Ruby for some code  
generation task ,Everything was going well until i hit that roadblock

class REXML::Element  
include TSort  
def initialize  
@dependencies=[]  
end  
def tsort\_each\_node(&block)  
@elements.each(&block)  
end  
def tsort\_each\_child(node, &block)  
@dependencies.each(&block) if @dependencies.size\>0  
end  
end  
well as you can see, i need to topologically sort some nodes in an  
xml file and there was a module Tsort in the  
ruby. from what understand i need to extend to class REXML::Element  
to feed Tsort algorithm. I have no problems  
with adding the methods but when i feed this new node to tsort() I get  
something like this

undefined method `size' for nil:NilClass H:/ruby/somCompiler.rb:112:in`tsort\_each\_child’  
c:/ruby/lib/ruby/1.8/tsort.rb:204:in  
`each_strongly_connected_component_from c:/ruby/lib/ruby/1.8/tsort.rb:183:in`each\_strongly\_connected\_component’  
c:/ruby/lib/ruby/1.8/rexml/element.rb:939:in `each' c:/ruby/lib/ruby/1.8/rexml/xpath.rb:53:in`each’  
c:/ruby/lib/ruby/1.8/rexml/element.rb:939:in `each' H:/ruby/somCompiler.rb:109:in`tsort\_each\_node’  
…

> From what I understand i am unable to add @dependencies array to the  
> REXML::Element.Is it not possible  
> or i am missing something terribly here?  
> Any help would be greatly appreciated…  
> Hurcan

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 17, 2007, 10:35pm UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/2 "2007-03-17T22:35:06Z")

</div>

On Mar 17, 2007, at 5:10 PM, hurcan solter wrote:

> ```
> end
> def tsort_each_node(&block)
> @elements.each(&block)
> end
> def tsort_each_child(node, &block)
> @dependencies.each(&block) if @dependencies.size>0
> end
> 
> ```
> 
> end

Just a guess but I suspect your problem is that you’ve effectively  
thrown away the initialize method for REXML::Element and replaced it  
with your own. I think you want:

alias \_\_original\_initialize initialize  
def initialize(\*args, &block)  
\_\_original\_initialize(\*args, &block)  
@dependencies = []  
end

This way you make sure the original version of initialize  
executes as well as your new code.

Gary W.

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 17, 2007, 11:26pm UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/3 "2007-03-17T23:26:11Z")

</div>

On 17.03.2007 22:33, Gary W. wrote:

> > ```
> > include TSort
> > 
> > ```
> 
> This way you make sure the original version of initialize  
> executes as well as your new code.

While this is true, at least @dependencies should be properly  
initialized unless REXML::Element instances are not created via new.

There’s another gotcha: by including TSort initialization might be  
broken, if TSort defines initialize and does not propagate to the parent  
class.

To OP: “if @dependencies.size\>0” can be rewritten as “unless  
@dependencies.empty?” which again is superfluous here: #each will take  
care of empty collections.

Maybe you need provide more code. From what you have shown so far it is  
not clear to me why @dependencies would be nil.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 18, 2007, 1:01am UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/4 "2007-03-18T01:01:20Z")

</div>

It looks like REXML already provides the two  
iterators you need to satisfy TSort. Try this:

require ‘rexml/document’  
require ‘tsort’

class REXML::Element  
include TSort  
def tsort\_each\_node(&block)  
each\_recursive(&block)  
end  
def tsort\_each\_child(node, &block)  
node.each\_child(&block) if node.respond\_to?(:each\_child)  
end  
end

doc = REXML::Document.new \<\<EOS  
  
Text, text, text  
  
EOS  
p doc.tsort

Gary W.

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 18, 2007, 1:55am UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/5 "2007-03-18T01:55:24Z")

</div>

On Mar 18, 2:00 am, Gary W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> end  
> p doc.tsort
> 
> Gary W.

well my sorting criteria something different from that.Consider this;

```
    <fixedRecordData name="EntityIdentifierStruct">
            <field name="FederateID" dataType="short int"/>
<field name="FederateIdentifier" 

```

dataType=“FederateIdentifierStruct”/

> 

```
<field name="orientation" dataType="OrientationStruct"/>

```

 EntityIdentifierStruct depends on FederateIdentifierStruct and FederateIdentifierStruct depends on none (primitives not important) and i also have to extract that denpendency information from child node attributes so one to one comparison wont work. So I have to compose a dependency graph first and keep it somewhere (I am thinking the element itself ,so the need for instance variable) only then i can give it to tsort\_each\_child to iterate over.., hurcan

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 17, 2007, 11:31pm UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/6 "2007-03-17T23:31:12Z")

</div>

On Mar 17, 11:33 pm, Gary W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > class REXML::Element  
> > end
> 
> This way you make sure the original version of initialize  
> executes as well as your new code.
> 
> Gary W.

On the contrary, it’s the original version that executes not mine.  
You see,it’s the REXML module that creates the Element instance  
and it calls the original constructor(if it’s the term) not mine. I  
erronously thought  
i am effectively replacing the REXML:Element with my own version.  
What i am trying to accomplish is adding to an existing class a new  
instance variable  
in its definition.

For example  
require “rexml/document”  
include REXML

class REXML::Element  
def some\_method  
puts “some\_method called”  
end

doc = Document.new File.open(“mydoc.xml”)  
doc.each\_element(“somexmltag”){|node| # i have no intervention here  
REXML does all the stuff  
puts node.methods #=\> [“some\_method” “namespaces” “attributes”]  
etc etc  
node.some\_method #=\> some\_method called  
the above code snippet works, and adds a method to an existing class  
in some other module  
i just wonder is it possible to add some instance variable in same  
manner?

---

<div class="post-metadata">

**Author:** ![hurcan\_solter](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/a88e4f/32.png) [@hurcan\_solter](https://www.ruby-forum.com/u/hurcan_solter)\
**Post date:** [March 18, 2007, 2:24am UTC](https://www.ruby-forum.com/t/mixin-classes-continuning-from-the-last-post/89159/7 "2007-03-18T02:24:27Z")

</div>

On Mar 17, 2007, at 8:55 PM, hurcan solter wrote:

> well my sorting criteria something different from that.Consider this;

Then you are going to have to implement Tsort over a different type  
of collection. Tsort uses the eql? method to compare nodes and I  
don’t think you want to mess around with REXML’s notion of equality.

I think it would be better off iterating over all the nodes in the  
document and creating a new dependency graph based on your criteria  
and then applying Tsort to that new data structure instead of the  
REXML data structure.

I’ll admit to not looking too deep into your problem but I get the  
feeling that you are applying TSort to the wrong data structure.

Gary W.
