summaryrefslogtreecommitdiffstats
path: root/upstream/mageia-cauldron/man1/perllol.1
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 19:43:11 +0000
commitfc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch)
treece1e3bce06471410239a6f41282e328770aa404a /upstream/mageia-cauldron/man1/perllol.1
parentInitial commit. (diff)
downloadmanpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.tar.xz
manpages-l10n-fc22b3d6507c6745911b9dfcc68f1e665ae13dbc.zip
Adding upstream version 4.22.0.upstream/4.22.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'upstream/mageia-cauldron/man1/perllol.1')
-rw-r--r--upstream/mageia-cauldron/man1/perllol.1464
1 files changed, 464 insertions, 0 deletions
diff --git a/upstream/mageia-cauldron/man1/perllol.1 b/upstream/mageia-cauldron/man1/perllol.1
new file mode 100644
index 00000000..5a441c66
--- /dev/null
+++ b/upstream/mageia-cauldron/man1/perllol.1
@@ -0,0 +1,464 @@
+.\" -*- mode: troff; coding: utf-8 -*-
+.\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43)
+.\"
+.\" 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
+..
+.\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>.
+.ie n \{\
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds C`
+. ds C'
+'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 >0, 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.
+.\"
+.\" Avoid warning from groff about undefined register 'F'.
+.de IX
+..
+.nr rF 0
+.if \n(.g .if rF .nr rF 1
+.if (\n(rF:(\n(.g==0)) \{\
+. if \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. if !\nF==2 \{\
+. nr % 0
+. nr F 2
+. \}
+. \}
+.\}
+.rr rF
+.\" ========================================================================
+.\"
+.IX Title "PERLLOL 1"
+.TH PERLLOL 1 2023-11-28 "perl v5.38.2" "Perl Programmers Reference Guide"
+.\" 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
+perllol \- Manipulating Arrays of Arrays in Perl
+.SH DESCRIPTION
+.IX Header "DESCRIPTION"
+.SS "Declaration and Access of Arrays of Arrays"
+.IX Subsection "Declaration and Access of Arrays of Arrays"
+The simplest two-level data structure to build in Perl is an array of
+arrays, sometimes casually called a list of lists. It's reasonably easy to
+understand, and almost everything that applies here will also be applicable
+later on with the fancier data structures.
+.PP
+An array of an array is just a regular old array \f(CW@AoA\fR that you can
+get at with two subscripts, like \f(CW\*(C`$AoA[3][2]\*(C'\fR. Here's a declaration
+of the array:
+.PP
+.Vb 1
+\& use v5.10; # so we can use say()
+\&
+\& # assign to our array, an array of array references
+\& @AoA = (
+\& [ "fred", "barney", "pebbles", "bambam", "dino", ],
+\& [ "george", "jane", "elroy", "judy", ],
+\& [ "homer", "bart", "marge", "maggie", ],
+\& );
+\& say $AoA[2][1];
+\& bart
+.Ve
+.PP
+Now you should be very careful that the outer bracket type
+is a round one, that is, a parenthesis. That's because you're assigning to
+an \f(CW@array\fR, so you need parentheses. If you wanted there \fInot\fR to be an \f(CW@AoA\fR,
+but rather just a reference to it, you could do something more like this:
+.PP
+.Vb 8
+\& # assign a reference to array of array references
+\& $ref_to_AoA = [
+\& [ "fred", "barney", "pebbles", "bambam", "dino", ],
+\& [ "george", "jane", "elroy", "judy", ],
+\& [ "homer", "bart", "marge", "maggie", ],
+\& ];
+\& say $ref_to_AoA\->[2][1];
+\& bart
+.Ve
+.PP
+Notice that the outer bracket type has changed, and so our access syntax
+has also changed. That's because unlike C, in perl you can't freely
+interchange arrays and references thereto. \f(CW$ref_to_AoA\fR is a reference to an
+array, whereas \f(CW@AoA\fR is an array proper. Likewise, \f(CW$AoA[2]\fR is not an
+array, but an array ref. So how come you can write these:
+.PP
+.Vb 2
+\& $AoA[2][2]
+\& $ref_to_AoA\->[2][2]
+.Ve
+.PP
+instead of having to write these:
+.PP
+.Vb 2
+\& $AoA[2]\->[2]
+\& $ref_to_AoA\->[2]\->[2]
+.Ve
+.PP
+Well, that's because the rule is that on adjacent brackets only (whether
+square or curly), you are free to omit the pointer dereferencing arrow.
+But you cannot do so for the very first one if it's a scalar containing
+a reference, which means that \f(CW$ref_to_AoA\fR always needs it.
+.SS "Growing Your Own"
+.IX Subsection "Growing Your Own"
+That's all well and good for declaration of a fixed data structure,
+but what if you wanted to add new elements on the fly, or build
+it up entirely from scratch?
+.PP
+First, let's look at reading it in from a file. This is something like
+adding a row at a time. We'll assume that there's a flat file in which
+each line is a row and each word an element. If you're trying to develop an
+\&\f(CW@AoA\fR array containing all these, here's the right way to do that:
+.PP
+.Vb 4
+\& while (<>) {
+\& @tmp = split;
+\& push @AoA, [ @tmp ];
+\& }
+.Ve
+.PP
+You might also have loaded that from a function:
+.PP
+.Vb 3
+\& for $i ( 1 .. 10 ) {
+\& $AoA[$i] = [ somefunc($i) ];
+\& }
+.Ve
+.PP
+Or you might have had a temporary variable sitting around with the
+array in it.
+.PP
+.Vb 4
+\& for $i ( 1 .. 10 ) {
+\& @tmp = somefunc($i);
+\& $AoA[$i] = [ @tmp ];
+\& }
+.Ve
+.PP
+It's important you make sure to use the \f(CW\*(C`[ ]\*(C'\fR array reference
+constructor. That's because this wouldn't work:
+.PP
+.Vb 1
+\& $AoA[$i] = @tmp; # WRONG!
+.Ve
+.PP
+The reason that doesn't do what you want is because assigning a
+named array like that to a scalar is taking an array in scalar
+context, which means just counts the number of elements in \f(CW@tmp\fR.
+.PP
+If you are running under \f(CW\*(C`use strict\*(C'\fR (and if you aren't, why in
+the world aren't you?), you'll have to add some declarations to
+make it happy:
+.PP
+.Vb 6
+\& use strict;
+\& my(@AoA, @tmp);
+\& while (<>) {
+\& @tmp = split;
+\& push @AoA, [ @tmp ];
+\& }
+.Ve
+.PP
+Of course, you don't need the temporary array to have a name at all:
+.PP
+.Vb 3
+\& while (<>) {
+\& push @AoA, [ split ];
+\& }
+.Ve
+.PP
+You also don't have to use \fBpush()\fR. You could just make a direct assignment
+if you knew where you wanted to put it:
+.PP
+.Vb 5
+\& my (@AoA, $i, $line);
+\& for $i ( 0 .. 10 ) {
+\& $line = <>;
+\& $AoA[$i] = [ split " ", $line ];
+\& }
+.Ve
+.PP
+or even just
+.PP
+.Vb 4
+\& my (@AoA, $i);
+\& for $i ( 0 .. 10 ) {
+\& $AoA[$i] = [ split " ", <> ];
+\& }
+.Ve
+.PP
+You should in general be leery of using functions that could
+potentially return lists in scalar context without explicitly stating
+such. This would be clearer to the casual reader:
+.PP
+.Vb 4
+\& my (@AoA, $i);
+\& for $i ( 0 .. 10 ) {
+\& $AoA[$i] = [ split " ", scalar(<>) ];
+\& }
+.Ve
+.PP
+If you wanted to have a \f(CW$ref_to_AoA\fR variable as a reference to an array,
+you'd have to do something like this:
+.PP
+.Vb 3
+\& while (<>) {
+\& push @$ref_to_AoA, [ split ];
+\& }
+.Ve
+.PP
+Now you can add new rows. What about adding new columns? If you're
+dealing with just matrices, it's often easiest to use simple assignment:
+.PP
+.Vb 5
+\& for $x (1 .. 10) {
+\& for $y (1 .. 10) {
+\& $AoA[$x][$y] = func($x, $y);
+\& }
+\& }
+\&
+\& for $x ( 3, 7, 9 ) {
+\& $AoA[$x][20] += func2($x);
+\& }
+.Ve
+.PP
+It doesn't matter whether those elements are already
+there or not: it'll gladly create them for you, setting
+intervening elements to \f(CW\*(C`undef\*(C'\fR as need be.
+.PP
+If you wanted just to append to a row, you'd have
+to do something a bit funnier looking:
+.PP
+.Vb 2
+\& # add new columns to an existing row
+\& push $AoA[0]\->@*, "wilma", "betty"; # explicit deref
+.Ve
+.SS "Access and Printing"
+.IX Subsection "Access and Printing"
+Now it's time to print your data structure out. How
+are you going to do that? Well, if you want only one
+of the elements, it's trivial:
+.PP
+.Vb 1
+\& print $AoA[0][0];
+.Ve
+.PP
+If you want to print the whole thing, though, you can't
+say
+.PP
+.Vb 1
+\& print @AoA; # WRONG
+.Ve
+.PP
+because you'll get just references listed, and perl will never
+automatically dereference things for you. Instead, you have to
+roll yourself a loop or two. This prints the whole structure,
+using the shell-style \fBfor()\fR construct to loop across the outer
+set of subscripts.
+.PP
+.Vb 3
+\& for $aref ( @AoA ) {
+\& say "\et [ @$aref ],";
+\& }
+.Ve
+.PP
+If you wanted to keep track of subscripts, you might do this:
+.PP
+.Vb 3
+\& for $i ( 0 .. $#AoA ) {
+\& say "\et elt $i is [ @{$AoA[$i]} ],";
+\& }
+.Ve
+.PP
+or maybe even this. Notice the inner loop.
+.PP
+.Vb 5
+\& for $i ( 0 .. $#AoA ) {
+\& for $j ( 0 .. $#{$AoA[$i]} ) {
+\& say "elt $i $j is $AoA[$i][$j]";
+\& }
+\& }
+.Ve
+.PP
+As you can see, it's getting a bit complicated. That's why
+sometimes is easier to take a temporary on your way through:
+.PP
+.Vb 6
+\& for $i ( 0 .. $#AoA ) {
+\& $aref = $AoA[$i];
+\& for $j ( 0 .. $#{$aref} ) {
+\& say "elt $i $j is $AoA[$i][$j]";
+\& }
+\& }
+.Ve
+.PP
+Hmm... that's still a bit ugly. How about this:
+.PP
+.Vb 7
+\& for $i ( 0 .. $#AoA ) {
+\& $aref = $AoA[$i];
+\& $n = @$aref \- 1;
+\& for $j ( 0 .. $n ) {
+\& say "elt $i $j is $AoA[$i][$j]";
+\& }
+\& }
+.Ve
+.PP
+When you get tired of writing a custom print for your data structures,
+you might look at the standard Dumpvalue or Data::Dumper modules.
+The former is what the Perl debugger uses, while the latter generates
+parsable Perl code. For example:
+.PP
+.Vb 1
+\& use v5.14; # using the + prototype, new to v5.14
+\&
+\& sub show(+) {
+\& require Dumpvalue;
+\& state $prettily = new Dumpvalue::
+\& tick => q("),
+\& compactDump => 1, # comment these two lines
+\& # out
+\& veryCompact => 1, # if you want a bigger
+\& # dump
+\& ;
+\& dumpValue $prettily @_;
+\& }
+\&
+\& # Assign a list of array references to an array.
+\& my @AoA = (
+\& [ "fred", "barney" ],
+\& [ "george", "jane", "elroy" ],
+\& [ "homer", "marge", "bart" ],
+\& );
+\& push $AoA[0]\->@*, "wilma", "betty";
+\& show @AoA;
+.Ve
+.PP
+will print out:
+.PP
+.Vb 3
+\& 0 0..3 "fred" "barney" "wilma" "betty"
+\& 1 0..2 "george" "jane" "elroy"
+\& 2 0..2 "homer" "marge" "bart"
+.Ve
+.PP
+Whereas if you comment out the two lines I said you might wish to,
+then it shows it to you this way instead:
+.PP
+.Vb 10
+\& 0 ARRAY(0x8031d0)
+\& 0 "fred"
+\& 1 "barney"
+\& 2 "wilma"
+\& 3 "betty"
+\& 1 ARRAY(0x803d40)
+\& 0 "george"
+\& 1 "jane"
+\& 2 "elroy"
+\& 2 ARRAY(0x803e10)
+\& 0 "homer"
+\& 1 "marge"
+\& 2 "bart"
+.Ve
+.SS Slices
+.IX Subsection "Slices"
+If you want to get at a slice (part of a row) in a multidimensional
+array, you're going to have to do some fancy subscripting. That's
+because while we have a nice synonym for single elements via the
+pointer arrow for dereferencing, no such convenience exists for slices.
+.PP
+Here's how to do one operation using a loop. We'll assume an \f(CW@AoA\fR
+variable as before.
+.PP
+.Vb 5
+\& @part = ();
+\& $x = 4;
+\& for ($y = 7; $y < 13; $y++) {
+\& push @part, $AoA[$x][$y];
+\& }
+.Ve
+.PP
+That same loop could be replaced with a slice operation:
+.PP
+.Vb 1
+\& @part = $AoA[4]\->@[ 7..12 ];
+.Ve
+.PP
+Now, what if you wanted a \fItwo-dimensional slice\fR, such as having
+\&\f(CW$x\fR run from 4..8 and \f(CW$y\fR run from 7 to 12? Hmm... here's the simple way:
+.PP
+.Vb 6
+\& @newAoA = ();
+\& for ($startx = $x = 4; $x <= 8; $x++) {
+\& for ($starty = $y = 7; $y <= 12; $y++) {
+\& $newAoA[$x \- $startx][$y \- $starty] = $AoA[$x][$y];
+\& }
+\& }
+.Ve
+.PP
+We can reduce some of the looping through slices
+.PP
+.Vb 3
+\& for ($x = 4; $x <= 8; $x++) {
+\& push @newAoA, [ $AoA[$x]\->@[ 7..12 ] ];
+\& }
+.Ve
+.PP
+If you were into Schwartzian Transforms, you would probably
+have selected map for that
+.PP
+.Vb 1
+\& @newAoA = map { [ $AoA[$_]\->@[ 7..12 ] ] } 4 .. 8;
+.Ve
+.PP
+Although if your manager accused you of seeking job security (or rapid
+insecurity) through inscrutable code, it would be hard to argue. :\-)
+If I were you, I'd put that in a function:
+.PP
+.Vb 5
+\& @newAoA = splice_2D( \e@AoA, 4 => 8, 7 => 12 );
+\& sub splice_2D {
+\& my $lrr = shift; # ref to array of array refs!
+\& my ($x_lo, $x_hi,
+\& $y_lo, $y_hi) = @_;
+\&
+\& return map {
+\& [ $lrr\->[$_]\->@[ $y_lo .. $y_hi ] ]
+\& } $x_lo .. $x_hi;
+\& }
+.Ve
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+perldata, perlref, perldsc
+.SH AUTHOR
+.IX Header "AUTHOR"
+Tom Christiansen <\fItchrist@perl.com\fR>
+.PP
+Last update: Tue Apr 26 18:30:55 MDT 2011