FAQ
cvsuser 02/10/08 01:05:50

Modified: . perlfaq4.pod
Log:
* Why doesn't & work the way I want it to?
+ change the result of 11 & 3 to the correct one (3)

* How do I find the current century or millennium?
+ mention POSIX::strftime which is a lot easier to read
than the other examples.

* How can I make my hash remember the order I put elements into it?
+ made strict clean

Revision Changes Path
1.33 +19 -10 perlfaq/perlfaq4.pod

Index: perlfaq4.pod
===================================================================
RCS file: /cvs/public/perlfaq/perlfaq4.pod,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -w -r1.32 -r1.33
--- perlfaq4.pod 10 Sep 2002 19:49:38 -0000 1.32
+++ perlfaq4.pod 8 Oct 2002 08:05:50 -0000 1.33
@@ -1,6 +1,6 @@
=head1 NAME

-perlfaq4 - Data Manipulation ($Revision: 1.32 $, $Date: 2002/09/10 19:49:38 $)
+perlfaq4 - Data Manipulation ($Revision: 1.33 $, $Date: 2002/10/08 08:05:50 $)

=head1 DESCRIPTION

@@ -263,7 +263,7 @@
(the number C<3> is treated as the bit pattern C<00000011>).

So, saying C<11 & 3> performs the "and" operation on numbers (yielding
-C<1>). Saying C<"11" & "3"> performs the "and" operation on strings
+C<3>). Saying C<"11" & "3"> performs the "and" operation on strings
(yielding C<"1">).

Most problems with C<&> and C<|> arise because the programmer thinks
@@ -390,11 +390,20 @@
return 1+int((((localtime(shift || time))[5] + 1899))/1000);
}

-On some systems, you'll find that the POSIX module's strftime() function
-has been extended in a non-standard way to use a C<%C> format, which they
-sometimes claim is the "century". It isn't, because on most such systems,
-this is only the first two digits of the four-digit year, and thus cannot
-be used to reliably determine the current century or millennium.
+You can also use the POSIX strftime() function which may be a bit
+slower but is easier to read and maintain.
+
+ use POSIX qw/strftime/;
+
+ my $week_of_the_year = strftime "%W", localtime;
+ my $day_of_the_year = strftime "%j", localtime;
+
+On some systems, the POSIX module's strftime() function has
+been extended in a non-standard way to use a C<%C> format,
+which they sometimes claim is the "century". It isn't,
+because on most such systems, this is only the first two
+digits of the four-digit year, and thus cannot be used to
+reliably determine the current century or millennium.

=head2 How can I compare two dates and find the difference?

@@ -1862,11 +1871,11 @@
Use the Tie::IxHash from CPAN.

