Skip to content

Instantly share code, notes, and snippets.

@jqr
Forked from technicalpickles/snippet.rb
Created April 6, 2009 20:10
Show Gist options
  • Save jqr/90910 to your computer and use it in GitHub Desktop.
Save jqr/90910 to your computer and use it in GitHub Desktop.
# Spawned from this thread: http://rubyflow.com/items/1990
module Enumerable
# Wraps an enumerable in an easy interface for selecting subsets. Comparison
# and method calls are supported.
#
# [0, 1, 2, 3].filter > 1 # => [2, 3]
# [0, 1, 2, 3].filter.zero? # => [0]
#
# Warning: Do not use this with the != operator, use filter_not instead.
#
# [0, 1, 2, 3].filter != 1 # => false
def filter
FilterableEnumerable.new(self)
end
# Wraps an enumerable in an easy interface for selecting subsets with a
# negative comparison. Comparison and method calls are supported.
#
# [0, 1, 2, 3].filter_not > 1 # => [0, 1]
# [0, 1, 2, 3].filter_not.zero? # => [1, 2, 3]
#
# Warning: Do not use this with the != operator, use filter instead.
def filter_not
FilterableEnumerable.new(self, true)
end
end
class FilterableEnumerable
def initialize(original, negate = false)
@original = original
@negate = negate
end
def ==(value)
@original.select { |v| (v == value) ^ @negate }
end
def method_missing(sym, *args, &block)
@original.select { |v| v.send(sym, *args, &block) ^ @negate }
end
def respond_to?(sym, include_private = false)
@original.all? { |v| v.respond_to?(sym, include_private) }
end
end
require 'test/unit'
class TestFilterableEnumerable < Test::Unit::TestCase
def setup
@enumerable = 0..10
end
def test_gte
assert_equal [5, 6, 7, 8, 9, 10], @enumerable.filter >= 5
end
def test_gt
assert_equal [6, 7, 8, 9, 10], @enumerable.filter > 5
end
def test_lte
assert_equal [0, 1, 2, 3, 4], @enumerable.filter < 5
end
def test_le
assert_equal [0, 1, 2, 3, 4, 5], @enumerable.filter <= 5
end
def test_eq
assert_equal [5], @enumerable.filter == 5
end
def test_not_eq
assert_equal [0, 1, 2, 3, 4, 6, 7, 8, 9, 10], @enumerable.filter_not == 5
end
def test_method_missing
assert_equal [0], @enumerable.filter.zero?
end
def test_not_method_missing
assert_equal [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], @enumerable.filter_not.zero?
end
def test_respond_to
assert @enumerable.filter.respond_to?(:zero?)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment