From: Alexandru Popescu Date: 2005-09-14T20:07:48+09:00 Subject: Re: ruby and aop Thanks for both suggestions so far. However these are easy solutions for the most commons things. When talking about aop there are a lot of joinpoints that are interesting, there are the intertype declarations (this part I think is pretty easy in Ruby), and maybe some more little tricks. :alex |.::the_mindstorm::.| #: Matthias Georgi changed the world a bit at a time by saying on 9/14/2005 12:11 PM :# > Hi Alexandru! > > I think, aop-like programming is done mostly by redefining methods. > This is somewhat ugly, as you have to alias the old method. > A good example is the once macro as used in freeride or date.rb: > > module Once > def once(*ids) > for id in ids > module_eval <<-"end;" > alias_method :__#{id.to_i}__, :#{id.to_s} > private :__#{id.to_i}__ > def #{id.to_s}(*args, &block) > (@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0] > end > end; > end > end > private :once > end > > By using once, you can cache method results like: > > class MyClass > extend Once > once :my_method > end > > I can imagine a cleaner aop-style of doing this like: > > aspect_around MyModule::MyClass, :my_method do |meth, *args| > ( @__my_method__ ||= [ meth.call(*args) ] )[0] > end > > or more generally > > module Once > def once(*ids) > for id in ids > aspect_around self, id do |meth, *args| > if cache = instance_variable_get("@__#{id}__") > cache[0] > else > result = meth.call(*args) > instance_variable_set("@__#{id}__", [result]) > end > end > end > end > end > > >