3

我不确定这之间的区别。

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 的类方法之一……这与创建的匿名类不同,该类位于对象与其获取实例方法的类之间。

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

4

3 回答 3

6

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

def String.hello 的情况是否相同?String 只是类 Class 的一个实例,对吗?

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

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

不,您缺少的部分是认为可以拥有一个类级别的方法,而无需将其添加到单例类中。您拥有的是一个作为 Class 实例的对象,并且您正在向位于它和 Class 之间的隐式类添加方法。您有时还会看到这种语法

class << self
  def method
  end
end

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

于 2011-09-27T17:50:30.220 回答
2

只是为了补充马特的答案:

这两个例子都做同样的事情,以另一种方式编写它们:

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

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

A = Class.new在 Ruby 上,您可以将方法添加到使用或使用语法糖创建的类,或者添加class A; ...; end到每个对象都存在的 Eigenclass 中。类方法实际上是 Class 实例的 Eigenclass 的方法,想想def self.method; ...; end. 可以使用以下 sintax 打开特征类:

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

由于 Eigenclasses 也是类的实例(尝试添加p self.class最后一个示例),它们也有 Eigenclasses 等等。如果它看起来令人困惑,请记住它Object是一个类并且Class是一个对象。这就是我喜欢鲁比的原因!

于 2011-09-27T18:07:43.810 回答
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

据我了解,这是主要区别。

这有帮助吗?

于 2011-09-27T17:50:17.940 回答