.\" Automatically generated by Pod::Man 2.22 (Pod::Simple 3.07) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .ie \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .el \{\ . de IX .. .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Syntax::Keyword::Gather 3pm" .TH Syntax::Keyword::Gather 3pm "2011-02-25" "perl v5.10.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Syntax::Keyword::Gather \- Provide a gather keyword .SH "VERSION" .IX Header "VERSION" version 1.001000 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 1 \& use Syntax::Keyword::Gather; \& \& my @list = gather { \& # Try to extract odd numbers and odd number names... \& for (@data) { \& if (/(one|three|five|seven|nine)$/) { take qq{\*(Aq$_\*(Aq} } \& elsif (/^\ed+$/ && $_ %2) { take $_ } \& } \& # But use the default set if there aren\*(Aqt any of either... \& take @defaults unless gathered; \& } .Ve .PP or to use the stuff that Sub::Exporter gives us, try .PP .Vb 5 \& # this is a silly idea \& use syntax gather => { \& gather => { \-as => \*(Aqbake\*(Aq }, \& take => { \-as => \*(Aqcake\*(Aq }, \& }; \& \& my @vals = bake { cake (1...10) }; .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Perl 6 provides a new control structure \*(-- \f(CW\*(C`gather\*(C'\fR \*(-- that allows lists to be constructed procedurally, without the need for a temporary variable. Within the block/closure controlled by a \f(CW\*(C`gather\*(C'\fR any call to \&\f(CW\*(C`take\*(C'\fR pushes that call's argument list to an implicitly created array. \&\f(CW\*(C`take\*(C'\fR returns the number of elements it took. This module implements that control structure. .PP At the end of the block's execution, the \f(CW\*(C`gather\*(C'\fR returns the list of values stored in the array (in a list context) or a reference to the array (in a scalar context). .PP For example, instead of writing: .PP .Vb 9 \& print do { \& my @wanted; \& while (my $line = <>) { \& push @wanted, $line if $line =~ /\eD/; \& push @wanted, \-$line if some_other_condition($line); \& } \& push @wanted, \*(AqEOF\*(Aq; \& join q{, }, @wanted; \& }; .Ve .PP instead we can write: .PP .Vb 7 \& print join q{, }, gather { \& while (my $line = <>) { \& take $line if $line =~ /\eD/; \& take \-$line if some_other_condition($line); \& } \& take \*(AqEOF\*(Aq; \& } .Ve .PP and instead of: .PP .Vb 9 \& my $text = do { \& my $string; \& while (<>) { \& next if /^#|^\es*$/; \& last if /^_\|_[DATA|END]_\|_\en$/; \& $string .= $_; \& } \& $string; \& }; .Ve .PP we could write: .PP .Vb 7 \& my $text = join q{}, gather { \& while (<>) { \& next if /^#|^\es*$/; \& last if /^_\|_[DATA|END]_\|_\en$/; \& take $_; \& } \& }; .Ve .PP There is also a third function \*(-- \f(CW\*(C`gathered\*(C'\fR \*(-- which returns a reference to the implicit array being gathered. This is useful for handling defaults: .PP .Vb 7 \& my @odds = gather { \& for @data { \& take $_ if $_ % 2; \& take to_num($_) if /[one|three|five|nine]$/; \& } \& take (1,3,5,7,9) unless gathered; \& } .Ve .PP Note that \*(-- as the example above implies \*(-- the \f(CW\*(C`gathered\*(C'\fR function returns a special Perl 5 array reference that acts like a Perl 6 array reference in boolean, numeric, and string contexts. .PP It's also handy for creating the implicit array by some process more complex than by simple sequential pushing. For example, if we needed to prepend a count of non-numeric items: .PP .Vb 7 \& my @odds = gather { \& for @data { \& take $_ if $_ %2; \& take to_num($_) if /[one|three|five|seven|nine]$/; \& } \& unshift gathered, +grep(/[a\-z]/i, @data); \& } .Ve .PP Conceptually \f(CW\*(C`gather\*(C'\fR/\f(CW\*(C`take\*(C'\fR is the generalized form from which both \&\f(CW\*(C`map\*(C'\fR and \f(CW\*(C`grep\*(C'\fR derive. That is, we could implement those two functions as: .PP .Vb 3 \& sub map (&@) { \& my $coderef = shift; \& my @list = @{shift @_}; \& \& return gather { \& take $coderef\->($_) for (@list) \& }; \& } \& \& sub grep (&@) { \& my $coderef = shift; \& my @list = @{shift @_}; \& \& return gather { \& take $_ if $coderef\->($_) for @list \& }; \& } .Ve .PP A \f(CW\*(C`gather\*(C'\fR is also a very handy way of short-circuiting the construction of a list. For example, suppose we wanted to generate a single sorted list of lines from two sorted files, but only up to the first line they have in common. We could gather the lines like this: .PP .Vb 10 \& my @merged_diff = gather { \& my $a = <$fh_a>; \& my $b = <$fh_b>; \& while (1) { \& if ( defined $a && defined $b ) { \& if ($a eq $b) { last } # Duplicate means end of list \& elsif ($a lt $b) { take $a; $a = <$fh_a>; } \& else { take $b; $b = <$fh_b>; } \& } \& elsif (defined $a) { take $a; $a = <$fh_a>; } \& elsif (defined $b) { take $b; $b = <$fh_b>; } \& else { last } \& } \& } .Ve .SH "NAME" Syntax::Keyword::Gather \- Implements the Perl 6 'gather/take' control structure in Perl 5 .SH "HISTORY" .IX Header "HISTORY" This module was forked from Damian Conway's Perl6::Gather for a few reasons. .IP "to avoid the slightly incendiary name =item to avoid the use of the Perl6::Exporter =item ~ doesn't overload to mean string context =item to no longer takes the current topic ($_)" 1 .IX Item "to avoid the slightly incendiary name =item to avoid the use of the Perl6::Exporter =item ~ doesn't overload to mean string context =item to no longer takes the current topic ($_)" .PP The last item is actually due to an unintended side-effect of the fact that if \&\f(CW\*(C`take\*(C'\fR has an array of zero length it takes \f(CW$_\fR, which is suprising at the very least. I'll fix that issue if I can. .SH "BUGS AND IRRITATIONS" .IX Header "BUGS AND IRRITATIONS" It would be nice to be able to code the default case as: .PP .Vb 6 \& my @odds = gather { \& for (@data) { \& take if $_ % 2; \& take to_num($_) if /(?:one|three|five|nine)\ez/; \& } \& } or (1,3,5,7,9); .Ve .PP but Perl 5's \f(CW\*(C`or\*(C'\fR imposes a scalar context on its left argument. This is arguably a bug and definitely an irritation. .SH "AUTHORS" .IX Header "AUTHORS" .IP "\(bu" 4 Arthur Axel \*(L"fREW\*(R" Schmidt .IP "\(bu" 4 Damian Conway .SH "COPYRIGHT AND LICENSE" .IX Header "COPYRIGHT AND LICENSE" This software is copyright (c) 2010 by Arthur Axel \*(L"fREW\*(R" Schmidt. .PP This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.