在“class<< self”定义中缺少常量和“const_missing”

时间:2011-03-14 20:35:23

标签: ruby jruby

const_missing定义中定义class << self和其他类方法而不是使用def self.foo语法时,我对Ruby的行为感到非常困惑。

我试图做这样的事情:

class Foo
  class << self
    def foo
      puts MISSING
    end

    def const_missing(name)
      puts "#{name} missing"
    end
  end
end

Foo.foo

我主要使用class << self语法来定义类方法。但是,它没有按预期工作。永远不会调用const_missing。以上结果是NameError。

定义这样的两种方法按预期工作:

def self.foo
  puts MISSING
end

def self.const_missing(name)
  puts "#{name} missing"
end

我认为class << self语法只是定义类方法的另一种方法,但完全等同于def self.foo?我用MRI 1.8.7,1.9.2和JRuby 1.5.6测试了上述内容。所以很明显我在这里错过了什么?

非常感谢任何提示。

谢谢,马丁

1 个答案:

答案 0 :(得分:12)

class << self不是定义类方法的快捷方式。这种语法(我不知道确切的命名)打开了一个对象(在你的例子中是一个类)的本征类。有了它,您可以定义对象的方法(而不是实例方法)。但是当你将一个常量调用到本征类时,你从本征类调用一个常量,而不是从类中调用一个常量。在这种情况下,你必须在const_missing的本征类上定义一个类方法,有两种方法:

class Test
  class << self
    def foo
      p MISSING
    end

    # First way: (syntax sugar for the second way)
    def self.const_missing(name)
      name
    end

    # Second way:
    class << self # eigenclass of the eigenclass of the class
      def const_missing(name)
        name
      end
    end

  end
end

Test.foo #=> :MISSING