6 # The <code>Enumerable</code> mixin provides collection classes with
7 # several traversal and searching methods, and with the ability to
8 # sort. The class must provide a method <code>each</code>, which
9 # yields successive members of the collection. If
10 # <code>Enumerable#max</code>, <code>#min</code>, or
11 # <code>#sort</code> is used, the objects in the collection must also
12 # implement a meaningful <code><=></code> operator, as these methods
13 # rely on an ordering between members of the collection.
18 # Call the given block for each element
19 # which is yield by +each+. Return false
20 # if one block value is false. Otherwise
21 # return true. If no block is given and
22 # +self+ is false return false.
28 unless block.call(*val)
43 # Call the given block for each element
44 # which is yield by +each+. Return true
45 # if one block value is true. Otherwise
46 # return false. If no block is given and
47 # +self+ is true object return true.
68 # Call the given block for each element
69 # which is yield by +each+. Append all
70 # values of each block together and
75 return to_enum :collect unless block_given?
79 ary.push(block.call(*val))
85 # Call the given block for each element
86 # which is yield by +each+. Return
87 # +ifnone+ if no block value was true.
88 # Otherwise return the first block value
92 def detect(ifnone=nil, &block)
104 # Call the given block for each element
105 # which is yield by +each+. Pass an
106 # index to the block which starts at 0
107 # and increase by 1 for each element.
110 def each_with_index(&block)
111 return to_enum :each_with_index unless block_given?
115 block.call(val.__svalue, i)
122 # Return an array of all elements which
123 # are yield by +each+.
129 # __svalue is an internal method
130 ary.push val.__svalue
142 # Call the given block for each element
143 # which is yield by +each+. Return an array
144 # which contains all elements whose block
149 return to_enum :find_all unless block_given?
153 ary.push(val.__svalue) if block.call(*val)
159 # Call the given block for each element
160 # which is yield by +each+ and which return
161 # value was true when invoking === with
162 # +pattern+. Return an array with all
163 # elements or the respective block values.
166 def grep(pattern, &block)
171 ary.push((block)? block.call(*val): sv)
178 # Return true if at least one element which
179 # is yield by +each+ returns a true value
180 # by invoking == with +obj+. Otherwise return
186 if val.__svalue == obj
194 # Call the given block for each element
195 # which is yield by +each+. Return value
196 # is the sum of all block values. Pass
197 # to each block the current sum and the
201 def inject(*args, &block)
202 raise ArgumentError, "too many arguments" if args.size > 2
203 if Symbol === args[-1]
205 block = ->(x,y){x.__send__(sym,y)}
209 flag = true # no initial argument
218 # push first element as initial
222 result = block.call(result, val)
236 # Return the maximum value of all elements
237 # yield by +each+. If no block is given <=>
238 # will be invoked to define this value. If
239 # a block is given it will be used instead.
243 flag = true # 1st element?
253 result = val if block.call(val, result) > 0
255 result = val if (val <=> result) > 0
263 # Return the minimum value of all elements
264 # yield by +each+. If no block is given <=>
265 # will be invoked to define this value. If
266 # a block is given it will be used instead.
270 flag = true # 1st element?
280 result = val if block.call(val, result) < 0
282 result = val if (val <=> result) < 0
293 alias member? include?
296 # Call the given block for each element
297 # which is yield by +each+. Return an
298 # array which contains two arrays. The
299 # first array contains all elements
300 # whose block value was true. The second
301 # array contains all elements whose
302 # block value was false.
305 def partition(&block)
310 ary_T.push(val.__svalue)
312 ary_F.push(val.__svalue)
319 # Call the given block for each element
320 # which is yield by +each+. Return an
321 # array which contains only the elements
322 # whose block value was false.
328 ary.push(val.__svalue) unless block.call(*val)
334 # Alias for find_all.
337 alias select find_all
341 # Does this OK? Please test it.
342 def __sort_sub__(sorted, work, src_ary, head, tail, &block)
344 sorted[head] = work[head] if src_ary == 1
348 # on current step, which is a src ary?
350 src, dst = sorted, work
352 src, dst = work, sorted
355 key = src[head] # key value for dividing values
356 i, j = head, tail # position to store on the dst ary
358 (head + 1).upto(tail){|idx|
359 if ((block)? block.call(src[idx], key): (src[idx] <=> key)) > 0
371 # sort each sub-array
372 src_ary = (src_ary + 1) % 2 # exchange a src ary
373 __sort_sub__(sorted, work, src_ary, head, i - 1, &block) if i > head
374 __sort_sub__(sorted, work, src_ary, i + 1, tail, &block) if i < tail
376 # private :__sort_sub__
379 # Return a sorted array of all elements
380 # which are yield by +each+. If no block
381 # is given <=> will be invoked on each
382 # element to define the order. Otherwise
383 # the given block will be used for
389 self.each{|*val| ary.push(val.__svalue)}
391 __sort_sub__(ary, ::Array.new(ary.size), 0, 0, ary.size - 1, &block)
402 # redefine #hash 15.3.1.3.15