Class Cut
In: lib/facets/more/cut.rb
Parent: Module

Cut

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.

Implementation

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.

Limitations

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.

Methods

included   join   method_added   new   stub  

Constants

Stub = Struct.new(:cutname,:cutclass)

External Aliases

new -> create

Public Class methods

Public Instance methods

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.

Prevent infinite loop.

[Validate]