From: David Pollak Date: 2006-06-23T12:43:15+09:00 Subject: Re: AOP style logging - is this possible in ruby? ------=_Part_9351_17786295.1151034180344 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline Rob, You can "trap" methods as they're being added to your classes and rewrite them. For example: class Module def method_added(meth_name) # don't muck with stuff added to Module return if self == Module || meth_name.to_s.match(/^__aop__/) # don't infinitely call ourselves return if caller[0] =~ /method_added/ # rename the newly added method self.send(:alias_method,"__aop__#{meth_name}".intern, meth_name) # get the method to determine its parameters meth = self.instance_method(meth_name) params = '' a = meth.arity fixed_cnt = a.abs fixed_cnt -= 1 if a < 0 # build up a list of parameters (0...fixed_cnt).each {|x| params << "p#{x},"} params << "*argv" if a < 0 params.gsub!(/,$/, '') # create the "AOP" method that calls the orignal method self.module_eval("def #{meth_name}(#{params}) ; puts \"Called #{meth_name} stack #{caller}\" ; __aop__#{meth_name}(#{params}); end") end end class Foo def bar(a,b,c) puts "I'm bar!! a = #{a} b = #{b} c = #{c}" end end 1.upto(3) do |x| Foo.new.bar(1,"loop #{x}", 4) end You've got all the wrapping functionality you want. In the method_added method, you can test for class name, method visibility, etc. But the above code shows how to intercept methods as they're added. Does this answer your question? Thanks, David On 6/22/06, Rob Sanheim wrote: > > In Java, with AOP magic and bytecode manipulation under the covers, > you could do something like this: (psuedocode, in real java it would > be xml or annotations) > > For methods that are: public, name matches foo*, members of classes > Bar and Boo, intercept and log by calling myLogger > > then myLogger would get the method object, and be able to log the > name, time of call, parameters, etc... > > I know in Ruby you can very easily turn methods or blocks into > objects, and even do some things similiar to basic AOP, but can > something like this be done? > > Module AOPLogger > log_methods :criteria => "all", :log => :method_name, :time, :date > > Where log_methods is a class method to be implemented in AOPLogger and > then extend'ed into classes where you want method calls intercepted > and logged. > > I imagine something like this might be possible by establishing a > proxy object around objects you want mixed in, then tying into > method_missing, though I imagine it would get nasty quick. > > Any ideas? > > - Rob > > ps - a related, but simpler question - is there a way inside a method > body to get the name of that method reflectively? > ie: def foo > logger.debug("method called is #{method_name}) > end > => "method called is foo" > -- > http://www.robsanheim.com > http://www.seekingalpha.com > http://www.ajaxian.com > > -- -------- David Pollak's Ruby Playground http://dppruby.com ------=_Part_9351_17786295.1151034180344--