Module: Enumerable::Argumentable
- Defined in:
- lib/standard/facets/enumargs.rb
Overview
This is a simple reimplementation of the core Enumerable module to allow its 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 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. However, The methods #find and #detect have been made modified to work by removing its rarely used optional parameter and providing instead an optional keyword parameter (:ifnone => …). Please keep these difference in mind.
Example
require 'enumargs'
class T
include Enumerable::Argumentable
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]
Class Method Summary collapse
-
.wrap_enumerable_method(methodname) ⇒ Object
Helper method to wrap Enumerable methods.
Instance Method Summary collapse
-
#find(*args, &yld) ⇒ Object
(also: #detect)
Make exception for #find (a negative arity method) to accept keyword argument.
-
#to_a(*args) ⇒ Object
Support for #to_a.
Class Method Details
.wrap_enumerable_method(methodname) ⇒ Object
Helper method to wrap Enumerable methods.
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/standard/facets/enumargs.rb', line 34 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 # this branch is used when the method has a variable number of arguments # resulting in an arity of -1. Right now this is bugged as it does # not pass the argument to the each, and always passes the argument # to the method. This makes methods like .min amdn .max to act # in an unexpected manner. class_eval %{ def #{m}( *args, &yld ) enum_for(:each).#{m}( *args, &yld ) end } end end |
Instance Method Details
#find(*args, &yld) ⇒ Object Also known as: detect
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| ... }
85 86 87 88 89 90 91 92 93 |
# File 'lib/standard/facets/enumargs.rb', line 85 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 |
#to_a(*args) ⇒ Object
Support for #to_a.
74 75 76 77 |
# File 'lib/standard/facets/enumargs.rb', line 74 def to_a(*args) #map(*args){ |x| x } enum_for(:each, *args).to_a end |