[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Race condition in class inheritance

Gaspard Bucher

9/14/2007 2:09:00 PM

I need to identify classes from a string called kpath (class path)
reflecting the class inheritance. The string is made of the first
letter of each class. This is what I have now:
class Node
@@classes = {'N' => self}
def self.inherited(child)
super
@@classes[child.kpath] = child
end

def self.kpath
self == Node ? ksel : (superclass.kpath + ksel)
end

def self.ksel
self.to_s[0..0]
end

def self.class_from_kpath(kpath)
@@classes[kpath]
end
end

class Page < Node
end

class Document < Page
end

class Draft < Page
def self.ksel
'A'
end
end

puts Node.class_from_kpath('N') # got 'Node', ok.
puts Node.class_from_kpath('NPD') # wanted 'Document', got 'Draft'
puts Node.class_from_kpath('NPA') # wanted 'Draft', got nil

I understand that Draft's ksel method is not known at the time
Node.inherited is called.

How can I have Node.inherited being called once the complete child
class is built ?

Thanks for your answers.
Gaspard

2 Answers

Joel VanderWerf

9/14/2007 3:52:00 PM

0

Gaspard Bucher wrote:
> I need to identify classes from a string called kpath (class path)
> reflecting the class inheritance. The string is made of the first
> letter of each class. This is what I have now:

Defer building the hash until class_from_path is called.

One quick and dirty set of changes that does it:

> class Node
> @@classes = {'N' => self}

Replace:

> def self.inherited(child)
> super
> @@classes[child.kpath] = child
> end

With:

@@unhandled_children = []
def self.inherited(child)
super
@@unhandled_children << child
end


>
> def self.kpath
> self == Node ? ksel : (superclass.kpath + ksel)
> end
>
> def self.ksel
> self.to_s[0..0]
> end
>
> def self.class_from_kpath(kpath)

Add:

while child = @@unhandled_children.pop
@@classes[child.kpath] = child
end

> @@classes[kpath]
> end
> end
>
> class Page < Node
> end
>
> class Document < Page
> end
>
> class Draft < Page
> def self.ksel
> 'A'
> end
> end
>
> puts Node.class_from_kpath('N') # got 'Node', ok.
> puts Node.class_from_kpath('NPD') # wanted 'Document', got 'Draft'
> puts Node.class_from_kpath('NPA') # wanted 'Draft', got nil
>
> I understand that Draft's ksel method is not known at the time
> Node.inherited is called.
>
> How can I have Node.inherited being called once the complete child
> class is built ?
>
> Thanks for your answers.
> Gaspard


--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Gaspard Bucher

9/14/2007 5:55:00 PM

0

Thanks for the idea, that's a good workaround.

Gaspard

2007/9/14, Joel VanderWerf <vjoel@path.berkeley.edu>:
> Gaspard Bucher wrote:
> > I need to identify classes from a string called kpath (class path)
> > reflecting the class inheritance. The string is made of the first
> > letter of each class. This is what I have now:
>
> Defer building the hash until class_from_path is called.
>
> One quick and dirty set of changes that does it:
>
> > class Node
> > @@classes = {'N' => self}
>
> Replace:
>
> > def self.inherited(child)
> > super
> > @@classes[child.kpath] = child
> > end
>
> With:
>
> @@unhandled_children = []
> def self.inherited(child)
> super
> @@unhandled_children << child
> end
>
>
> >
> > def self.kpath
> > self == Node ? ksel : (superclass.kpath + ksel)
> > end
> >
> > def self.ksel
> > self.to_s[0..0]
> > end
> >
> > def self.class_from_kpath(kpath)
>
> Add:
>
> while child = @@unhandled_children.pop
> @@classes[child.kpath] = child
> end
>
> > @@classes[kpath]
> > end
> > end
> >
> > class Page < Node
> > end
> >
> > class Document < Page
> > end
> >
> > class Draft < Page
> > def self.ksel
> > 'A'
> > end
> > end
> >
> > puts Node.class_from_kpath('N') # got 'Node', ok.
> > puts Node.class_from_kpath('NPD') # wanted 'Document', got 'Draft'
> > puts Node.class_from_kpath('NPA') # wanted 'Draft', got nil
> >
> > I understand that Draft's ksel method is not known at the time
> > Node.inherited is called.
> >
> > How can I have Node.inherited being called once the complete child
> > class is built ?
> >
> > Thanks for your answers.
> > Gaspard
>
>
> --
> vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
>
>