U:RDoc::AnyMethod[iI"slice_before:ETI"Enumerable#slice_before;TF:publico:RDoc::Markup::Document:@parts[o:RDoc::Markup::Paragraph; [I"6Creates an enumerator for each chunked elements. ;TI"EThe beginnings of chunks are defined by _pattern_ and the block.;To:RDoc::Markup::BlankLine o;
; [I"PIf _pattern_ === _elt_
returns true
or the block ;TI"Nreturns true
for the element, the element is beginning of a ;TI"chunk.;T@o;
; [I"SThe ===
and _block_ is called from the first element to the last ;TI"Eelement of _enum_. The result for the first element is ignored.;T@o;
; [I"DThe result enumerator yields the chunked elements as an array. ;TI"/So +each+ method can be called as follows:;T@o:RDoc::Markup::Verbatim; [I"3enum.slice_before(pattern).each { |ary| ... }
;TI"9enum.slice_before { |elt| bool }.each { |ary| ... }
;T:@format0o;
; [I"BOther methods of the Enumerator class and Enumerable module, ;TI"2such as +to_a+, +map+, etc., are also usable.;T@o;
; [I"IFor example, iteration over ChangeLog entries can be implemented as ;TI"
follows:;T@o;; [I"'# iterate over ChangeLog entries.
;TI"open("ChangeLog") { |f|
;TI"0 f.slice_before(/\A\S/).each { |e| pp e }
;TI"}
;TI"
;TI"B# same as above. block is used instead of pattern argument.
;TI"open("ChangeLog") { |f|
;TI"C f.slice_before { |line| /\A\S/ === line }.each { |e| pp e }
;TI"}
;T;
0o;
; [I"@"svn proplist -R" produces multiline output for each file. ;TI"$They can be chunked as follows:;T@o;; [
I"@IO.popen([{"LC_ALL"=>"C"}, "svn", "proplist", "-R"]) { |f|
;TI"? f.lines.slice_before(/\AProp/).each { |lines| p lines }
;TI"}
;TI"E#=> ["Properties on '.':\n", " svn:ignore\n", " svk:merge\n"]
;TI"># ["Properties on 'goruby.c':\n", " svn:eol-style\n"]
;TI"T# ["Properties on 'complex.c':\n", " svn:mime-type\n", " svn:eol-style\n"]
;TI"@# ["Properties on 'regparse.c':\n", " svn:eol-style\n"]
;TI"
# ...
;T;
0o;
; [ I"BIf the block needs to maintain state over multiple elements, ;TI""local variables can be used. ;TI"OFor example, three or more consecutive increasing numbers can be squashed ;TI"5as follows (see +chunk_while+ for a better way):;T@o;; [I"a = [0, 2, 3, 4, 6, 7, 9]
;TI"prev = a[0]
;TI"p a.slice_before { |e|
;TI" prev, prev2 = e, prev
;TI" prev2 + 1 != e
;TI"}.map { |es|
;TI"@ es.length <= 2 ? es.join(",") : "#{es.first}-#{es.last}"
;TI"}.join(",")
;TI"#=> "0,2-4,6,7,9"
;T;
0o;
; [ I"6However local variables should be used carefully ;TI";if the result enumerator is enumerated twice or more. ;TI"EThe local variables should be initialized for each enumeration. ;TI")Enumerator.new can be used to do it.;T@o;; [,I"D# Word wrapping. This assumes all characters have same width.
;TI"#def wordwrap(words, maxwidth)
;TI" Enumerator.new {|y|
;TI"2 # cols is initialized in Enumerator.new.
;TI" cols = 0
;TI"" words.slice_before { |w|
;TI"" cols += 1 if cols != 0
;TI" cols += w.length
;TI" if maxwidth < cols
;TI" cols = w.length
;TI" true
;TI" else
;TI" false
;TI" end
;TI"# }.each {|ws| y.yield ws }
;TI" }
;TI" end
;TI"#text = (1..20).to_a.join(" ")
;TI",enum = wordwrap(text.split(/\s+/), 10)
;TI"puts "-"*10
;TI"?enum.each { |ws| puts ws.join(" ") } # first enumeration.
;TI"puts "-"*10
;TI"cenum.each { |ws| puts ws.join(" ") } # second enumeration generates same result as the first.
;TI"puts "-"*10
;TI"#=> ----------
;TI"# 1 2 3 4 5
;TI"# 6 7 8 9 10
;TI"# 11 12 13
;TI"# 14 15 16
;TI"# 17 18 19
;TI"# 20
;TI"# ----------
;TI"# 1 2 3 4 5
;TI"# 6 7 8 9 10
;TI"# 11 12 13
;TI"# 14 15 16
;TI"# 17 18 19
;TI"# 20
;TI"# ----------
;T;
0o;
; [I"Dmbox contains series of mails which start with Unix From line. ;TI"BSo each mail can be extracted by slice before Unix From line.;T@o;; ["I"# parse mbox
;TI"open("mbox") { |f|
;TI" f.slice_before { |line|
;TI"" line.start_with? "From "
;TI" }.each { |mail|
;TI" unix_from = mail.shift
;TI" i = mail.index("\n")
;TI" header = mail[0...i]
;TI" body = mail[(i+1)..-1]
;TI"' body.pop if body.last == "\n"
;TI"O fields = header.slice_before { |line| !" \t".include?(line[0]) }.to_a
;TI" p unix_from
;TI" pp fields
;TI" pp body
;TI" }
;TI"}
;TI"
;TI"M# split mails in mbox (slice before Unix From line after an empty line)
;TI"open("mbox") { |f|
;TI" emp = true
;TI" f.slice_before { |line|
;TI" prevemp = emp
;TI" emp = line == "\n"
;TI". prevemp && line.start_with?("From ")
;TI" }.each { |mail|
;TI"' mail.pop if mail.last == "\n"
;TI" pp mail
;TI" }
;TI"};T;
0:
@fileI"enum.c;T:0@omit_headings_from_table_of_contents_below0I"enum.slice_before(pattern) -> an_enumerator
enum.slice_before { |elt| bool } -> an_enumerator
;T0[ I" (p1);T@FI"Enumerable;TcRDoc::NormalModule00