Class | Cut |
In: |
lib/facets/more/cut.rb
|
Parent: | Module |
Cut is a low-level AOP facility.
class X def x; "x"; end end cut :C < X do def x; '{' + super + '}'; end end X.new.x #=> "{x}"
Cuts act as "pre-class". Which depictively is:
ACut < AClass < ASuperClass
Instantiating AClass effecively instantiates ACut instead, but that action is essentially transparent.
This implementation of Cut-based AOP nearly meets the formal concepts. This differs slighly in that a Cut is not a class but rather a subclass of Module which is included into a single "proxycut" class.
This is very low-level library, as pure-Ruby library go. It overrides new for all classes and included for all modules. If you consider the formal usage of Cuts, it essentially usurps any further need for callbacks of this kind. Nonetheless, those callback will still be used and developers should "play nice" by wrapping such functionality rather than overriding. Cuts on the other hand, purposefully overrides.
IMPORTANT To appropriately use Cuts, it should be the first library required. One way to faciliate this by adding it to your RUBYOPT.
You can not cut classes formed via literal constructors, such as a String defined via "" or a Hash defined via {}. Ruby provides no means for overriding literal constructors.
Stub | = | Struct.new(:cutname,:cutclass) |
new | -> | create |
Define a pointcut as selection of joinpoints (methods in our case) to be advised. The block should return the name of the advice to use when teh joinpoint matches, nil or false otherwise.
join :break => { |jp| jp =~ /^log.*/ }
This would be very interesting in the context of annotations too.
join :break => { |jp| ann(mp).class == String ? :break }
Takes a hash of advice => method a joining the advice to the method.