我听说Ruby具有强大的反射和元编程能力。我想知道是否有办法显示我可以调用的类或对象的所有方法?
答案 0 :(得分:2)
几乎!
您可以在任何对象(包括类)上调用.methods
,以获取该对象上可用方法的列表。
但是,#method_missing
允许Ruby对象响应在该对象上实际定义的消息。可以找出特定方法名称对象是否响应该消息,但是不可能列出所有可以通过这种方式捕获的方法。
答案 1 :(得分:1)
如果您正在寻找班级实例的所有公共和受保护方法,那么您可以在课程本身上调用instance_methods
。
它还接受布尔值可选参数,默认设置为true。 True将列出您的类超类的所有实例方法,如果为false,它将仅返回您的类。
答案 2 :(得分:0)
一个例子通常很有帮助。在这里,我定义了两个类A
和B
,其中B
是A
的子类。 A
有一个公共类方法,一个公共实例方法和一个私有实例方法。
类B
有两个公共类方法,五个公共实例方法和两个私有实例方法。三个公共实例方法(..owners
)用于显示各种方法的所有者。此外,B
包含所有A
方法。重点将放在B
上。
我已经开始使用三个下划线的所有方法的名称,只是为了方便从Ruby返回的方法列表中提取它们。例如,B
有52个(类)方法,但名称以三个下划线开头的唯一方法在A
和B
中定义。
我认为你可以通过研究以下内容来学到很多东西。它不仅应该回答你的问题,而且会让你了解一些非常方便的Ruby方法,即:
class A
def ___aim_pub; end
def self.___acm_pub; end
private
def ___aim_pvt; end
end
class B < A
def self.___my_owners
(my methods).each { |m| puts "#{m} owner = #{method(m).owner}" }
end
def ___my_owners
(my methods).each { |m| puts "#{m} owner = #{method(m).owner}" }
end
def ___my_private_owners
(my self.class.private_instance_methods).each { |m|
puts "#{m} owner = #{method(m).owner}" }
end
def ___b1im_pub; end
def ___b2im_pub; end
def self.___b1cm_pub; end
def self.___b2cm_pub; end
private
def ___b1im_pvt; end
def ___b2im_pvt; end
end
辅助
def my(ms)
ms.select { |m| m.to_s[0,3] == '___' }
end
公共类方法
B.methods.size
#=> 103
my B.methods
#=> [:___my_owners, :___b1cm_pub, :___b2cm_pub, :___acm_pub]
B.methods false
#=> [:___my_owners, :___b1cm_pub, :___b2cm_pub]
B.___my_owners
# ___my_owners owner = #<Class:B>
# ___b1cm_pub owner = #<Class:B>
# ___b2cm_pub owner = #<Class:B>
# ___acm_pub owner = #<Class:A>
b = B.new
#=> #<B:0x000001028bbdb8>
公共实例方法
B.instance_methods.size
#=> 60
B.instance_methods == b.methods
#=> true
my B.instance_methods
#=> [:___my_owners, :___my_private_owners, :___b1im_pub,
# :___b2im_pub, :___aim_pub]
B.instance_methods false
#=> [:___my_owners, :___my_private_owners, :___b1im_pub, :___b2im_pub]
b.___my_owners
# ___my_owners owner = B
# ___my_private_owners owner = B
# ___b1im_pub owner = B
# ___b2im_pub owner = B
# ___aim_pub owner = A
私有实例方法
B.private_instance_methods.size
#=> 78
my B.private_instance_methods
#=> [:___b1im_pvt, :___b2im_pvt, :___aim_pvt]
B.private_instance_methods false
#=> [:___b1im_pvt, :___b2im_pvt]
b.___my_private_owners
# ___b1im_pvt owner = B
# ___b2im_pvt owner = B
# ___aim_pvt owner = A