Finding parent-class hierarchy recursively

R

RichardOnRails

Hi,

I wrote a method to display a class' "parentage" based on an idea in
"Ruby Cookbook", sec. 10.1:

def parents(obj)
( (obj.superclass ? parents(obj.superclass) : []) << obj). reverse
end

I displayed Class' parent-class hierarchy with:

Class.superclass.inspect => Module
Module.superclass.inspect => Object
Object.superclass.inspect => nil

Then I tested the automatic generation of that hierarchy as follows:

parents(Class).inspect => [Class, Object, Module]
Expected: [Class, Module, Object]

I tried display intermediate values during the recursion, but I
couldn't see where I'm going wrong. Any ideas?

Thanks in advance,
Richard
 
S

Sebastian Hungerecker

RichardOnRails said:
def parents(obj)
( (obj.superclass ? parents(obj.superclass) : []) << obj). reverse
end
[...]
parents(Class).inspect => [Class, Object, Module]
Expected: [Class, Module, Object]

Ok, here's what happens:
parents(Class) = (parents(Module) << Class).reverse
parents(Module) = (parents(Object) << Module).reverse
parents(Object) = [Object]
parents(Module) = ([Object] << Module).reverse
= [Module, Object]
parents(Class) = ([Module, Object] << Class).reverse
= [Module, Object, Class].reverse
= [Class, Object, Module]

Anyway, do you know that you can get what you want just by calling
TheClass.ancestors? Well, not quite as that also includes included
modules, but TheClass.ancestors.grep(Class) would give you exactly
the results you expected from your method.

HTH,
Sebastian
 
R

RichardOnRails

RichardOnRails said:
def parents(obj)
  ( (obj.superclass ? parents(obj.superclass) : []) << obj). reverse
end
[...]
parents(Class).inspect  =>  [Class, Object, Module]
                   Expected:  [Class, Module, Object]

Ok, here's what happens:
parents(Class)  = (parents(Module) << Class).reverse
parents(Module) = (parents(Object) << Module).reverse
parents(Object) = [Object]
parents(Module) = ([Object] << Module).reverse
                = [Module, Object]
parents(Class)  = ([Module, Object] << Class).reverse
                = [Module, Object, Class].reverse
                = [Class, Object, Module]

Anyway, do you know that you can get what you want just by calling
TheClass.ancestors? Well, not quite as that also includes included
modules, but TheClass.ancestors.grep(Class) would give you exactly
the results you expected from your method.

HTH,
Sebastian

Thanks, Sebastian!

I stupidly failed to recognize that "reverse" would affect each
iteration of the recursive routine, rather than merely to last
iteration as I intended.

I removed the interior "reverse" and the world is beautiful again, to
wit:

parents(Class).reverse.inspect
=> [Class, Module, Object]
TheClass.ancestors?

I did know about that, but thanks for asking. I wanted to write my
own trace routine so that I have my own insight into metaprogramming
techniques and the structure of Ruby.

Best wishes,
Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top