我试图为给定的类创建一个包含所有超类的数组。我试图通过使用循环来解决这个问题。为什么这不起作用?
class Object
def superclasses
array = []
klass = self.superclass
unless klass == nil
array << klass
klass = klass.superclass
end
array
end
end
class Bar
end
class Foo < Bar
end
p Foo.superclasses # should be [Bar, Object, BasicObject]
答案 0 :(得分:3)
unless
不是循环。您正在寻找的是until
:
class Object
def superclasses
array = []
klass = self.superclass
until klass == nil
array << klass
klass = klass.superclass
end
array
end
end
class Bar
end
class Foo < Bar
end
p Foo.superclasses # Prints "[Bar, Object, BasicObject]"
此外,您不需要新的方法。已经有一种名为Module#ancestors
的方法基本上可以满足您的需求:
class Bar
end
class Foo < Bar
end
p Foo.ancestors # Prints "[Foo, Bar, Object, Kernel, BasicObject]"
请注意,ancestors
的返回值包括Foo
本身,以及已包含在继承链中的模块,如Kernel
。如果您不想要,可以像这样定义superclasses
:
class Module
def superclasses
ancestors[1..-1].select{|mod| mod.is_a? Class }
end
end
class Bar
end
class Foo < Bar
end
p Foo.superclasses # Prints "[Bar, Object, BasicObject]"
答案 1 :(得分:3)
你需要一个循环来继续查找超类:
def superclasses
array = []
klass = self.superclass
while klass
array << klass
klass = klass.superclass
end
array
end
我觉得使用递归看起来好一点
def superclasses
return [] if superclass.nil?
[superclass].concat superclass.superclasses
end
确实应该在Class
中定义此方法,因为不是每个Object
都会响应superclass
。
Ruby的内置方式是Module#ancestors
。但它并不完全相同,因为它也考虑了包含的模块。然而,内置方式是执行此操作的正确方法,因为严格的超类链并不能真正为您提供Ruby中的全貌。
答案 2 :(得分:0)
获得超类的另一种方法
class Object
def superclasses
ObjectSpace.each_object(Class).select { |klass| klass < self }
end
end