diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 19:43:11 +0000 |
commit | fc22b3d6507c6745911b9dfcc68f1e665ae13dbc (patch) | |
tree | ce1e3bce06471410239a6f41282e328770aa404a /upstream/mageia-cauldron/man1/perllol.1 | |
parent | Initial commit. (diff) | |
download | manpages-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.1 | 464 |
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 |