[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Finding parent-class hierarchy recursively

RichardOnRails

9/13/2008 3:17:00 AM

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
2 Answers

Sebastian Hungerecker

9/13/2008 9:22:00 AM

0

RichardOnRails wrote:
> 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
--
NP: Obituary - I'm in Pain
Jabber: sepp2k@jabber.org
ICQ: 205544826

RichardOnRails

9/14/2008 1:19:00 AM

0

On Sep 13, 5:21 am, Sebastian Hungerecker <sep...@googlemail.com>
wrote:
> RichardOnRails wrote:
> > 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
> --
> NP: Obituary - I'm in Pain
> Jabber: sep...@jabber.org
> ICQ: 205544826

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