Ada*_*Lee 15 ruby ruby-on-rails ruby-on-rails-4
我正在阅读一些使用Rails 4中的问题的代码.
我读了一些文章要说,如果我们想要使用模块包含类方法ClassMethods,但我使用类似的东西读取代码:
class_methods do
def ****
end
end
Run Code Online (Sandbox Code Playgroud)
max*_*max 10
ActiveSupport::Concern 为模块混合模块的常见Ruby模式提供语法糖。
当您使用模块作为mixins时,不能self像在类中那样声明类方法:
module Foo
def self.bar
"Hello World"
end
def instance_method
"Hello World"
end
end
class Baz
include Foo
end
Run Code Online (Sandbox Code Playgroud)
irb(main):010:0> Baz.bar
NoMethodError: undefined method `bar' for Baz:Class
from (irb):10
irb(main):011:0> Foo.bar
=> "Hello World"
irb(main):012:0>
Run Code Online (Sandbox Code Playgroud)
从示例中可以看到,实际上创建了一个模块方法-那是因为self是模块。您可以改用extend:
module Foo
def a_class_method
"Hello World"
end
end
class Bar
extend Foo
end
Run Code Online (Sandbox Code Playgroud)
irb(main):049:0> Bar.a_class_method
=> "Hello World"
Run Code Online (Sandbox Code Playgroud)
但这不允许您在模块中声明实例方法。真的没有那么有用。
因此解决方案是创建一个名为的内部模块,ClassMethods并在包含该模块时扩展该类:
module Foo
# this is a method thats called when you include the module in a class.
def self.included(base)
base.extend ClassMethods
end
def an_instance_method
end
# the name ClassMethods is just convention.
module ClassMethods
def a_class_method
"Hello World"
end
end
end
class Bar
include Foo
end
Run Code Online (Sandbox Code Playgroud)
irb(main):071:0> Bar.a_class_method
=> "Hello World"
Run Code Online (Sandbox Code Playgroud)
几乎每个红宝石宝石/图书馆都可以找到这种样板代码。
通过扩展模块,ActiveSupport::Concern您可以将其缩短为:
module Foo
extend ActiveSupport::Concern
class_methods do
def a_class_method
"Hello World"
end
end
end
Run Code Online (Sandbox Code Playgroud)
在后台ActiveSupport::Concern创建一个ClassMethods模块,并在(ClassMethods)模块的上下文中评估该块。如果您对它实际上是如何执行的感到好奇,请挖掘源代码。
这只是为了方便.module ClassMethods是纯Ruby,但为方便起见class_methods定义ActiveSupport::Concern.如果您查看源代码,您会发现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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5463 次 |
| 最近记录: |