【问题标题】:Value of self in a method defined on singleton class在单例类上定义的方法中的 self 值
【发布时间】:2014-04-24 14:37:04
【问题描述】:

为什么self,在一个单例类上定义的方法(singleton2),不等于其他三种情况下的那个单例类?

    class A
      def self.singleton1
        class << self
          self
        end
      end

      class << self
        def singleton2
          self
        end
      end
    end

    def singleton3
      class << A
        self
      end
    end

    p [A.singleton1, A.singleton1.object_id]           # [#<Class:A>, 70003841656620]
    p [A.singleton2, A.singleton2.object_id]           # [A, 70003841656640]
    p [singleton3, singleton3.object_id]               # [#<Class:A>, 70003841656620]
    p [A.singleton_class, A.singleton_class.object_id] # [#<Class:A>, 70003841656620]

【问题讨论】:

    标签: ruby singleton metaprogramming


    【解决方案1】:

    我会逐个解释。

     def self.singleton1
       class << self
         self
       end
     end
    

    这里,方法里面的selfA。现在在该方法中,您正在创建另一个范围,这是A 的单例类的范围,使用class &lt;&lt; self。当您调用A.singeton1 时,单例类的self 将被返回,因为A 的单例类中的self 是方法singleton1 的最后一条语句。

    class << self
      def singleton2
        self
      end
    end
    

    这里,A 的单例类主体内的self单例类本身。现在您在类A 上定义了一个单例方法singleton2。在方法内部,最后一个表达式是self,它总是会设置为receiver,这里是A。还有一点,def singleton2 新建了一个作用域,这个作用域不同于A 的单例类的作用域。

    按照上面的解释,我希望下面的代码输出一定对你很清楚:-

    class A
      def self.singleton1
        class << self
          self
        end
      end
    
      class << self
        def singleton2
          self
        end
      end
    end
    
    A.singleton2 # => A 
    A.singleton1 # => #<Class:A>
    

    输出 A#&lt;Class:A&gt; 清楚地说明为什么 object_ids 不同。

    从上面2个解释中,singleton3的情况就一目了然了。

    【讨论】:

      猜你喜欢
      • 2018-06-28
      • 2019-01-14
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多