ruby class_methods在concern中有什么作用?

vmjh9lq9  于 2022-12-03  发布在  Ruby
关注(0)|答案(3)|浏览(113)

我正在阅读一些使用Rails 4中的关注点的代码。
我读到一些文章说,如果我们想包含类方法,就使用模块ClassMethods,但我读到的代码使用了类似这样的东西:

class_methods do
  def **** 
  end
end
mspsb9vt

mspsb9vt1#

ActiveSupport::Concern为模块mixin的常见Ruby模式提供了语法糖。
在使用modules as mixins时,不能像在类中那样使用self来声明类方法:
第一个
从这个例子中你可以看到,它实际上创建了一个模块方法--这是因为self是模块。你可以使用extend来代替:
第一次
但是这并不允许你在模块中声明示例方法,这并不是真的那么有用。
因此,解决方案是创建一个内部模块(通常命名为ClassMethods),并在包含该模块时扩展类:
第一个
几乎在每个Ruby gem/库中都可以找到此样板代码。
通过使用ActiveSupport::Concern扩展您的模块,您可以将其缩短为:

module Foo
  extend ActiveSupport::Concern
  class_methods do
    def a_class_method
      "Hello World"
    end
  end
end

ActiveSupport::Concern创建了一个ClassMethods模块,并在该模块的上下文中对该块求值。如果你想知道它实际上是如何做到这一点的,请深入研究源代码。

mqxuamgl

mqxuamgl2#

这只是为了方便。module ClassMethods是纯Ruby,但是为了方便,class_methods是在ActiveSupport::Concern中定义的。

# activesupport/lib/concern.rb
  def class_methods(&class_methods_module_definition)
    mod = const_defined?(:ClassMethods, false) ?
      const_get(:ClassMethods) :
      const_set(:ClassMethods, Module.new)

    mod.module_eval(&class_methods_module_definition)
  end
w8biq8rn

w8biq8rn3#

class_methods用于将类方法添加到关注点使用的模型中。
典型的模块如下所示:

module M
  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    ...
  end
end

通过使用ActiveSupport::Concern,上面的模块可以写成:

require 'active_support/concern'

module M
  extend ActiveSupport::Concern

  class_methods do
    ...
  end
end

作为Oleg Antonyan pointed out,从源代码中,我们知道它将在幕后使用ClassMethods模块。
参考:http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

相关问题