I'm trying to write a class that supports nested around filters without introducing an Aspect-oriented library.
class Foo
attr_accessor :around_filter
def initialize
#filters which wrap the following one are the ones with interesting logic
#vanilla do-nothing filter
@around_filter = lambda { yield } # or lambda {|&blk| blk.call}
end
def bar
#would execute the around filters however deeply nested, then "meaty code"
@around_filter.call do
#meaty code here
puts 'done'
end
end
#I expected to point only to the topmost filter, hoping to recurse
def add_around_filter(&blk)
prior_around_filter = @around_filter
@around_filter = #??mystery code here?? refers to prior_around_filter
end
end
The goal is to be able to add any number of around filters:
foo = Foo.new
foo.add_around_filter do
puts 'strawberry'
yield
puts 'blueberry'
end
foo.add_around_filter do
puts 'orange'
yield
puts 'grape'
end
foo.bar #=> orange, strawberry, done, blueberry, grape
I know there are a bunch of holes in the example. I wrote only enough to covey the general direction, distilling from a much larger actual class.
Although I prefer yield
syntax, I'm not opposed to block references:
foo.add_around_filter do |&blk|
puts 'orange'
blk.call
puts 'grape'
end
I got this working only with a single around filter. I tried lots of things with nesting, but never cracked the puzzle. If you have a solution, I'd appreciate it a bunch!