D7net
Home
Console
Upload
information
Create File
Create Folder
About
Tools
:
/
proc
/
self
/
root
/
opt
/
alt
/
ruby34
/
share
/
ri
/
system
/
Enumerator
/
Filename :
cdesc-Enumerator.ri
back
Copy
U:RDoc::NormalClass[iI"Enumerator:ET@I"Object;To:RDoc::Markup::Document:@parts[o;;[$o:RDoc::Markup::Paragraph;[I"?A class which allows both internal and external iteration.;To:RDoc::Markup::BlankLine o; ;[I";An Enumerator can be created by the following methods.;To:RDoc::Markup::List: @type:BULLET:@items[o:RDoc::Markup::ListItem:@label0;[o; ;[I"Object#to_enum;To;;0;[o; ;[I"Object#enum_for;To;;0;[o; ;[I"Enumerator.new;T@o; ;[I"BMost methods have two forms: a block form where the contents ;TI"Jare evaluated for each item in the enumeration, and a non-block form ;TI";which returns a new Enumerator wrapping the iteration.;T@o:RDoc::Markup::Verbatim;[I")enumerator = %w(one two three).each ;TI"+puts enumerator.class # => Enumerator ;TI" ;TI"7enumerator.each_with_object("foo") do |item, obj| ;TI" puts "#{obj}: #{item}" ;TI" end ;TI" ;TI"# foo: one ;TI"# foo: two ;TI"# foo: three ;TI" ;TI"8enum_with_obj = enumerator.each_with_object("foo") ;TI".puts enum_with_obj.class # => Enumerator ;TI" ;TI"'enum_with_obj.each do |item, obj| ;TI" puts "#{obj}: #{item}" ;TI" end ;TI" ;TI"# foo: one ;TI"# foo: two ;TI"# foo: three ;T:@format0o; ;[I"FThis allows you to chain Enumerators together. For example, you ;TI"?can map a list's elements to strings containing the index ;TI"%and the element as a string via:;T@o;;[I"@puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" } ;TI"&# => ["0:foo", "1:bar", "2:baz"] ;T;0S:RDoc::Markup::Heading: leveli: textI"External Iteration;T@o; ;[I"=An Enumerator can also be used as an external iterator. ;TI"IFor example, Enumerator#next returns the next value of the iterator ;TI"=or raises StopIteration if the Enumerator is at the end.;T@o;;[ I"8e = [1,2,3].each # returns an enumerator object. ;TI"puts e.next # => 1 ;TI"puts e.next # => 2 ;TI"puts e.next # => 3 ;TI"*puts e.next # raises StopIteration ;T;0o; ;[I"K+next+, +next_values+, +peek+, and +peek_values+ are the only methods ;TI"ewhich use external iteration (and Array#zip(Enumerable-not-Array) which uses +next+ internally).;T@o; ;[I"EThese methods do not affect other internal enumeration methods, ;TI"Vunless the underlying iteration method itself has side-effect, e.g. IO#each_line.;T@o; ;[I"YFrozenError will be raised if these methods are called against a frozen enumerator. ;TI"ISince +rewind+ and +feed+ also change state for external iteration, ;TI"-these methods may raise FrozenError too.;T@o; ;[I"HExternal iteration differs *significantly* from internal iteration ;TI"due to using a Fiber:;To;;; ;[ o;;0;[o; ;[I"CThe Fiber adds some overhead compared to internal enumeration.;To;;0;[o; ;[I"OThe stacktrace will only include the stack from the Enumerator, not above.;To;;0;[o; ;[I"LFiber-local variables are *not* inherited inside the Enumerator Fiber, ;TI"8which instead starts with no Fiber-local variables.;To;;0;[o; ;[I">Fiber storage variables *are* inherited and are designed ;TI"Hto handle Enumerator Fibers. Assigning to a Fiber storage variable ;TI"Donly affects the current Fiber, so if you want to change state ;TI"Ein the caller Fiber of the Enumerator Fiber, you need to use an ;TI"Cextra indirection (e.g., use some object in the Fiber storage ;TI"*variable and mutate some ivar of it).;T@o; ;[I"Concretely:;T@o;;[I"&Thread.current[:fiber_local] = 1 ;TI"Fiber[:storage_var] = 1 ;TI"e = Enumerator.new do |y| ;TI"_ p Thread.current[:fiber_local] # for external iteration: nil, for internal iteration: 1 ;TI"/ p Fiber[:storage_var] # => 1, inherited ;TI" Fiber[:storage_var] += 1 ;TI" y << 42 ;TI" end ;TI" ;TI"p e.next # => 42 ;TI"@p Fiber[:storage_var] # => 1 (it ran in a different Fiber) ;TI" ;TI"e.each { p _1 } ;TI"Zp Fiber[:storage_var] # => 2 (it ran in the same Fiber/"stack" as the current Fiber) ;T;0S;;i;I"5Convert External Iteration to Internal Iteration;T@o; ;[I"SYou can use an external iterator to implement an internal iterator as follows:;T@o;;["I"def ext_each(e) ;TI" while true ;TI" begin ;TI" vs = e.next_values ;TI" rescue StopIteration ;TI" return $!.result ;TI" end ;TI" y = yield(*vs) ;TI" e.feed y ;TI" end ;TI" end ;TI" ;TI"o = Object.new ;TI" ;TI"def o.each ;TI" puts yield ;TI" puts yield(1) ;TI" puts yield(1, 2) ;TI" 3 ;TI" end ;TI" ;TI"4# use o.each as an internal iterator directly. ;TI"*puts o.each {|*x| puts x; [:b, *x] } ;TI"8# => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3 ;TI" ;TI"2# convert o.each to an external iterator for ;TI"*# implementing an internal iterator. ;TI"7puts ext_each(o.to_enum) {|*x| puts x; [:b, *x] } ;TI"7# => [], [:b], [1], [:b, 1], [1, 2], [:b, 1, 2], 3;T;0: @fileI"enumerator.c;T:0@omit_headings_from_table_of_contents_below0;0;0[ [ [[I"Enumerable;To;;[ ;@�;0I"enumerator.c;T[[I" class;T[[:public[[I"new;T@�[I"produce;T@�[I"product;T@�[:protected[ [:private[ [I" instance;T[[;[[I"+;T@�[I" each;T@�[I"each_with_index;T@�[I"each_with_object;T@�[I" feed;T@�[I"inspect;T@�[I" next;T@�[I"next_values;T@�[I" peek;T@�[I"peek_values;T@�[I"rewind;T@�[I" size;T@�[I"with_index;T@�[I"with_object;T@�[;[ [;[ [ [U:RDoc::Context::Section[i 0o;;[ ;0;0[@�@�cRDoc::TopLevel