如果我有4个具有以下层次结构的类:
class MainClass < ActiveRecord::Base
...
end
class SubClassA < MainClass
...
end
class SubClassB < MainClass
...
end
class SubClassC < MainClass
...
end
如何在不经过并创建其他每个类的实例的情况下获取MainClass的子类列表?
在新的IRB会议中,我可以进去说
irb(main)> MainClass.descendants
=> []
但是,如果我经历并创建每个子类的实例,我将看到以下
irb(main)> SubClassA.new
=> #<SubClassA ...>
irb(main)> SubClassB.new
=> #<SubClassB ...>
irb(main)> SubClassC.new
=> #<SubClassC ...>
irb(main)> MainClass.descendants
=> [SubClassA(...), SubClassB(...), SubClassC(...)]
我基本上都在寻找一种方法来编程提供所有子类,以便将来当我想添加SubClassD,SubClassE等时,我不必担心每个人都在用户之前的代码中实例化可以看到他们。
答案 0 :(得分:9)
这是一个开发模式的假象,只在第一次引用时加载类:那些文件还没有被解释器读取 - 就ruby而言,这些类真的还不存在
解决方法是放
/** Servlet implementation class FetchTest */
@WebServlet( urlPatterns = {"/users", "/Users/"})
public class Users extends HttpServlet
{
/** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */
protected void doGet( HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException
{
m_showUsers( response);
}
/** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */
protected void doPost( HttpServletRequest request , HttpServletResponse response ) throws ServletException , IOException
{
m_updateUser(request , response);
}
@Override
protected void doDelete( HttpServletRequest req , HttpServletResponse resp ) throws ServletException , IOException
{
m_deleteUser(req , resp);
}
@Override
protected void doPut( HttpServletRequest req , HttpServletResponse resp ) throws ServletException , IOException
{
m_insertUser(req , resp);
}
在主要类的文件底部(类定义之外)
答案 1 :(得分:8)
有几种方法可以实现这一目标。通过使用诸如descendants_tracker:
之类的宝石class MainClass < ActiveRecord::Base
extend DescendantsTracker
end
class SubClassA < MainClass
end
...
MainClass.descendants # => [SubClassA]
或者您可以在父类中创建自定义的内容,例如this:
class MainClass < ActiveRecord::Base
def self.descendants
ObjectSpace.each_object(Class).select { |klass| klass < self }
end
end
class SubClassA < MainClass
end
class SubClassB < MainClass
end
puts MainClass.descendants
#=> SubClassA
SubClassB
您还可以检查依赖关系的级别。如果你想要一个MainClass直接子节点的数组,例如你可以使用.subclasses
类方法
MainClass.subclasses # => [SubClassA, SubClassB,...]
现在,如果您想要多个级别的子类,请使用.descendants
。您可以找到示例here
答案 2 :(得分:0)
您可以使用ObjectSpace#each_object来编制 back = re.compile("'\\\\'")
print back.findall(line)
个孩子的列表:
假设:
MainClass
class MainClass ; end
class SubClassA < MainClass; end
class SubClassB < MainClass; end
class SubClassC < SubClassB; end
可能是一个子类的事实是无关紧要的。
MainClass