use Tie::IxHash;
- tie(%myhash, Tie::IxHash);
- for ($i=0; $i<20; $i++) {
+ tie my %myhash, Tie::IxHash;
+ for (my $i=0; $i<20; $i++) {
$myhash{$i} = 2*$i;
}
- @keys = keys %myhash;
+ my @keys = keys %myhash;
# @keys = (0,1,2,3,...)

=head2 Why does passing a subroutine an undefined element in a hash create it?

Search Discussions

  • Comdog at Oct 23, 2002 at 1:00 am
    cvsuser 02/10/22 18:00:37

    Modified: . perlfaq4.pod
    Log:
    * completely replaced answer with one from Joe Schaefer.
    + emphasis module use (the XS versions are *really* fast)
    + show a pure perl function that is still 5 times faster than
    the previous example

    Revision Changes Path
    1.34 +33 -27 perlfaq/perlfaq4.pod

    Index: perlfaq4.pod
    ===================================================================
    RCS file: /cvs/public/perlfaq/perlfaq4.pod,v
    retrieving revision 1.33
    retrieving revision 1.34
    diff -u -w -r1.33 -r1.34
    --- perlfaq4.pod 8 Oct 2002 08:05:50 -0000 1.33
    +++ perlfaq4.pod 23 Oct 2002 01:00:37 -0000 1.34
    @@ -1,6 +1,6 @@
    =head1 NAME

    -perlfaq4 - Data Manipulation ($Revision: 1.33 $, $Date: 2002/10/08 08:05:50 $)
    +perlfaq4 - Data Manipulation ($Revision: 1.34 $, $Date: 2002/10/23 01:00:37 $)

    =head1 DESCRIPTION

    @@ -1460,34 +1460,40 @@

    =head2 How do I permute N elements of a list?

    -Here's a little program that generates all permutations
    -of all the words on each line of input. The algorithm embodied
    -in the permute() function should work on any list:
    +Use the List::Permutor module on CPAN. If the list is
    +actually an array, try the Algorithm::Permute module (also
    +on CPAN). It's written in XS code and is very efficient.
    +
    + use Algorithm::Permute;
    + my @array = 'a'..'d';
    + my $p_iterator = Algorithm::Permute->new ( \@array );
    + while (my @perm = $p_iterator->next) {
    + print "next permutation: (@perm)\n";
    + }
    +
    +Here's a little program that generates all permutations of
    +all the words on each line of input. The algorithm embodied
    +in the permute() function is discussed in Volume 4 (still
    +unpublished) of Knuth's I<The Art of Computer Programming>
    +and will work on any list:

    #!/usr/bin/perl -n
    - # tsc-permute: permute each word of input
    - permute([split], []);
    - sub permute {
    - my @items = @{ $_[0] };
    - my @perms = @{ $_[1] };
    - unless (@items) {
    - print "@perms\n";
    - } else {
    - my(@newitems,@newperms,$i);
    - foreach $i (0 .. $#items) {
    - @newitems = @items;
    - @newperms = @perms;
    - unshift(@newperms, splice(@newitems, $i, 1));
    - permute([@newitems], [@newperms]);
    - }
    + # Fischer-Kause ordered permutation generator
    +
    + sub permute (&@) {
    + my $code = shift;
    + my @idx = 0..$#_;
    + while ( $code->(@_[@idx]) ) {
    + my $p = $#idx;
    + --$p while $idx[$p-1] > $idx[$p];
    + my $q = $p or return;
    + push @idx, reverse splice @idx, $p;
    + ++$q while $idx[$p-1] > $idx[$q];
    + @idx[$p-1,$q]=@idx[$q,$p-1];
    }
    }

    -Unfortunately, this algorithm is very inefficient. The Algorithm::Permute
    -module from CPAN runs at least an order of magnitude faster. If you don't
    -have a C compiler (or a binary distribution of Algorithm::Permute), then
    -you can use List::Permutor which is written in pure Perl, and is still
    -several times faster than the algorithm above.
    + permute {print"@_\n"} split;

    =head2 How do I sort an array by (anything)?
  • Comdog at Oct 30, 2002 at 6:40 pm
    cvsuser 02/10/30 10:40:34

    Modified: . perlfaq4.pod
    Log:
    this looks like a big patch because i removed the comment characters before
    the bulk of the text. Russ's explanation doesn't need to be code comments.

    * other changes
    + removed the flame-war bait about localtime() - 86400. everywhere
    i saw someone discuss that solution people starting flaming each other over
    all sorts of stuff, i don't think it is a good thing to tell newbies to do.
    i also do not like to start off answers with a wrong answer.
    + start off with a module solution

    Revision Changes Path
    1.35 +51 -49 perlfaq/perlfaq4.pod

    Index: perlfaq4.pod
    ===================================================================
    RCS file: /cvs/public/perlfaq/perlfaq4.pod,v
    retrieving revision 1.34
    retrieving revision 1.35
    diff -u -w -r1.34 -r1.35
    --- perlfaq4.pod 23 Oct 2002 01:00:37 -0000 1.34
    +++ perlfaq4.pod 30 Oct 2002 18:40:34 -0000 1.35
    @@ -1,6 +1,6 @@
    =head1 NAME

    -perlfaq4 - Data Manipulation ($Revision: 1.34 $, $Date: 2002/10/23 01:00:37 $)
    +perlfaq4 - Data Manipulation ($Revision: 1.35 $, $Date: 2002/10/30 18:40:34 $)

    =head1 DESCRIPTION

    @@ -449,18 +449,20 @@

    =head2 How do I find yesterday's date?

    -The C<time()> function returns the current time in seconds since the
    -epoch. Take twenty-four hours off that:
    +If you only need to find the date (and not the same time), you
    +can use the Date::Calc module.

    - $yesterday = time() - ( 24 * 60 * 60 );
    + use Date::Calc qw(Today Add_Delta_Days);

    -Then you can pass this to C<localtime()> and get the individual year,
    -month, day, hour, minute, seconds values.
    + my @date = Add_Delta_Days( Today(), -1 );

    -Note very carefully that the code above assumes that your days are
    -twenty-four hours each. For most people, there are two days a year
    -when they aren't: the switch to and from summer time throws this off.
    -A solution to this issue is offered by Russ Allbery.
    + print "@date\n";
    +
    +Most people try to use the time rather than the calendar to
    +figure out dates, but that assumes that your days are
    +twenty-four hours each. For most people, there are two days
    +a year when they aren't: the switch to and from summer time
    +throws this off. Russ Allbery offers this solution.

    sub yesterday {
    my $now = defined $_[0] ? $_[0] : time;
    @@ -469,38 +471,38 @@
    my $tdst = (localtime $then)[8] > 0;
    $then - ($tdst - $ndst) * 60 * 60;
    }
    - # Should give you "this time yesterday" in seconds since epoch relative to
    - # the first argument or the current time if no argument is given and
    - # suitable for passing to localtime or whatever else you need to do with
    - # it. $ndst is whether we're currently in daylight savings time; $tdst is
    - # whether the point 24 hours ago was in daylight savings time. If $tdst
    - # and $ndst are the same, a boundary wasn't crossed, and the correction
    - # will subtract 0. If $tdst is 1 and $ndst is 0, subtract an hour more
    - # from yesterday's time since we gained an extra hour while going off
    - # daylight savings time. If $tdst is 0 and $ndst is 1, subtract a
    - # negative hour (add an hour) to yesterday's time since we lost an hour.
    - #
    - # All of this is because during those days when one switches off or onto
    - # DST, a "day" isn't 24 hours long; it's either 23 or 25.
    - #
    - # The explicit settings of $ndst and $tdst are necessary because localtime
    - # only says it returns the system tm struct, and the system tm struct at
    - # least on Solaris doesn't guarantee any particular positive value (like,
    - # say, 1) for isdst, just a positive value. And that value can
    - # potentially be negative, if DST information isn't available (this sub
    - # just treats those cases like no DST).
    - #
    - # Note that between 2am and 3am on the day after the time zone switches
    - # off daylight savings time, the exact hour of "yesterday" corresponding
    - # to the current hour is not clearly defined. Note also that if used
    - # between 2am and 3am the day after the change to daylight savings time,
    - # the result will be between 3am and 4am of the previous day; it's
    - # arguable whether this is correct.
    - #
    - # This sub does not attempt to deal with leap seconds (most things don't).
    - #
    - # Copyright relinquished 1999 by Russ Allbery <rra@stanford.edu>
    - # This code is in the public domain
    +
    +Should give you "this time yesterday" in seconds since epoch relative to
    +the first argument or the current time if no argument is given and
    +suitable for passing to localtime or whatever else you need to do with
    +it. $ndst is whether we're currently in daylight savings time; $tdst is
    +whether the point 24 hours ago was in daylight savings time. If $tdst
    +and $ndst are the same, a boundary wasn't crossed, and the correction
    +will subtract 0. If $tdst is 1 and $ndst is 0, subtract an hour more
    +from yesterday's time since we gained an extra hour while going off
    +daylight savings time. If $tdst is 0 and $ndst is 1, subtract a
    +negative hour (add an hour) to yesterday's time since we lost an hour.
    +
    +All of this is because during those days when one switches off or onto
    +DST, a "day" isn't 24 hours long; it's either 23 or 25.
    +
    +The explicit settings of $ndst and $tdst are necessary because localtime
    +only says it returns the system tm struct, and the system tm struct at
    +least on Solaris doesn't guarantee any particular positive value (like,
    +say, 1) for isdst, just a positive value. And that value can
    +potentially be negative, if DST information isn't available (this sub
    +just treats those cases like no DST).
    +
    +Note that between 2am and 3am on the day after the time zone switches
    +off daylight savings time, the exact hour of "yesterday" corresponding
    +to the current hour is not clearly defined. Note also that if used
    +between 2am and 3am the day after the change to daylight savings time,
    +the result will be between 3am and 4am of the previous day; it's
    +arguable whether this is correct.
    +
    +This sub does not attempt to deal with leap seconds (most things don't).
    +
    +

    =head2 Does Perl have a Year 2000 problem? Is Perl Y2K compliant?

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcvs-perlfaq @
categoriesperl
postedOct 8, '02 at 8:05a
activeOct 30, '02 at 6:40p
posts3
users1
websitelearn.perl.org...

1 user in discussion

Comdog: 3 posts

People

Translate

site design / logo © 2018 Grokbase