Ruby元编程-子类回调模块
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ruby元编程-子类回调模块相关的知识,希望对你有一定的参考价值。
require 'rubygems' require 'active_model' # use this if you want to create before and after filters around a commonly used # method, but still want to define the method in subclasses. module SubclassableCallbacks def self.included(base) base.extend ClassMethods end module ClassMethods attr_accessor :subclassable_callbacks def subclassable_callbacks(*methods) @subclassable_callbacks ||= [] unless methods.empty? @subclassable_callbacks = @subclassable_callbacks.concat(methods).flatten.compact.map(&:to_sym).uniq define_model_callbacks *methods class_eval do methods.each do |variable| define_method "implementation_#{variable.to_s}" do; end define_method variable do send("_run_#{variable.to_s}_callbacks") do send("implementation_#{variable.to_s}") end end alias_method "superclass_#{variable.to_s}", variable end end end @subclassable_callbacks end end def self.override ObjectSpace.each_object(Class) do |object| if object.ancestors.include?(SubclassableCallbacks) object.class_eval do methods = object.subclassable_callbacks last_index = object.superclass.ancestors.index(SubclassableCallbacks) if last_index && last_index > 0 superclass_methods = object.superclass.ancestors[0..last_index - 1].map(&:subclassable_callbacks) methods = methods.concat(superclass_methods).flatten.uniq end methods.each do |name| alias_method "subclass_#{name}", "#{name}" alias_method "implementation_#{name}", "subclass_#{name}" alias_method "#{name}", "superclass_#{name}" end end end end end end class BaseModel extend ActiveModel::Callbacks include SubclassableCallbacks subclassable_callbacks :save before_save { puts "[save:before]"} after_save { puts "[save:after]"} end class SomeModel < BaseModel def save puts "[saving some_model...]" true end end class AnotherModel < BaseModel def save puts "[saving another_model...]" true end end SubclassableCallbacks.override SomeModel.new.save #=> [save:before] #=> [saving some_model...] #=> [save:after] AnotherModel.new.save #=> [save:before] #=> [saving another_model...] #=> [save:after]
以上是关于Ruby元编程-子类回调模块的主要内容,如果未能解决你的问题,请参考以下文章
GroovyMOP 元对象协议与元编程 ( 使用 Groovy 元编程进行函数拦截 | 属性缺失 propertyMissing 函数回调 | 方法缺失 methodMissing 函数回调 )