On 6/22/06, [email protected] [email protected] wrote:
Why not:
aspect = Aspect.new do |a|
a.apply_to_types SomeClass, String, FooBar
a.pointcut(“some_method”,…).with(LoggingInterceptor.new)
a.register_with_aop_engine
end
Like others, I’m not sure how the implementation of the
apply_to_types, pointcut and register_with_aop_engine will go (I’m
sure there’s some… I’m just not worrying about it), but I agree with
David that an instance of the Aspect class is probably what you really
want. I’d clean the syntax up (“clean” being just my opinion) a little
more like:
aspect(SomeClass, String, FooBar) do
pointcut :some_method,
:some_prop=,
:some_prop,
:length
with LoggingInterceptor.new
end
Implementation of the builder:
def aspect(*classes, &definition)
AspectBuilder.instance.build(*classes, &definition)
end
class AspectBuilder
include Singleton
def build(*classes, &definition)
@aspect = Aspect.new
@methods = []
@aspect.apply_to_types *classes
instance_eval &definition
@aspect.register_with_aop_engine
end
def pointcut(*methods)
@methods += methods
end
def with(interceptor)
@aspect.pointcut(*@methods).with(interceptor)
@methods = []
end
end
Sample implementation of the Aspect class (just stubbing here):
class Aspect
def apply_to_types(*classes)
@classes = classes
end
def pointcut(*methods)
cut = PointCut.new(*methods)
(@cuts ||= []) << cut
cut
end
def register_with_aop_engine
classes = @classes.size == 1 ? @classes[0] :
[@classes[0..-2].join(', '), @classes[-1]].join(' and ')
puts "Adding an aspect on #{classes} with the following cuts:"
@cuts.each{ |cut| puts "\t#{cut}" }
end
class PointCut
def initialize(*methods)
@methods = methods
end
def with(interceptor)
@interceptor = interceptor
end
def to_s
methods = @methods.size == 1 ? @methods[0] :
[@methods[0..-2].join(', '), @methods[-1]].join(' and ')
"Cutting #{methods} with a #{@interceptor.class}"
end
end
end
Output of the above built aspect with the Aspect stub as above and
simple classes for SomeClass, FooBar and LoggingInterceptor:
Adding an aspect on SomeClass, String and FooBar with the following
cuts:
Cutting some_method, some_prop=, some_prop and length with a
LoggingInterceptor
Jacob F.