EnumerablePass

This is a simple reimplementation of the core Enumerable module to allow the methods to take and pass-on arbitrary arguments to the underlying each call. This library uses Enumerator and scans Enumerable so it can alwasy stay in sync.

NOTE Any Enumerable method with a negative arity cannot do pass arguments due to ambiguity in the argument count. So the methods inject and zip do NOT work this way, but simply work as they do in Enumerable. The method find (and detect) though has been made to work by removing its rarely used optional parameter and providing instead an optional keyword parameter (:ifnone => …). Please keep these difference in mind.

  class T
    include EnumerablePass
    def initialize(arr)
      @arr = arr
    end
    def each(n)
      arr.each{ |e| yield(e+n) }
    end
  end

  t = T.new([1,2,3])
  t.collect(4)
  #=> [5,6,7]
Methods
detect find wrap_enumerable_method
Public Class methods
wrap_enumerable_method( methodname )
# File lib/more/facets/enumerablepass.rb, line 78
  def self.wrap_enumerable_method( methodname )

    m = methodname
    meth = Enumerable.instance_method(m)
    arity = meth.arity

    case arity <=> 0
    when 0
      class_eval %{
        def #{m}( *args, &yld )
          enum_for(:each, *args).#{m}( &yld )
        end
      }
    when 1
      class_eval %{
        def #{m}( *args, &yld )
          args, each_args = args[0...#{arity}], args[#{arity}..-1]
          enum_for(:each, *each_args).#{m}( *args, &yld )
        end
      }
    else
      class_eval %{
        def #{m}( *args, &yld )
          enum_for(:each).#{m}( *args, &yld )
        end
      }
    end
  end
Public Instance methods
detect(*args, &yld)

Alias for find

find(*args, &yld)

Make exception for find (a negative arity method) to accept keyword argument.

  ObjectSpace.find(Class, :ifnone=>lambda{1}) { |e| ... }
  ObjectSpace.find(Class, :ifnone=>lambda{1}) { |e| ... }
This method is also aliased as detect
# File lib/more/facets/enumerablepass.rb, line 117
  def find(*args, &yld)  # future use **keys ?
    if Hash === args.last and args.last.key?(:ifnone)
      ifnone = args.last.delete(:ifnone)
      args.pop if args.last.empty?
      enum_for(:each, *args).find( ifnone, &yld )
    else
      enum_for(:each, *args).find( &yld )
    end
  end