Generic support for filters applied in context
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
This is the main class, it provides DSL methods to build nestable context, global and local filters and to execute filters depending on context.
- 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 local- filter_blockto take effect for the given- codeblock, 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 the- nilpriority, try priorities:- [:first, nil, :last]
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
endThe 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
endThis should be it, for real life example check:




