From: Massimiliano Mirra - bard Date: 2003-08-27T05:48:48+09:00 Subject: Re: Aspect oriented Everything? Mark Wilson writes: > I have yet to read a description of what aspect oriented development is > and how one would use it, that I could understand (i.e., with a code > example that explains what is being done). Could someone provide such a > description? Disclaimer: I've never used AspectJ nor AspectR, nor do actually know much more about AOP than what has been said in this thread in in earlier ones in this group. The following was whipped together in about ten minutes after seeing Dan's post; if you find stupidity atoms in it, they probably all belong to me. module Wrappable def Wrappable.append_features(c) c.public_instance_methods.each do |method| c.class_eval " alias_method :unwrapped_#{method}, :#{method} remove_method :#{method} def #{method}(*args) call_prewrap(:#{method}, *args) result = unwrapped_#{method}(*args) call_postwrap(:#{method}, result) result end " end end end module Aspectable def add_prewrap(method_id, &block) @prewraps ||= {} @prewraps[method_id] ||= [] @prewraps[method_id] << block end def add_postwrap(method_id, &block) @postwraps ||= {} @postwraps[method_id] ||= [] @postwraps[method_id] << block end def call_prewrap(method_id, *args) @prewraps ||= {} @prewraps[method_id].each { |wrap| wrap.call(method_id, *args) } end def call_postwrap(method_id, *args) @postwraps ||= {} @postwraps[method_id].each { |wrap| wrap.call(method_id, *args) } end end class Test def greet(someone) puts "Hello, #{someone}!" end end t = Test.new t.greet('world') # >> Hello, world! class Test include Wrappable include Aspectable end log_enter = proc { |method, *args| STDERR.puts "Now entering '#{method}' with args #{args.inspect}" } log_exit = proc { |method, result| STDERR.puts "Now exiting '#{method}' with result #{result.inspect}" } t = Test.new t.add_prewrap(:greet, &log_enter) t.add_postwrap(:greet, &log_exit) t.greet('matz') # >> Now entering 'greet' with args ["matz"] # >> Hello, matz! # >> Now exiting 'greet' with result nil Massimiliano p.s.: Yes, the modules are tightly coupled and that is bad, I didn't find a way to have it work with a single module (not that I've searched that hard...).