我正在阅读一些使用Rails 4中的关注点的代码。我读到一些文章说,如果我们想包含类方法,就使用模块ClassMethods,但我读到的代码使用了类似这样的东西:
ClassMethods
class_methods do def **** end end
mspsb9vt1#
ActiveSupport::Concern为模块mixin的常见Ruby模式提供了语法糖。在使用modules as mixins时,不能像在类中那样使用self来声明类方法:第一个从这个例子中你可以看到,它实际上创建了一个模块方法--这是因为self是模块。你可以使用extend来代替:第一次但是这并不允许你在模块中声明示例方法,这并不是真的那么有用。因此,解决方案是创建一个内部模块(通常命名为ClassMethods),并在包含该模块时扩展类:第一个几乎在每个Ruby gem/库中都可以找到此样板代码。通过使用ActiveSupport::Concern扩展您的模块,您可以将其缩短为:
ActiveSupport::Concern
self
module Foo extend ActiveSupport::Concern class_methods do def a_class_method "Hello World" end end end
ActiveSupport::Concern创建了一个ClassMethods模块,并在该模块的上下文中对该块求值。如果你想知道它实际上是如何做到这一点的,请深入研究源代码。
mqxuamgl2#
这只是为了方便。module ClassMethods是纯Ruby,但是为了方便,class_methods是在ActiveSupport::Concern中定义的。
module ClassMethods
class_methods
# 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
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
3条答案
按热度按时间mspsb9vt1#
ActiveSupport::Concern
为模块mixin的常见Ruby模式提供了语法糖。在使用modules as mixins时,不能像在类中那样使用
self
来声明类方法:第一个
从这个例子中你可以看到,它实际上创建了一个模块方法--这是因为
self
是模块。你可以使用extend来代替:第一次
但是这并不允许你在模块中声明示例方法,这并不是真的那么有用。
因此,解决方案是创建一个内部模块(通常命名为
ClassMethods
),并在包含该模块时扩展类:第一个
几乎在每个Ruby gem/库中都可以找到此样板代码。
通过使用
ActiveSupport::Concern
扩展您的模块,您可以将其缩短为:ActiveSupport::Concern
创建了一个ClassMethods
模块,并在该模块的上下文中对该块求值。如果你想知道它实际上是如何做到这一点的,请深入研究源代码。mqxuamgl2#
这只是为了方便。
module ClassMethods
是纯Ruby,但是为了方便,class_methods
是在ActiveSupport::Concern
中定义的。w8biq8rn3#
class_methods
用于将类方法添加到关注点使用的模型中。典型的模块如下所示:
通过使用
ActiveSupport::Concern
,上面的模块可以写成:作为Oleg Antonyan pointed out,从源代码中,我们知道它将在幕后使用
ClassMethods
模块。参考:http://api.rubyonrails.org/classes/ActiveSupport/Concern.html