Bug #1554 [ruby-core:23661]
Enumerator#first & #take should consume only what is needed [patch]
| Status : | Closed | Start : | 06/02/2009 | |
| Priority : | Normal | Due date : | ||
| Assigned to : | - | % Done : | 100% |
|
| Category : | core | |||
| Target version : | 1.9.2 | |||
| ruby -v : | ruby 1.9.2dev (2009-06-01 trunk 23616) [i386-darwin9.7.0] |
Description
Currently, in Ruby 1.9.x:
require 'stringio'
s = StringIO.new("first \n second \n third")
s.rewind
p s.take(1), s.take(1)
# Prints "[first \n]" and "[ second \n]"
s.rewind
p [s.first], [s.first]
# Prints "[first \n]" and "[ second \n]"
s.rewind
p s.first(1), s.first(1)
# Prints "[first \n]" and "[third]"
I believe most people would expect that [s.first], s.first(1) and s.take(1) should be the same and have the same side effects, if any. It is also more efficient that :each yields just the right number of times necessary to complete the request. As such it would be preferable if the last printout was the same as the previous two.
Note that in Ruby 1.8.7, the output for Enumerable#take is also wrong.
The included patches fix this issue for both versions.
I took the opportunity to change #first so that it calls :to_int on its argument only once if it needs to be converted. Before the patch it is called twice. This brings it in line with Array#first and Enumerable#take.
Note: rubyspecs have been updated.
Associated revisions
- enum.c (first_i): Enumerator#first should consume only what is
needed. a patch from Marc-Andre Lafortune.
[ruby-core:23661] - enum.c (enum_first): call to_int once for an argument. based on a patch from Marc-Andre Lafortune.