summaryrefslogtreecommitdiff
path: root/pod/perlfaq4.pod
diff options
context:
space:
mode:
authorbrian d foy <bdfoy@cpan.org>2010-01-13 16:29:30 +0100
committerbrian d foy <bdfoy@cpan.org>2010-01-13 16:29:30 +0100
commit8d2e243f5816f9d2c4247f962523e4220e4a9ce8 (patch)
tree0bf3370d386eaeb7d1637928f8aa84853b956c43 /pod/perlfaq4.pod
parent3b10bc60979cfe9ad677ef795a35603768200ad6 (diff)
downloadperl-8d2e243f5816f9d2c4247f962523e4220e4a9ce8.tar.gz
* FAQ sync for Perl 5.12 release candidate
This is commit cfc60b072536b6232cec8a3a3551c8bdf3c3eefd from the perlfaq repository at git@github.com:briandfoy/perlfaq.git
Diffstat (limited to 'pod/perlfaq4.pod')
-rw-r--r--pod/perlfaq4.pod138
1 files changed, 101 insertions, 37 deletions
diff --git a/pod/perlfaq4.pod b/pod/perlfaq4.pod
index 5549634af0..5c7e1346eb 100644
--- a/pod/perlfaq4.pod
+++ b/pod/perlfaq4.pod
@@ -62,7 +62,7 @@ are in base 10:
print $string + 44; # prints 688, certainly not octal!
This problem usually involves one of the Perl built-ins that has the
-same name a Unix command that uses octal numbers as arguments on the
+same name a unix command that uses octal numbers as arguments on the
command line. In this example, C<chmod> on the command line knows that
its first argument is octal because that's what it does:
@@ -537,7 +537,7 @@ doesn't matter and you end up with the previous date.
(contributed by brian d foy)
-Perl itself never had a Y2K problem, although that never stopped people
+Perl itself never had a Y2K problem, although that nevers stopped people
from creating Y2K problems on their own. See the documentation for
C<localtime> for its proper use.
@@ -1197,43 +1197,115 @@ indentation correctly preserved:
=head2 What is the difference between a list and an array?
-An array has a changeable length. A list does not. An array is
-something you can push or pop, while a list is a set of values. Some
-people make the distinction that a list is a value while an array is a
-variable. Subroutines are passed and return lists, you put things into
-list context, you initialize arrays with lists, and you C<foreach()>
-across a list. C<@> variables are arrays, anonymous arrays are
-arrays, arrays in scalar context behave like the number of elements in
-them, subroutines access their arguments through the array C<@_>, and
-C<push>/C<pop>/C<shift> only work on arrays.
+(contributed by brian d foy)
+
+A list is a fixed collection of scalars. An array is a variable that
+holds a variable collection of scalars. An array can supply its collection
+for list operations, so list operations also work on arrays:
+
+ # slices
+ ( 'dog', 'cat', 'bird' )[2,3];
+ @animals[2,3];
+
+ # iteration
+ foreach ( qw( dog cat bird ) ) { ... }
+ foreach ( @animals ) { ... }
+
+ my @three = grep { length == 3 } qw( dog cat bird );
+ my @three = grep { length == 3 } @animals;
+
+ # supply an argument list
+ wash_animals( qw( dog cat bird ) );
+ wash_animals( @animals );
+
+Array operations, which change the scalars, reaaranges them, or adds
+or subtracts some scalars, only work on arrays. These can't work on a
+list, which is fixed. Array operations include C<shift>, C<unshift>,
+C<push>, C<pop>, and C<splice>.
+
+An array can also change its length:
+
+ $#animals = 1; # truncate to two elements
+ $#animals = 10000; # pre-extend to 10,001 elements
+
+You can change an array element, but you can't change a list element:
+
+ $animals[0] = 'Rottweiler';
+ qw( dog cat bird )[0] = 'Rottweiler'; # syntax error!
+
+ foreach ( @animals ) {
+ s/^d/fr/; # works fine
+ }
+
+ foreach ( qw( dog cat bird ) ) {
+ s/^d/fr/; # Error! Modification of read only value!
+ }
+
+However, if the list element is itself a variable, it appears that you
+can change a list element. However, the list element is the variable, not
+the data. You're not changing the list element, but something the list
+element refers to. The list element itself doesn't change: it's still
+the same variable.
-As a side note, there's no such thing as a list in scalar context.
-When you say
+You also have to be careful about context. You can assign an array to
+a scalar to get the number of elements in the array. This only works
+for arrays, though:
+
+ my $count = @animals; # only works with arrays
+
+If you try to do the same thing with what you think is a list, you
+get a quite different result. Although it looks like you have a list
+on the righthand side, Perl actually sees a bunch of scalars separated
+by a comma:
- $scalar = (2, 5, 7, 9);
+ my $scalar = ( 'dog', 'cat', 'bird' ); # $scalar gets bird
-you're using the comma operator in scalar context, so it uses the scalar
-comma operator. There never was a list there at all! This causes the
-last value to be returned: 9.
+Since you're assigning to a scalar, the righthand side is in scalar
+context. The comma operator (yes, it's an operator!) in scalar
+context evaluates its lefthand side, throws away the result, and
+evaluates it's righthand side and returns the result. In effect,
+that list-lookalike assigns to C<$scalar> it's rightmost value. Many
+people mess this up becuase they choose a list-lookalike whose
+last element is also the count they expect:
+
+ my $scalar = ( 1, 2, 3 ); # $scalar gets 3, accidentally
=head2 What is the difference between $array[1] and @array[1]?
-The former is a scalar value; the latter an array slice, making
-it a list with one (scalar) value. You should use $ when you want a
-scalar value (most of the time) and @ when you want a list with one
-scalar value in it (very, very rarely; nearly never, in fact).
+(contributed by brian d foy)
+
+The difference is the sigil, that special character in front of the
+array name. The C<$> sigil means "exactly one item", while the C<@>
+sigil means "zero or more items". The C<$> gets you a single scalar,
+while the C<@> gets you a list.
-Sometimes it doesn't make a difference, but sometimes it does.
-For example, compare:
+The confusion arises because people incorrectly assume that the sigil
+denotes the variable type.
- $good[0] = `some program that outputs several lines`;
+The C<$array[1]> is a single-element access to the array. It's going
+to return the item in index 1 (or undef if there is no item there).
+If you intend to get exactly one element from the array, this is the
+form you should use.
-with
+The C<@array[1]> is an array slice, although it has only one index.
+You can pull out multiple elements simultaneously by specifying
+additional indices as a list, like C<@array[1,4,3,0]>.
- @bad[0] = `same program that outputs several lines`;
+Using a slice on the lefthand side of the assignment supplies list
+context to the righthand side. This can lead to unexpected results.
+For instance, if you want to read a single line from a filehandle,
+assigning to a scalar value is fine:
-The C<use warnings> pragma and the B<-w> flag will warn you about these
-matters.
+ $array[1] = <STDIN>;
+
+However, in list context, the line input operator returns all of the
+lines as a list. The first line goes into C<@array[1]> and the rest
+of the lines mysteriously disappear:
+
+ @array[1] = <STDIN>; # most likely not what you want
+
+Either the C<use warnings> pragma or the B<-w> flag will warn you when
+you use an array slice with a single index.
=head2 How can I remove duplicate elements from a list or array?
@@ -2497,17 +2569,9 @@ the C<PDL> module from CPAN instead--it makes number-crunching easy.
See L<http://search.cpan.org/dist/PGPLOT> for the code.
-=head1 REVISION
-
-Revision: $Revision$
-
-Date: $Date$
-
-See L<perlfaq> for source control details and availability.
-
=head1 AUTHOR AND COPYRIGHT
-Copyright (c) 1997-2009 Tom Christiansen, Nathan Torkington, and
+Copyright (c) 1997-2010 Tom Christiansen, Nathan Torkington, and
other authors as noted. All rights reserved.
This documentation is free; you can redistribute it and/or modify it