Ruby 元编程之 - Ruby 勾子 ( hook ) 方法

yufei       6 年, 3 月 前       1541

Ruby 内置了一些钩子 ( hook ) 方法,允许我们动态操作类,模块和对象。下面列出了一些最重要的钩子方法

  • Module#included
  • Module#extended
  • Module#prepended
  • Class#inherited

included, extended 和 prepended 三个模块级别的钩子方法

但一个模块被包含 ( included ) 、 扩展 ( extended ) 或预先前置在另一个模块或类中时,就会自动调用该模块下的这些钩子方法。

因为它们的工作模式类似,因此我们这里只以 included 钩子方法为例。

module Commentable
  def self.included(commentable_entity)
    puts "The #{commentable_entity} entity now accepts comments !"
  end
end

class MediumPost
  include Commentable
end

运行结果如下

The MediumPost entity now accepts comments !

这些钩子方法允许我们为钩子所在的模块或类添加新方法或新属性。

这个机制实际上是由 ActiveSupport::Concern 模块使用的。

对于 Module#extendedModule#prepended 钩子方法,实现也非常相似

Class#inherited

当一个类定义了 Class#inherited 方法时,任何一个该类的子类被创建时就会自动调用该方法

当我们想要在每个子类的类定义中定义变量或类属性 ( class_attribute ) 时,此钩子方法非常方便

class User
  def self.inherited(user_type)
    puts "#{user_type} is a kind of user"
  end
end

class Tenant < User
end

运行结果如下

Tenant is a kind of user

最显著的应用场景是:ActiveRecord::Core 模块对 initialize_find_by_cache 类方法的作用

总结

钩子相关方法可以非常方便地对类和模块进行操作。但是,当它们修改模块/类蓝图时,会引起一些不需要的副作用,如祖先类方法覆盖等

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.