用于类和对象的Ruby Singleton方法
我正在学习Ruby Singletons,我找到了一些方法来定义和获取Class和Object单例方法的列表。
类Singleton方法
定义类单例方法的方法:
class MyClass def MyClass.first_sing_method 'first' end def self.second_sing_method 'second' end class << self def third_sing_method 'third' end end class << MyClass def fourth_sing_method 'fourth' end end end def MyClass.fifth_sing_method 'fifth' end MyClass.define_singleton_method(:sixth_sing_method) do 'sixth' end
获取class级单身人士方法列表的方法:
#get singleton methods list for class and it's ancestors MyClass.singleton_methods #get singleton methods list for current class only MyClass.methods(false)
对象单例方法
定义对象单例方法的方法
class MyClass end obj = MyClass.new class << obj def first_sing_method 'first' end end def obj.second_sing_method 'second' end obj.define_singleton_method(:third_sing_method) do 'third' end
获取对象单例方法列表的方法
#get singleton methods list for object and it's ancestors obj.singleton_methods #get singleton methods list for current object only obj.methods(false)
还有其他方法吗?
首先,列出单例方法的方法是使用singleton_methods
。 methods
方法返回对象的公共和受保护方法的名称列表。 此外,它在Object
类中定义。 尝试extend
实例。 它是最优雅的方式之一,因为它支持代码重用,在我看来非常面向对象:
class Foo def bar puts "Hi" end end module Bar def foo puts "Bye" end end f = Foo.new f.bar #=> hi f.extend Bar f.foo #=> bye f.methods(false) #=> [] # the module we extended from is not a superclass # therefore, this must be empty, as expected f.singleton_methods #=> ["foo"] # this lists the singleton method correctly g = Foo.new g.foo #=> NoMethodError
编辑 :在评论中你问为什么methods(false)
在这种情况下methods(false)
返回任何内容。 阅读完C代码后,似乎:
-
methods
返回对象可用的所有方法(也包括所包含模块中的方法) -
singleton_methods
返回对象的所有单例方法(也包括所包含模块中的方法)( 文档 ) -
singleton_methods(false)
返回对象的所有单例方法,但不返回包含模块中声明的方法 -
methods(false)
假设通过调用singleton_methods
返回单例方法, 但它也将参数false
传递给它; 这是一个错误还是一个function – 我不知道
希望这有点澄清了这个问题。 底线:调用singleton_methods
,似乎更可靠。
更多方法:
类单例方法
class << MyClass define_method :sixth_sing_method do puts "sixth" end end class MyClass class << self define_method :fourth_sing_method do puts "seventh" end end end
对象单例方法
class << obj define_method :fourth_sing_method do puts "fourth" end end
接下来,您可以将define_method
和define_singleton_method
与send
结合使用,例如
obj.send :define_singleton_method, :nth_sing_method, lambda{ puts "nth" }
及其所有可能的组合。 要使用define_method
,您需要首先捕获单例类(对于类对象也是如此)
singleton_class = class << obj; self end singleton_class.send :define_method, :nth_sing_method, lambda{ puts "nth" }
另一种方法是在单例类对象上使用class_eval
:
singleton_class.class_eval do def nth_sing_method puts "nth" end end
然后你再次将send
与class_eval
结合起来......
我想有无数的方法:)
对象单例方法
instance_eval的
class A end a = A.new a.instance_eval do def v "asd" end end a.singleton_methods => [:z, :v]