包含任何模块时的 Ruby 回调

标签 ruby module callback mixins

我知道我们可以为任何单独的模块定义 included 回调。

有什么方法可以定义一个回调,只要任何模块被包含在另一个模块或类中,它就会被调用?然后,回调最好能够访问包含的模块以及包含它的类/模块。

最佳答案

我想不出也找不到 Ruby 中的内置方法来做到这一点。

一种替代方法是直接对 Module 类进行猴子修补以创建回调。为此,我们可以在原始方法 includeextend 周围添加一些包装方法,以在每次 includeinclude 时强制执行我们定义的回调extend 方法被调用。

按照以下几行应该可以工作:

class Module

  def self.before
    m_include = instance_method(:include)
    m_extend = instance_method(:extend)

    define_method(:include) do |*args, &block|
      included_callback(args[0])
      m_include.bind(self).call(*args, &block)
    end

    define_method(:extend) do |*args, &block|
      extend_callback(args[0])
      m_extend.bind(self).call(*args, &block)
    end
  end

  def included_callback(mod_name)
    puts "#{self} now has included Module #{mod_name}"
  end

  def extend_callback(mod_name)
    puts "#{self} now has extended Module #{mod_name}"
  end

  before
end

一个测试它是否有效的例子:

module Awesome

  def bar
    puts "bar"
  end

  def self.baz
    puts "baz"
  end
end

class TestIncludeAwesome
  include Awesome
end

class TestExtendAwesome
  extend Awesome
end

示例代码应输出以下内容:

> TestIncludeAwesome now has included Module Awesome
> TestExtendAwesome now has extended Module Awesome

关于包含任何模块时的 Ruby 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43075503/

相关文章:

javascript - Angularjs:[$injector:modulerr] 无法实例化模块 ui-router

php - 如何 $_GET [' ' ] 从 mod_modulenamet/mpl/default.php 中的 $document->addStylesheet() 到 joomla 模块的 css.php 文件的值

Codeigniter 将 2 个参数传递给回调

javascript - 将额外变量传递给回调

javascript - 使用预设参数编写回调函数

Ruby:如何将 IP 范围转换为 IP 数组

ruby - 指定 TLSv1 时 SSLv3 证书验证失败?

mysql - Ruby on Rails 多个唯一列

ruby-on-rails - 基于关系创建范围

JavaScript:我可以访问包含导入模块的对象吗?