【问题标题】:Ruby singleton classRuby 单例类
【发布时间】:2011-11-26 06:26:24
【问题描述】:

我不确定这之间的区别。

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

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

【问题讨论】:

    标签: ruby singleton-methods


    【解决方案1】:

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

    def String.hello  
       puts "hello there"   
    end
    

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

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

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

    这有帮助吗?

    【讨论】:

    • 不正确,尝试在irb中做你的第一个例子,然后做"".hello,你会发现你得到一个方法未找到错误
    • 你是对的,那么第一块代码基本上什么都不做?
    • 第一个块在功能上等同于执行 "class String; def self.hello; puts "hello there"; end; end;"
    【解决方案2】:

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

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

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

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

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

    class << self
      def method
      end
    end
    

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

    【讨论】:

    • 啊...有趣的事情让你头晕目眩。所以类方法是指向类Class实例的常量上的单例方法。对吗?
    【解决方案3】:

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

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

    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 或语法糖 class A; ...; end 创建的类,或添加到每个对象都存在的 Eigenclass 中。类方法实际上是类实例的 Eigenclass 的方法,想想def self.method; ...; end 中的“自我”是什么。可以用这个 sintax 打开特征类:

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

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

    【讨论】:

      猜你喜欢
      • 2018-12-10
      • 2020-08-05
      • 1970-01-01
      • 1970-01-01
      • 2010-09-17
      • 2014-09-03
      • 1970-01-01
      • 1970-01-01
      • 2013-02-22
      相关资源
      最近更新 更多