require 'minitest/autorun'
module Reducible
Undef = Object.new
def any? v = Undef
reduce(false) { |b, e|
return true if v === e || block_given? && yield(e)
b
}
end
def index v = Undef
reduce(0) { |i, e|
return i if e == v || block_given? && yield(e)
i + 1 if i < size - 1
}
end
def max n = nil
if n
reduce([]) { |ms, e|
(ms << e).sort.drop(ms.size > n ? 1 : 0).reverse
}
else
reduce { |m, e| e > m ? e : m }
end
end
end
Array.prepend Reducible
describe Reducible do
it 'implements #any?' do
assert [1,2,3].any? &:even?
assert [1,2,3].any? Fixnum
refute [1,2,3].any? &:zero?
refute [1,2,3].any? String
end if Reducible.instance_methods.include? :any?
it 'implements #index' do
[1,2,3].index(3).must_equal 2
[1,2,3].index(4).must_be_nil
[1,2,3].index(&:even?).must_equal 1
[1,2,3].index(&:zero?).must_be_nil
end if Reducible.instance_methods.include? :index
it 'implements #max' do
[2,3,1].max.must_equal 3
[2,3,1].max(1).must_equal [3]
[2,3,1].max(2).must_equal [3,2]
[2,3,1].max(3).must_equal [3,2,1]
end if Reducible.instance_methods.include? :max
end