Add support for Aspect Oriented Programming (AOP).
Examples
class Controller
pre :force_login, :where => :prepend wrap Benchmark, :on => :index post :taraa, :on => login
end
module Timestamped
pre :on => :og_insert { |this| this.create_time = Time.now } pre :on => :og_update { |this| this.update_time = Time.now } pre :on => [:og_insert, :og_update] { |this| this.create_time = Time.now }
end
Methods
Classes and Modules
Module Aspects::ClassMethodsConstants
Advice | = | Struct.new(:code, :options) |
Store the code and the metadata (options) for an Advice. |
Public Class methods
[ show source ]
# File lib/facets/more/aspects.rb, line 178 def self.append_features(base) super base.extend(ClassMethods) base.inheritor :advices, [], :+ end
Include Modules that define advices.
[ show source ]
# File lib/facets/more/aspects.rb, line 101 def self.include_advice_modules(target) add_advices = [] del_advices = [] for a in target.advices if a.code.is_a?(Module) and (!a.code.class.ancestors.include?(Class)) target.module_eval %{ include #{a.code} } options = a.options.reject { |k,v| k == :pre || k == :post } method = (a.options[:pre] || 'pre').to_s if a.code.instance_methods.include?(method) options.update(:where => :prepend, :join => :pre) add_advices << Advice.new(method.to_sym, options) end method = (a.options[:post] || 'post').to_s if a.code.instance_methods.include?(method) options.update(:where => :append, :join => :post) add_advices << Advice.new(method.to_sym, options) end del_advices << a end end # Delete the original advices. for a in del_advices target.advices!.delete(a) end # Add the new advices. target.advices!.concat(add_advices) end
Apply the advices to the target class.
[ show source ]
# File lib/facets/more/aspects.rb, line 75 def self.wrap(target, methods = target.instance_methods) include_advice_modules(target) for m in [methods].flatten args = [] target.instance_method(m).arity.times { |i| args << "a#{i}" } args = args.join(',') target.module_eval "alias_method :__unwrapped_\#{m}, :\#{m}\ndef \#{m}(\#{args})\n\#{gen_advice_code(m, target.advices, :pre)}\n__unwrapped_\#{m}(\#{args})\n\#{gen_advice_code(m, target.advices, :post)}\nend\n", __FILE__, __LINE__ end end