Support for simple Aspect Oriented Programming (AOP).
The ‘before’ and ‘after’ methods wrap another method or a block of code arround the target method.
before :save do
@time = Time.now
end before :insert, :call => :timestamp before :read, :create, :call => :check_user_login after :read, do
puts "Article hit"
end before instance_methods, :call => :log
The :call => :advice version is slightly faster, but the default block notation is more elegant. The aspects are s inherited. You can define aspects before the target methods are defined.
If no target methods are provided, apply the advice to all localy defined public methods. For example:
before(:call => :try_login) before do
@time = Time.now
end
The Aspects module is included by default in all modules.
Check this page for more details on the method aliasing trick: zimbatm.oree.ch/2006/12/25/various-method-aliasing-methods-in-ruby
author: George Moschovitis (gmosx.com)
Apply aspects to the given class.
[ show source ]
# File lib/nitro/aspects.rb, line 152
152: def apply(klass)
153: $ASPECTS_WRAPPING_METHOD = true
154:
155: return unless klass.respond_to? :advices
156:
157: for a in klass.advices
158: if a.targets == :LOCAL_METHODS
159: meths = klass.instance_methods(:local, :public)
160: else
161: meths = a.targets
162: end
163: for m in meths
164: a.wrap(klass, m)
165: end
166: end
167:
168: $ASPECTS_WRAPPING_METHOD = false
169: end
[ show source ]
# File lib/nitro/aspects.rb, line 206
206: def resolve_args(target)
207: if (ar = target.arity) > 0
208: args = []
209: ar.times do |i|
210: args << "param#{i}"
211: end
212: args = args.join(", ")
213: elsif ar == 0
214: args = ""
215: else
216: args = "*args"
217: end
218:
219: return args
220: end
Apply all aspects to all classes. In some cases, you have to manually call this method.
[ show source ]
# File lib/nitro/aspects.rb, line 144
144: def setup
145: ObjectSpace.each_object(Class) do |c|
146: apply(c)
147: end
148: end
Insert the advice after the method. Works exactly like #before.
[ show source ]
# File lib/nitro/aspects.rb, line 89
89: def after(*args, &block)
90: targets, advice, options = Aspects.resolve(self, args, block)
91: advices! << Aspects::Advice.new(:after_method, targets, advice)
92: Aspects.apply(self) unless $STATIC_ASPECTS
93: return self
94: end
Insert the advice before the method.
[ show source ]
# File lib/nitro/aspects.rb, line 78
78: def before(*args, &block)
79: targets, advice, options = Aspects.resolve(self, args, block)
80: advices! << Aspects::Advice.new(:before_method, targets, advice)
81: Aspects.apply(self) unless $STATIC_ASPECTS
82: return self
83: end
Alias for #after
Alias for #before