ruby-on-rails - 什么是 Ruby module.included?
问题描述
我试图更好地理解 Ruby 中的元编程,但对什么Module.included
是元编程感到困惑?我目前的理解是,当模块被包含到另一个模块或类中时,这是 Ruby 调用的回调。除此之外,这些用于哪些类型的(元)编程结构?有什么例子吗?
解决方案
Module#included
允许模块从单个包含注入类和实例方法,并执行相关代码。
ActiveSupport::Concern的文档说明了一个典型的用法。它将类方法注入调用类,并执行代码。在这种情况下,添加一个范围。
module M
def self.included(base)
base.extend ClassMethods
base.class_eval do
scope :disabled, -> { where(disabled: true) }
end
end
module ClassMethods
...
end
end
这是 ActiveSupport::Concern 版本,它做同样的事情,但添加了声明性语法糖。
require 'active_support/concern'
module M
extend ActiveSupport::Concern
included do
scope :disabled, -> { where(disabled: true) }
end
class_methods do
...
end
end
included
一个类只包含模块。它允许模块成为一个简洁的包:实例方法、类方法和设置代码。
class Thing
# Class and instance methods are injected, and the new scope is added.
include M
end
没有included
模块只能注入实例方法。必须单独添加类方法,以及执行任何设置代码。
module M
def some_instance_method
...
end
module ClassMethods
def setup
scope :disabled, -> { where(disabled: true) }
end
end
end
class Thing
# Inject the instance methods
include M
# Inject the class methods
extend M::ClassMethods
# Run any setup code.
setup
end
其他示例可能是注册一个类,例如作为可用插件。
class Plugin
def self.included(base)
base.extend ClassMethods
bass.class_eval do
register_as_plugin(base)
end
end
module ClassMethods
def register_as_plugin(klass)
...
end
end
end
class Thing
include Plugin
end
或添加必要的访问器。
class HasLogger
def self.included(base)
bass.class_eval do
attr_writer :logger
end
end
def logger
@logger ||= Rails.logger
end
end
class Thing
include HasLogger
end
推荐阅读
- c# - 在 WPF 中 dataGridTemplateColumn.CellTemplate 的同一按钮单击事件后面调用不同的函数
- laravel - 如何检查laravel登录中是否存在电子邮件
- jquery - Ajax Post 调用响应为空
- python - .extract() 不正确的 img 链接-scrapy
- android - 过滤器工作文本未在 android 的 recyclerview 中突出显示
- python-3.x - 如何创建一个目录为绝对根目录的python虚拟环境
- r - 用 R 插补
- sqlite - 在 SQLite 中搜索 blob 字段
- javascript - 如何更改 React Google Charts 中的语言?
- angular - 错误 TS2344:类型“T[K]”不满足约束