具有来自包含器类的静态方法调用的 Ruby 模块

发布于 2024-07-25 18:09:07 字数 278 浏览 6 评论 0原文

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

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

但是编译器在第四行给出错误。

还有其他方法来定义常数吗?

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

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

Is there any other way to define the constant?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

白云悠悠 2024-08-01 18:09:07

在 Ruby 中实现此目的更惯用的方法是:

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 的 metaclass 的上下文中,而不是 A 本身。 find 方法位于 A 本身,而不是其元类。 要记住的是,类本身就是对象,因此有自己的元类。

尝试使其更清楚:

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 习惯用法。

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

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.

To try to make it clearer:

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

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

潦草背影 2024-08-01 18:09:07

根据你的具体情况。

module B 
  def self.included(base)
    base.const_set("CONST", base.find)
  end
end 

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

puts A::CONST

尽管它有效,但有点混乱。 您确定不能采用不同的方式来实现您的目标吗?

In your specific case.

module B 
  def self.included(base)
    base.const_set("CONST", base.find)
  end
end 

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

puts A::CONST

Despite it works, it's a little bit messy. Are you sure you can't follow a different way to achieve your goal?

仲春光 2024-08-01 18:09:07
module B 
  def self.included(base)
    class << base
      CONST = self.find
    end
  end
end 

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

然后编译器错误已修复,请尝试。

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

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

then the compiler error is fixed, pls try.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文