Race condition in class inheritance

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

Gaspard B. 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

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

Gaspard

2007/9/14, Joel VanderWerf [email protected]: