Only all-upper case "special" POD sections
[p5sagit/p5-mst-13.2.git] / pod / perlfaq4.pod
index df813da..f671b62 100644 (file)
@@ -21,7 +21,7 @@ L<perlnumber> shows the gory details of number representations and
 conversions.
 
 To limit the number of decimal places in your numbers, you can use the
-printf or sprintf function.  See the L<"Floating Point
+C<printf> or C<sprintf> function.  See the L<"Floating Point
 Arithmetic"|perlop> for more details.
 
        printf "%.2f", 10/3;
@@ -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:
 
@@ -533,35 +533,30 @@ you'll still end up on the previous calendar day, although not at
 noon. Since you don't care about the time, the one hour difference
 doesn't matter and you end up with the previous date.
 
-=head2 Does Perl have a Year 2000 problem? Is Perl Y2K compliant?
+=head2 Does Perl have a Year 2000 or 2038 problem? Is Perl Y2K compliant?
 
-Short answer: No, Perl does not have a Year 2000 problem.  Yes, Perl is
-Y2K compliant (whatever that means). The programmers you've hired to
-use it, however, probably are not.
+(contributed by brian d foy)
+
+Perl itself never had a Y2K problem, although that never stopped people
+from creating Y2K problems on their own. See the documentation for
+C<localtime> for its proper use.
 
-Long answer: The question belies a true understanding of the issue.
-Perl is just as Y2K compliant as your pencil--no more, and no less.
-Can you use your pencil to write a non-Y2K-compliant memo?  Of course
-you can.  Is that the pencil's fault?  Of course it isn't.
+Starting with Perl 5.11, C<localtime> and C<gmtime> can handle dates past 
+03:14:08 January 19, 2038, when a 32-bit based time would overflow. You
+still might get a warning on a 32-bit C<perl>:
 
-The date and time functions supplied with Perl (gmtime and localtime)
-supply adequate information to determine the year well beyond 2000
-(2038 is when trouble strikes for 32-bit machines).  The year returned
-by these functions when used in a list context is the year minus 1900.
-For years between 1910 and 1999 this I<happens> to be a 2-digit decimal
-number. To avoid the year 2000 problem simply do not treat the year as
-a 2-digit number.  It isn't.
+       % perl5.11.2 -E 'say scalar localtime( 0x9FFF_FFFFFFFF )'
+       Integer overflow in hexadecimal number at -e line 1.
+       Wed Nov  1 19:42:39 5576711
 
-When gmtime() and localtime() are used in scalar context they return
-a timestamp string that contains a fully-expanded year.  For example,
-C<$timestamp = gmtime(1005613200)> sets $timestamp to "Tue Nov 13 01:00:00
-2001".  There's no year 2000 problem here.
+On a 64-bit C<perl>, you can get even larger dates for those really long
+running projects:
 
-That doesn't mean that Perl can't be used to create non-Y2K compliant
-programs.  It can.  But so can your pencil.  It's the fault of the user,
-not the language.  At the risk of inflaming the NRA: "Perl doesn't
-break Y2K, people do."  See http://www.perl.org/about/y2k.html for
-a longer exposition.
+       % perl5.11.2 -E 'say scalar gmtime( 0x9FFF_FFFFFFFF )'
+       Thu Nov  2 00:42:39 5576711
+
+You're still out of luck if you need to keep tracking of decaying protons
+though.
 
 =head1 Data: Strings
 
@@ -1202,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
 
-As a side note, there's no such thing as a list in scalar context.
-When you say
+You can change an array element, but you can't change a list element:
 
-       $scalar = (2, 5, 7, 9);
+       $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!
+               }
 
-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.
+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.
+
+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:
+
+       my $scalar = ( 'dog', 'cat', 'bird' );  # $scalar gets bird
+
+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?
 
@@ -2502,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