Aspect Oriented Programming is not a popular topic in the Ruby community. Partially, it's because Ruby gives us some AOP constructs out-of-the-box (open classes) but also due to some built-in mechanisms in Rails - like filters and callbacks which serve as the dynamic part of AOP.
I think that there are scenarios in which traditional AOP can be very useful. Today, I'm going to show you how to implement logging of chosen method calls, without touching the methods itself.
Aquarium seems to be the best AOP framework with Ruby.
Installation
#the first part is only needed if you want to use ruby 1.9
#otherwise just put gem "aquarium" into the Gemfile and run "bundle install"
cd vendor/gems
git clone https://github.com/deanwampler/Aquarium.git
cd Aquarium
git checkout 1.9.1-port
# edit Gemfile and add:
gem 'aquarium', "0.0.0", :path => 'vendor/gems/Aquarium/aquarium'
bundle install
Creating an aspect
Create config/initializers/tracing_aspect.rb and paste:
require 'aquarium' include Aquarium::Aspects Aspect.new :around, :calls_to => :all_methods, :for_types => [User], :method_options => :exclude_ancestor_methods do |jp, obj, *args| begin names = "#{jp.target_type.name}##{jp.method_name}" p "Entering: #{names}: args = #{args.inspect}" jp.proceed ensure p "Leaving: #{names}: args = #{args.inspect}" end end
If you now run the tests or just use your app, you should see all the method calls on User objects being logged to the output.
I hope it works fine for you, let me know in case of problems.
4 comments:
and "jp, obj" are..?
jp = join_point
obj is the target object on which the methods are called.
Have you tried RCapture?
Last time I needed AOP (for logging), I ended up choosing RCapture over Aquarium and it was fairly easy to use: https://github.com/chastell/art-decomp/blob/master/lib/art-decomp/logging.rb#L39
@Piotr
I didn't know about RCapture, thanks!
Post a Comment