Ruby: 单例类真的是自己的匿名类吗?
Ruby: Are singleton classes really own anonymous classes?
在Programming Ruby 1.9 & 2.0一书的24.2 Singletons一章中,给出了以下代码:
animal = "cat"
def animal.speak
puts "The #{self} says miaow"
end
并解释为:"When we defined the singleton method for the "cat" 对象,Ruby 创建了一个新的匿名 class 并定义了 class 中的 speak 方法。这个匿名 class 称为 单例 class(有时 本征class)."
不幸的是,我无法验证 Ruby (2.5.1) 实际上创建了自己的匿名 class:
str = "a string" # => "a string"
[str, str.object_id] # => ["a string", 47279316765840]
[str.class, str.class.object_id] # => [String, 47279301115420]
def str.greet
"hello"
end # => :greet
str.greet # => "hello"
[str, str.object_id] # => ["a string", 47279316765840]
[str.class, str.class.object_id] # => [String, 47279301115420]
从上面可以看出,str的class在定义单例方法greet后并没有改变:它仍然显示为 String 与相同的 object_id 47279301115420.
那么,匿名 class 在哪里?
str = "a string" # => "a string"
[str, str.object_id] # => ["a string", 47279316765840]
[str.class, str.class.object_id] # => [String, 47279301115420]
def str.greet
"hello"
end # => :greet
str.greet # => "hello"
当您询问 str.class
或查看祖先链 (str.class.ancestors
) 时,Ruby 隐藏了 eigenclass。但是,您可以通过在使用 <<
检查 class 后返回 self 来获取对 eigenclass 的引用
str_class = class << str
self
end
# => #<Class:#<String:0x007fbba28b3f20>>
str_class.instance_methods(false) #=> [:greet] # the singleton method you defined becomes the instance method of this eigenclass. :)
str_class.ancestors
[#<Class:#<String:0x007fbba28b3f20>>, String, Comparable, Object, Kernel, BasicObject]
在Programming Ruby 1.9 & 2.0一书的24.2 Singletons一章中,给出了以下代码:
animal = "cat"
def animal.speak
puts "The #{self} says miaow"
end
并解释为:"When we defined the singleton method for the "cat" 对象,Ruby 创建了一个新的匿名 class 并定义了 class 中的 speak 方法。这个匿名 class 称为 单例 class(有时 本征class)."
不幸的是,我无法验证 Ruby (2.5.1) 实际上创建了自己的匿名 class:
str = "a string" # => "a string"
[str, str.object_id] # => ["a string", 47279316765840]
[str.class, str.class.object_id] # => [String, 47279301115420]
def str.greet
"hello"
end # => :greet
str.greet # => "hello"
[str, str.object_id] # => ["a string", 47279316765840]
[str.class, str.class.object_id] # => [String, 47279301115420]
从上面可以看出,str的class在定义单例方法greet后并没有改变:它仍然显示为 String 与相同的 object_id 47279301115420.
那么,匿名 class 在哪里?
str = "a string" # => "a string"
[str, str.object_id] # => ["a string", 47279316765840]
[str.class, str.class.object_id] # => [String, 47279301115420]
def str.greet
"hello"
end # => :greet
str.greet # => "hello"
当您询问 str.class
或查看祖先链 (str.class.ancestors
) 时,Ruby 隐藏了 eigenclass。但是,您可以通过在使用 <<
str_class = class << str
self
end
# => #<Class:#<String:0x007fbba28b3f20>>
str_class.instance_methods(false) #=> [:greet] # the singleton method you defined becomes the instance method of this eigenclass. :)
str_class.ancestors
[#<Class:#<String:0x007fbba28b3f20>>, String, Comparable, Object, Kernel, BasicObject]