0.0
No commit activity in last 3 years
No release in over 3 years
Generic support for filters applied in context
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 2.6
~> 5.4
~> 1.1
~> 10.3
 Project Readme

Context Filters

Gem Version Build Status Dependency Status Code Climate Coverage Status Inline docs Yard Docs Github Code

Generic support for filters applied in context

About

This is a set of classes (framework) to build context aware filtering system, allows:

  1. nested context
  2. global filters applied depending on context
  3. local filters applied in given scope
  4. priority based applying of global filters with mixed in local filtering
  5. 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 local filter_block to take effect for the given code 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 the nil 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: