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;
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:
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
=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?
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