我将一些模块包含并扩展到我的课程中。
我将binding.pry放入其中。使用self.methods列出我拥有的所有方法。
但是列表太长了,我怎么才能在我包含的模块中列出方法。除了我的self.class中的方法和来自inspect
to_s
之类的祖先的方法,...
include SnapshotsHelper
extend SnapshotsHelper
谢谢
答案 0 :(得分:2)
我认为您正在寻找以下内容:
module A
def meth1;end
def meth2;end
end
module B
def meth11;end
def meth21;end
end
class C
include A,B
end
list = C.included_modules.each_with_object({}) do |m,ob|
module_arry = m.instance_methods
ob[m]=C.instance_methods.select{|e| module_arry.include?(e)} if m != Kernel
end
p list
# >> {A=>[:meth1, :meth2], B=>[:meth11, :meth21]}
module A
def meth1;end
def meth2;end
end
module B
def meth11;end
def meth21;end
end
class C
extend A,B
end
list = C.singleton_class.included_modules.each_with_object({}) do |m,ob|
module_arry = m.instance_methods
class_methods = C.methods - C.instance_methods
ob[m]= class_methods.select{|e| module_arry.include?(e)} if m != Kernel
end
p list
# >> {A=>[:meth1, :meth2], B=>[:meth11, :meth21]}
答案 1 :(得分:1)
我想你只想要你所在的孩子中包含的模块中的方法,从父母中包含的模块中过滤掉方法。如果你也想要父母提供的模块,那么@Arup的答案就是好的。
没有提供您想要的核心方法,但如果您经常需要,可以创建一个。
给定类有三种方法来源:
来自模块的方法可以插入类本身或父类中(或者甚至通过模块中的钩子插入,但让我们把它放在一边)。
另请注意,Class继承自Module,因此Class是一个Module。
现在,拥有所有这些,您要做的是将所有模块包含在当前类中,删除父模块并获取方法。因此基本公式是:
methods_from_module_included_in_current_class = ( modules_in_class - modules_in_parent ).methods
要在课堂上获取所有模块,您可以使用#ancestors
方法。它将列出已在当前类中混合的所有类和模块(请记住:类只是一个模块)。
modules_in_class = MyClass.ancestors.reject { |ancestor| Class === ancestor }
在这里,我们拒绝列表中的类(Class === ancestor
与执行ancestor.is_a? Class
相同),因此我们知道我们只有模块。同样,我们不能只选择模块,因为Class是Module。
最后,我们可以应用相同的模式从父级获取模块:
module_in_parent = MyClass.superclass.ancestors.reject { |ancestor| Class === ancestor }
因此,要从当前类中包含的模块中获取所有方法:
( MyClass.ancestors.reject { |ancestor| Class === ancestor } - MyClass.superclass.ancestors.reject { |ancestor| Class === ancestor } ).map( &:instance_methods ).flatten
要获取类方法(因此使用#extend
添加方法),请将instance_methods
替换为methods
。
注意,如果在类初始化时声明了一些匿名模块,那么你可能仍然有一些不熟悉的方法,就像在ActiveRecord :: Base上的rails一样。
如果您经常使用此功能,可以使用方法对其进行分解:
class Object
def inner_module_methods
( self.class.ancestors.reject { |ancestor| Class === ancestor } - self.class.superclass.ancestors.reject { |ancestor| Class === ancestor } ).map( &:instance_methods ).flatten
end
end
您现在可以:
obj.inner_module_methods
或撬内:
inner_module_methods
您可能还想要filter methods by source file。从长远来看,如果发现这种情况更有效,更不稳定。