我正在学习Ruby Singletons,我找到了一些方法来定义和获取Class和Object单例方法的列表。
定义类单例方法的方法:
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
获取班级单身人士方法列表的方法:
#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)
还有其他方法吗?
答案 0 :(得分:13)
首先,列出单例方法的方法是使用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)
在这种情况下不返回任何内容。阅读完C代码之后,似乎:
methods
返回该对象可用的所有方法(也包括所包含模块中的方法)singleton_methods
返回对象的所有单例方法(也包括所包含模块中的方法)(documentation)singleton_methods(false)
返回对象的所有单例方法,但不在包含的模块中声明的方法methods(false)
假设通过调用singleton_methods
,但返回单例方法,它还会将参数false
传递给它;这是一个错误还是一个功能 - 我不知道希望这可以澄清一下这个问题。底线:致电singleton_methods
,似乎更可靠。
答案 1 :(得分:6)
更多方法:
班级单身人士方法
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
...
我想有无数种方法:)
答案 2 :(得分:1)
对象单例方法
instance_eval的
class A
end
a = A.new
a.instance_eval do
def v
"asd"
end
end
a.singleton_methods
=> [:z, :v]