Ruby模块,带有来自includer类的静态方法调用 [英] Ruby module with a static method call from includer class

查看:136
本文介绍了Ruby模块,带有来自includer类的静态方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在模块中定义使用包含此模块的类中的方法的常量:

I need to define the constant in the module that use the method from the class that includes this module:

module B 
  def self.included(base)
    class << base
  CONST = self.find
    end
  end
end 

class A
  def self.find
    "AAA"
  end
  include B 
end

puts A::CONST

但编译器会在第4行给出错误。

But the compiler gives the error on the 4th line.

还有其他方法可以定义常量吗?

Is there any other way to define the constant?

推荐答案

在Ruby中实现这一目标的更为惯用的方法是:

The more idiomatic way to achieve this in Ruby is:

module B 
  def self.included(klass)
    klass.class_eval <<-ruby_eval
      CONST = find
    ruby_eval

    # note that the block form of class_eval won't work
    # because you can't assign a constant inside a method
  end
end

class A
  def self.find
    "AAA"
  end
  include B 
end

puts A::CONST

你在做什么(class<< base)实际上会让你进入A的元类的上下文,而不是A本身。 find 方法是在A本身,而不是它的元类。要记住的是,类本身就是对象,因此有自己的元类。

What you were doing (class << base) actually puts you into the context of A's metaclass, not A itself. The find method is on A itself, not its metaclass. The thing to keep in mind is that classes are themselves objects, and so have their own metaclasses.

试图让它更清晰:

class Human
  def parent
    # this method is on the Human class and available
    # to all instances of Human.
  end

  class << self
    def build
      # this method is on the Human metaclass, and
      # available to its instance, Human itself.
    end

    # the "self" here is Human's metaclass, so build
    # cannot be called.
  end

  def self.build
    # exactly the same as the above
  end

  build # the "self" here is Human itself, so build can
        # be called
end

不确定是否有帮助,但是如果你不理解它,你仍然可以使用上面的class_eval成语。

Not sure if that helps, but if you don't understand it, you can still use the class_eval idiom above.

这篇关于Ruby模块,带有来自includer类的静态方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