diff options
author | brian d foy <bdfoy@cpan.org> | 2010-01-13 16:29:30 +0100 |
---|---|---|
committer | brian d foy <bdfoy@cpan.org> | 2010-01-13 16:29:30 +0100 |
commit | 8d2e243f5816f9d2c4247f962523e4220e4a9ce8 (patch) | |
tree | 0bf3370d386eaeb7d1637928f8aa84853b956c43 /pod/perlfaq4.pod | |
parent | 3b10bc60979cfe9ad677ef795a35603768200ad6 (diff) | |
download | perl-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.pod | 138 |
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 |