【问题标题】:How to access to ghost parent classes in ruby?如何在 ruby​​ 中访问幽灵父类?
【发布时间】:2010-11-27 04:54:57
【问题描述】:

我正在观看 prag dave 的第一个 ruby​​ 元编程截屏视频。在某些时候,他说当您向实例变量添加方法时,ruby 会引入“鬼类”。 i.

animal = "cat"
def animal.speak
  puts "hola"
end
animal.speak       # => hola
animal.class       # => String

dog = "dog"

dog.speak          # Undefined method `speak' for "dog":String
String.send :speak # NoMethodError: undefined method `speak' for String:Class
animal.send :speak # hola

speak 方法存储在哪里? 如果是不可见的代理类,我们如何访问该代理类?

【问题讨论】:

    标签: ruby oop class


    【解决方案1】:

    方法speak 存储在元类(也称为特征类)中,您称之为“不可见的代理类”。在 Ruby 中,实例变量没有地方存储方法。它们只能存储实例变量及其类。因此,当您向实例添加方法时,会创建一个元类并将其插入其类链中。为了更好地了解内部结构,我推荐来自 Klank Boom Klang 的this article

    为了获得元类,您可以执行以下操作:

    animal = "cat"
    def animal.speak
      puts "hola"
    end
    animal.speak       # => hola
    animal.class       # => String
    
    metaclass = class << animal; self; end
    
    metaclass.inspect                        # => #<Class:#<String:0x2c9c460>>
    metaclass.instance_methods.index 'speak' # => 102
    metaclass.class                          # => Class
    

    【讨论】:

      【解决方案2】:

      有些人称之为“单例类”

      singleton_class = class << animal; self; end
      

      实际上这个单例类是任何类的类方法的宿主,检查这个例子,首先用类方法'hi'和'bye'定义类Foo:

      class Foo
        def self.hi ; p "hi" ; end
        def self.bye ; p "bye" ; end
      end
      Foo.singleton_methods #=> ["hi","bye"]
      

      现在让我们定义一个为我们返回单例类的方法:

      class Object
        def singleton_class 
           class << self
             self
           end
        end
      end
      

      现在试试这个:

      Foo.singleton_methods #=> ["bye", "hi"]
      Foo.singleton_class.instance_methods(false) #=> ["bye", "hi"]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-19
        • 2018-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多