Ruby单例类

时间:2011-09-27 17:41:21

标签: ruby singleton-methods

我不确定这与之间的区别。

def String.hello  
  puts "hello there"   
end

x = Person.new    
def x.hello    
  puts "hello there"    
end

根据我的理解,第二个代码块将创建Person类的对象。当我执行 def x.hello 时,它会创建一个匿名类(单例类),在向 x 对象发送消息时,将首先检查方法。

def String.hello 的情况是否相同? String只是类Class的实例正确吗?我已经读过,做 def String.hello 会将方法添加为String的类方法之一....这与创建的匿名类不同,它位于对象及其类之间它获取其实例方法。

上面的两个代码块会发生什么?

3 个答案:

答案 0 :(得分:6)

我喜欢红宝石的这一部分。有这种美丽的对称性,其中大多数核心功能只是高级功能的糖,所以一旦你完全理解了一个概念,你就可以将这种理解应用到很多语言中。

  
    

def String.hello的情况是否相同? String只是类Class的实例正确吗?

  

是的,您正在创建Class的实例,并将其分配给常量。

  
    

我已经读过,做def String.hello会将方法添加为String的类方法之一....这与创建的匿名类不同,后者位于对象及其类之间,它获取其实例方法

  

不,你丢失的那篇文章认为有可能有一个类级方法而不将它添加到单例类中。你所拥有的是一个对象,它是一个Class的实例,你将方法添加到位于它和Class之间的隐式类。您有时也会看到这种语法

class << self
  def method
  end
end

这是做同样的事情,只是非常明确。

答案 1 :(得分:2)

只是为了补充Matt的答案:

两个例子都做同样的事情,用另一种方式写出来:

String = Class.new # < done inside ruby initialization    
def String.hello    
  puts "hello there"    
end

x = Person.new    
def x.hello    
  puts "hello there"    
end

在Ruby上,您可以向使用A = Class.new或使用语法sugar class A; ...; end创建的类或者为每个对象存在的Eigenclass添加方法。实际上,类方法是类实例的本征类的方法,考虑def self.method; ...; end中的“自我”。可以用这个sintax打开本征类:

x = Person.new
class << x
  # ...
end

由于Eigenclasses也是类的实例(尝试在最后一个例子中添加p self.class)它们也有Eigenclasses等等。如果它看起来令人困惑,请记住Object是一个类,而Class是一个对象。这就是我爱Ruby的原因!

答案 2 :(得分:0)

以下代码将“hello”方法添加到String类中,这样所有后续字符串都将具有“hello”方法:

def String.hello  
   puts "hello there"   
end

虽然下面的代码会将“hello”方法添加到Person类的实例 x中。如果您创建一个新Person,该对象将没有“hello”方法。

x = Person.new    
def x.hello    
  puts "hello there"    
end

正如我所理解的那样,这是主要的区别。

这有帮助吗?