After some recent conversion on AOP on the list, I reviewing the
Cut-based AOP proposal and found one area that needed some address,
namely redirectly methods to their advice in a dyanamic and flexible
fashion. So I modified part of the proposal and addeda new feature,
which I think really strengthens the whole concept.
Advice Joining
Since advising multiple methods with a single advice is the common case
of AOP, a convenient means of redirecting target methods to advice is
essential. While it is trivial to define a method like the following
Cut#redirect_advice:
class Cut
def redirect_advice( h )
c = h.collect { |k,v|
“def #{k}(*a,&b) #{v}(this,*a, &b); end”
}
module_eval c.join("\n")
end
end
cut A < C
redirect_advice :f => :bracket, :g => :bracket
def bracket( target )
‘{’ + target.super + ‘}’
end
end
It is not sufficient for dealing with Ruby’s dynamicism. The above only
handles methods defined in the target class at the moment the cut is
defined. Complete AOP support requires the advice always stay in sync
even under dynamic alteration of the targeted class. Ruby already
provides means for this via the Module#method_added hook, but robust
use of this techinque is inconvenient at best. So a proper
advice-oriented call is warrented, namely Cut#join.
cut A < C
join :f => :bracket, :g => :bracket
def bracket( target )
‘{’ + target.super + ‘}’
end
end
The Cut#join method would also accept wildcards.
cut A < C
join ‘*’ => :bracket
def bracket( target )
‘{’ + target.super + ‘}’
end
end
The #join method provides the essential dynamic flexibility required of
a robust Ruby AOP solution.