Method: Object#to_enum
- Defined in:
- enumerator.c
#to_enum(method = :each, *args) ⇒ Enumerator #enum_for(method = :each, *args) ⇒ Enumerator #to_enum(method = :each, *args) {|*args| ... } ⇒ Enumerator #enum_for(method = :each, *args) {|*args| ... } ⇒ Enumerator
Creates a new Enumerator which will enumerate by calling method
on obj
, passing args
if any. What was yielded by method becomes values of enumerator.
If a block is given, it will be used to calculate the size of the enumerator without the need to iterate it (see Enumerator#size).
Examples
str = "xyz"
enum = str.enum_for(:each_byte)
enum.each { |b| puts b }
# => 120
# => 121
# => 122
# protect an array from being modified by some_method
a = [1, 2, 3]
some_method(a.to_enum)
# String#split in block form is more memory-effective:
very_large_string.split("|") { |chunk| return chunk if chunk.include?('DATE') }
# This could be rewritten more idiomatically with to_enum:
very_large_string.to_enum(:split, "|").lazy.grep(/DATE/).first
It is typical to call to_enum when defining methods for a generic Enumerable, in case no block is passed.
Here is such an example, with parameter passing and a sizing block:
module Enumerable
# a generic method to repeat the values of any enumerable
def repeat(n)
raise ArgumentError, "#{n} is negative!" if n < 0
unless block_given?
return to_enum(__method__, n) do # __method__ is :repeat here
sz = size # Call size and multiply by n...
sz * n if sz # but return nil if size itself is nil
end
end
each do |*val|
n.times { yield *val }
end
end
end
%i[hello world].repeat(2) { |w| puts w }
# => Prints 'hello', 'hello', 'world', 'world'
enum = (1..14).repeat(3)
# => returns an Enumerator when called without a block
enum.first(4) # => [1, 1, 1, 2]
enum.size # => 42
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
# File 'enumerator.c', line 368
static VALUE
obj_to_enum(int argc, VALUE *argv, VALUE obj)
{
VALUE enumerator, meth = sym_each;
if (argc > 0) {
--argc;
meth = *argv++;
}
enumerator = rb_enumeratorize_with_size(obj, meth, argc, argv, 0);
if (rb_block_given_p()) {
enumerator_ptr(enumerator)->size = rb_block_proc();
}
return enumerator;
}
|