summaryrefslogtreecommitdiff
path: root/pod/perldsc.pod
diff options
context:
space:
mode:
authorRicardo Signes <rjbs@semiotic.systems>2020-09-06 20:25:23 -0400
committerKarl Williamson <khw@cpan.org>2020-09-06 20:47:53 -0600
commit53e62bf8898afdc5cca37743a682b655dbe42614 (patch)
tree47df42645be7f39ed961bd67031fa7dee72641c8 /pod/perldsc.pod
parent748e249cf0d014c60e338b49bd0ef4c5af880325 (diff)
downloadperl-53e62bf8898afdc5cca37743a682b655dbe42614.tar.gz
perldsc: in general, prefer postfix to circumfix dereference
In all (or almost all) cases, postfix dereferencing is simpler to read and write. This makes it the better choice for teaching new Perl programmers. I have left in reference to circumfix deref, but mostly to acknowledge that it exists, not to suggest its use.
Diffstat (limited to 'pod/perldsc.pod')
-rw-r--r--pod/perldsc.pod83
1 files changed, 47 insertions, 36 deletions
diff --git a/pod/perldsc.pod b/pod/perldsc.pod
index 7564b97ccc..832835b5b5 100644
--- a/pod/perldsc.pod
+++ b/pod/perldsc.pod
@@ -183,31 +183,30 @@ The square brackets make a reference to a new array with a I<copy>
of what's in @array at the time of the assignment. This is what
you want.
-Note that this will produce something similar, but it's
-much harder to read:
+Note that this will produce something similar:
# Either without strict or having an outer-scope my @array;
# declaration.
for my $i (1..10) {
@array = 0 .. $i;
- @{$AoA[$i]} = @array;
+ $AoA[$i]->@* = @array;
}
Is it the same? Well, maybe so--and maybe not. The subtle difference
is that when you assign something in square brackets, you know for sure
it's always a brand new reference with a new I<copy> of the data.
-Something else could be going on in this new case with the C<@{$AoA[$i]}>
-dereference on the left-hand-side of the assignment. It all depends on
-whether C<$AoA[$i]> had been undefined to start with, or whether it
-already contained a reference. If you had already populated @AoA with
-references, as in
+Something else could be going on in this new case with the
+C<< $AoA[$i]->@* >> dereference on the left-hand-side of the assignment.
+It all depends on whether C<$AoA[$i]> had been undefined to start with,
+or whether it already contained a reference. If you had already
+populated @AoA with references, as in
$AoA[3] = \@another_array;
Then the assignment with the indirection on the left-hand-side would
use the existing reference that was already there:
- @{$AoA[3]} = @array;
+ $AoA[3]->@* = @array;
Of course, this I<would> have the "interesting" effect of clobbering
@another_array. (Have you ever noticed how when a programmer says
@@ -241,12 +240,24 @@ much more easily understood constructors C<[]> and C<{}> instead of
relying upon lexical (or dynamic) scoping and hidden reference-counting to
do the right thing behind the scenes.
+Note also that there exists another way to write a dereference! These
+two lines are equivalent:
+
+ $AoA[$i]->@* = @array;
+ @{ $AoA[$i] } = @array;
+
+The first form, called I<postfix dereference> is generally easier to
+read, because the expression can be read from left to right, and there
+are no enclosing braces to balance. On the other hand, it is also
+newer. It was added to the language in 2014, so you will often
+encounter the other form, I<circumfix dereference>, in older code.
+
In summary:
$AoA[$i] = [ @array ]; # usually best
$AoA[$i] = \@array; # perilous; just how my() was that array?
- @{ $AoA[$i] } = @array; # way too tricky for most programmers
-
+ $AoA[$i]->@* = @array; # way too tricky for most programmers
+ @{ $AoA[$i] } = @array; # just as tricky, and also harder to read
=head1 CAVEAT ON PRECEDENCE
X<dereference, precedence> X<dereferencing, precedence>
@@ -269,9 +280,9 @@ dereference the thing at that subscript. That's fine in C, but this isn't C.
The seemingly equivalent construct in Perl, C<$$aref[$i]> first does
the deref of $aref, making it take $aref as a reference to an
array, and then dereference that, and finally tell you the I<i'th> value
-of the array pointed to by $AoA. If you wanted the C notion, you'd have to
-write C<${$AoA[$i]}> to force the C<$AoA[$i]> to get evaluated first
-before the leading C<$> dereferencer.
+of the array pointed to by $AoA. If you wanted the C notion, you could
+write C<< $AoA[$i]->$* >> to explicitly dereference the I<i'th> item,
+reading left to right.
=head1 WHY YOU SHOULD ALWAYS C<use strict>
@@ -364,7 +375,7 @@ X<array of arrays> X<AoA>
}
# add to an existing row
- push @{ $AoA[0] }, "wilma", "betty";
+ push $AoA[0]->@*, "wilma", "betty";
=head2 Access and Printing of an ARRAY OF ARRAYS
@@ -381,7 +392,7 @@ X<array of arrays> X<AoA>
# print the whole thing with indices
for $i ( 0 .. $#AoA ) {
- print "\t [ @{$AoA[$i]} ],\n";
+ print "\t [ $AoA[$i]->@* ],\n";
}
# print the whole thing one at a time
@@ -431,7 +442,7 @@ X<hash of arrays> X<HoA>
}
# append new members to an existing family
- push @{ $HoA{"flintstones"} }, "wilma", "betty";
+ push $HoA{flintstones}->@*, "wilma", "betty";
=head2 Access and Printing of a HASH OF ARRAYS
@@ -443,31 +454,31 @@ X<hash of arrays> X<HoA>
# print the whole thing
foreach $family ( keys %HoA ) {
- print "$family: @{ $HoA{$family} }\n"
+ print "$family: $HoA{$family}->@* \n"
}
# print the whole thing with indices
foreach $family ( keys %HoA ) {
print "family: ";
- foreach $i ( 0 .. $#{ $HoA{$family} } ) {
+ foreach $i ( 0 .. $HoA{$family}->$#* ) {
print " $i = $HoA{$family}[$i]";
}
print "\n";
}
# print the whole thing sorted by number of members
- foreach $family ( sort { @{$HoA{$b}} <=> @{$HoA{$a}} } keys %HoA ) {
- print "$family: @{ $HoA{$family} }\n"
+ foreach $family ( sort { $HoA{$b}->@* <=> $HoA{$a}->@* } keys %HoA ) {
+ print "$family: $HoA{$family}->@* \n"
}
# print the whole thing sorted by number of members and name
foreach $family ( sort {
- @{$HoA{$b}} <=> @{$HoA{$a}}
- ||
- $a cmp $b
+ $HoA{$b}->@* <=> $HoA{$a}->@*
+ ||
+ $a cmp $b
} keys %HoA )
{
- print "$family: ", join(", ", sort @{ $HoA{$family} }), "\n";
+ print "$family: ", join(", ", sort $HoA{$family}->@* ), "\n";
}
=head1 ARRAYS OF HASHES
@@ -548,7 +559,7 @@ X<array of hashes> X<AoH>
# print the whole thing with indices
for $i ( 0 .. $#AoH ) {
print "$i is { ";
- for $role ( keys %{ $AoH[$i] } ) {
+ for $role ( keys $AoH[$i]->%* ) {
print "$role=$AoH[$i]{$role} ";
}
print "}\n";
@@ -640,7 +651,7 @@ X<hash of hashes> X<HoH>
# print the whole thing
foreach $family ( keys %HoH ) {
print "$family: { ";
- for $role ( keys %{ $HoH{$family} } ) {
+ for $role ( keys $HoH{$family}->%* ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
@@ -649,7 +660,7 @@ X<hash of hashes> X<HoH>
# print the whole thing somewhat sorted
foreach $family ( sort keys %HoH ) {
print "$family: { ";
- for $role ( sort keys %{ $HoH{$family} } ) {
+ for $role ( sort keys $HoH{$family}->%* ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
@@ -661,7 +672,7 @@ X<hash of hashes> X<HoH>
keys %HoH )
{
print "$family: { ";
- for $role ( sort keys %{ $HoH{$family} } ) {
+ for $role ( sort keys $HoH{$family}->%* ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
@@ -678,7 +689,7 @@ X<hash of hashes> X<HoH>
print "$family: { ";
# and print these according to rank order
for $role ( sort { $rank{$a} <=> $rank{$b} }
- keys %{ $HoH{$family} } )
+ keys $HoH{$family}->%* )
{
print "$role=$HoH{$family}{$role} ";
}
@@ -709,7 +720,7 @@ many different sorts:
$last = pop @ { $rec->{SEQUENCE} };
print $rec->{LOOKUP}{"key"};
- ($first_k, $first_v) = each %{ $rec->{LOOKUP} };
+ ($first_k, $first_v) = each $rec->{LOOKUP}->%*;
$answer = $rec->{THATCODE}->($arg);
$answer = $rec->{THISCODE}->($arg1, $arg2);
@@ -790,7 +801,7 @@ many different sorts:
foreach $family (keys %TV) {
$rec = $TV{$family}; # temp pointer
@kids = ();
- for $person ( @{ $rec->{members} } ) {
+ for $person ( $rec->{members}->@* ) {
if ($person->{role} =~ /kid|son|daughter/) {
push @kids, $person;
}
@@ -814,14 +825,14 @@ many different sorts:
# print the whole thing
foreach $family ( keys %TV ) {
print "the $family";
- print " is on during @{ $TV{$family}{nights} }\n";
+ print " is on during $TV{$family}{nights}->@*\n";
print "its members are:\n";
- for $who ( @{ $TV{$family}{members} } ) {
+ for $who ( $TV{$family}{members}->@* ) {
print " $who->{name} ($who->{role}), age $who->{age}\n";
}
print "it turns out that $TV{$family}{lead} has ";
- print scalar ( @{ $TV{$family}{kids} } ), " kids named ";
- print join (", ", map { $_->{name} } @{ $TV{$family}{kids} } );
+ print scalar ( $TV{$family}{kids}->@* ), " kids named ";
+ print join (", ", map { $_->{name} } $TV{$family}{kids}->@* );
print "\n";
}