Context Filters
Generic support for filters applied in context
About
This is a set of classes (framework) to build context aware filtering system, allows:
- nested context
- global filters applied depending on context
- local filters applied in given scope
- priority based applying of global filters with mixed in local filtering
- no assumptions in the usage or context/filter format
ContextFilters::Context
This is the main class, it provides DSL methods to build nestable context, global and local filters and to execute filters depending on context.
DSL Methods
-
initialize(priorities_array)
- sets up initial context (+nil+), execute all methods on this instance -
filter(priority, options) { code }
- create priority based filter for given options with the code bloc to execute -
local_filter(filter_block) { code }
- define localfilter_block
to take effect for the givencode
block, it's tricky as it takes two lambdas, try:local_filter(Proc.new{|cmd| "cd path && #{cmd}"}) { code }
-
context(options) { code }
- build new context, options are for matching filters, all code will be executes in context of given options -
evaluate_filters(target, method)
- evaluate global and local filters in the order of given priority, local filters are called after thenil
priority, try priorities:[:first, nil, :last]
Example
On The beginning we need object that can apply multiple filters on
itself, we will use the method change
for that:
# test/context-filters/filter_test_subject.rb
class FilterTestSubject
attr_accessor :value
def initialize(value)
@value = value
end
def change(&block)
@value = block.call(@value)
end
end
The method does not have to be called change, you can use any number of
attributes (@a1, @a2... = block.call(@a1, @a2...)
) or pass self
(block.call(self)
).
Now the real example:
# define filter that adds one to our number
addition = Proc.new { |value| value+1 }
# define filter that multiplies our number by three
multiplication = Proc.new { |value| value*3 }
# use the multiplication filter globally (the nil scope is the initial context)
subject.filter(nil,&multiplication)
# use addition filter only in the scope of the given block
subject.local_filter(addition) do
# usually you would extend Context and provide a helper method to do the following:
# build the object we want to filter
filter_test_subject = FilterTestSubject.new(3)
# apply matching filters to the object
subject.evaluate_filters(filter_test_subject, :change)
# get the result from object
puts filter_test_subject.value
# => 10
end
This should be it, for real life example check: