FAQ sync.
authorJarkko Hietaniemi <jhi@iki.fi>
Mon, 11 Mar 2002 21:42:58 +0000 (21:42 +0000)
committerJarkko Hietaniemi <jhi@iki.fi>
Mon, 11 Mar 2002 21:42:58 +0000 (21:42 +0000)
p4raw-id: //depot/perl@15179

pod/perlfaq.pod
pod/perlfaq1.pod
pod/perlfaq2.pod
pod/perlfaq4.pod
pod/perlfaq5.pod

index 059dd13..4fc7b8a 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq - frequently asked questions about Perl ($Date: 2002/01/31 04:27:54 $)
+perlfaq - frequently asked questions about Perl ($Date: 2002/03/11 21:32:23 $)
 
 =head1 DESCRIPTION
 
@@ -341,6 +341,10 @@ Why aren't my random numbers random?
 
 =item *
 
+How do I get a random number between X and Y?
+
+=item *
+
 How do I find the week-of-the-year/day-of-the-year?
 
 =item *
index f2154d2..89fe4dd 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq1 - General Questions About Perl ($Revision: 1.6 $, $Date: 2002/01/31 01:46:23 $)
+perlfaq1 - General Questions About Perl ($Revision: 1.7 $, $Date: 2002/02/21 14:49:15 $)
 
 =head1 DESCRIPTION
 
@@ -216,7 +216,7 @@ i.e. the current interpreter.  Hence Tom's quip that "Nothing but perl
 can parse Perl."  You may or may not choose to follow this usage.  For
 example, parallelism means "awk and perl" and "Python and Perl" look
 OK, while "awk and Perl" and "Python and perl" do not.  But never
-write "PERL", because perl isn't really an acronym, apocryphal
+write "PERL", because perl is not an acronym, apocryphal
 folklore and post-facto expansions notwithstanding.
 
 =head2 Is it a Perl program or a Perl script?
index da70187..ad7351d 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq2 - Obtaining and Learning about Perl ($Revision: 1.8 $, $Date: 2002/02/08 22:31:57 $)
+perlfaq2 - Obtaining and Learning about Perl ($Revision: 1.9 $, $Date: 2002/03/09 21:01:13 $)
 
 =head1 DESCRIPTION
 
@@ -183,7 +183,7 @@ following groups:
 
     comp.infosystems.www.authoring.cgi         Writing CGI scripts for the Web.
 
-There is also Usenet gateway to Perl mailing lists sponsored by perl.org at 
+There is also Usenet gateway to Perl mailing lists sponsored by perl.org at 
 nntp://nntp.perl.org, or a web interface to the same lists at
 http://nntp.perl.org/group/.  Other groups are listed at 
 http://lists.perl.org.
index 8df3c82..b530516 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq4 - Data Manipulation ($Revision: 1.14 $, $Date: 2002/02/08 22:30:23 $)
+perlfaq4 - Data Manipulation ($Revision: 1.19 $, $Date: 2002/03/11 22:15:19 $)
 
 =head1 DESCRIPTION
 
@@ -346,6 +346,20 @@ random numbers, but this takes quite a while.  If you want a better
 pseudorandom generator than comes with your operating system, look at
 ``Numerical Recipes in C'' at http://www.nr.com/ .
 
+=head2 How do I get a random number between X and Y?
+
+Use the following simple function.  It selects a random integer between
+(and possibly including!) the two given integers, e.g.,
+C<random_int_in(50,120)>
+
+   sub random_int_in ($$) {
+     my($min, $max) = @_;
+      # Assumes that the two arguments are integers themselves!
+     return $min if $min == $max;
+     ($min, $max) = ($max, $min)  if  $min > $max;
+     return $min + int rand(1 + $max - $min);
+   }
+
 =head1 Data: Dates
 
 =head2 How do I find the week-of-the-year/day-of-the-year?
@@ -690,6 +704,11 @@ integers:
     while ($string =~ /-\d+/g) { $count++ }
     print "There are $count negative numbers in the string";
 
+Another version uses a global match in list context, then assigns the
+result to a scalar, producing a count of the number of matches.
+
+       $count = () = $string =~ /-\d+/g;
+
 =head2 How do I capitalize all the words on one line?
 
 To make the first letter of each word upper case:
@@ -1125,11 +1144,11 @@ designed to answer this question quickly and efficiently.  Arrays aren't.
 
 That being said, there are several ways to approach this.  If you
 are going to make this query many times over arbitrary string values,
-the fastest way is probably to invert the original array and keep an
-associative array lying about whose keys are the first array's values.
+the fastest way is probably to invert the original array and maintain a
+hash whose keys are the first array's values.
 
     @blues = qw/azure cerulean teal turquoise lapis-lazuli/;
-    undef %is_blue;
+    %is_blue = ();
     for (@blues) { $is_blue{$_} = 1 }
 
 Now you can check whether $is_blue{$some_color}.  It might have been a
@@ -1139,7 +1158,7 @@ If the values are all small integers, you could use a simple indexed
 array.  This kind of an array will take up less space:
 
     @primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31);
-    undef @is_tiny_prime;
+    @is_tiny_prime = ();
     for (@primes) { $is_tiny_prime[$_] = 1 }
     # or simply  @istiny_prime[@primes] = (1) x @primes;
 
@@ -1885,9 +1904,9 @@ Assuming that you don't care about IEEE notations like "NaN" or
    if (/^-?\d+$/)       { print "is an integer\n" }
    if (/^[+-]?\d+$/)    { print "is a +/- integer\n" }
    if (/^-?\d+\.?\d*$/) { print "is a real number\n" }
-   if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal number" }
+   if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print "is a decimal number\n" }
    if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
-                       { print "a C float" }
+                       { print "a C float\n" }
 
 If you're on a POSIX system, Perl's supports the C<POSIX::strtod>
 function.  Its semantics are somewhat cumbersome, so here's a C<getnum>
index 93a5ffe..9863334 100644 (file)
@@ -1,6 +1,6 @@
 =head1 NAME
 
-perlfaq5 - Files and Formats ($Revision: 1.9 $, $Date: 2002/02/11 19:30:21 $)
+perlfaq5 - Files and Formats ($Revision: 1.12 $, $Date: 2002/03/11 22:25:25 $)
 
 =head1 DESCRIPTION
 
@@ -350,37 +350,23 @@ See L<perlform/"Accessing Formatting Internals"> for an swrite() function.
 
 =head2 How can I output my numbers with commas added?
 
-This one will do it for you:
+This one from Benjamin Goldberg will do it for you:
 
-    sub commify {
-        my $number = shift;
-       1 while ($number =~ s/^([-+]?\d+)(\d{3})/$1,$2/);
-       return $number;
-    }
-
-    $n = 23659019423.2331;
-    print "GOT: ", commify($n), "\n";
-
-    GOT: 23,659,019,423.2331
-
-You can't just:
-
-    s/^([-+]?\d+)(\d{3})/$1,$2/g;
+   s/(^[-+]?\d+?(?=(?>(?:\d{3})+)(?!\d))|\G\d{3}(?=\d))/$1,/g;
 
-because you have to put the comma in and then recalculate your
-position.
+or written verbosely:
 
-Alternatively, this code commifies all numbers in a line regardless of
-whether they have decimal portions, are preceded by + or -, or
-whatever:
-
-    # from Andrew Johnson <ajohnson@gpu.srv.ualberta.ca>
-    sub commify {
-       my $input = shift;
-        $input = reverse $input;
-        $input =~ s<(\d\d\d)(?=\d)(?!\d*\.)><$1,>g;
-        return scalar reverse $input;
-    }
+   s/(
+       ^[-+]?            # beginning of number.
+       \d{1,3}?          # first digits before first comma
+       (?=               # followed by, (but not included in the match) :
+          (?>(?:\d{3})+) # some positive multiple of three digits.
+          (?!\d)         # an *exact* multiple, not x * 3 + 1 or whatever.
+       )
+      |                  # or:
+       \G\d{3}           # after the last group, get three digits
+       (?=\d)            # but they have to have more digits after them.
+   )/$1,/xg;
 
 =head2 How can I translate tildes (~) in a filename?
 
@@ -501,35 +487,24 @@ best therefore to use glob() only in list context.
 
 Normally perl ignores trailing blanks in filenames, and interprets
 certain leading characters (or a trailing "|") to mean something
-special.  To avoid this, you might want to use a routine like the one below.
-It turns incomplete pathnames into explicit relative ones, and tacks a
-trailing null byte on the name to make perl leave it alone:
-
-    sub safe_filename {
-       local $_  = shift;
-        s#^([^./])#./$1#;
-        $_ .= "\0";
-       return $_;
-    }
+special. 
 
-    $badpath = "<<<something really wicked   ";
-    $fn = safe_filename($badpath");
-    open(FH, "> $fn") or "couldn't open $badpath: $!";
+The three argument form of open() lets you specify the mode
+separately from the filename.  The open() function treats
+special mode characters and whitespace in the filename as 
+literals
 
-This assumes that you are using POSIX (portable operating systems
-interface) paths.  If you are on a closed, non-portable, proprietary
-system, you may have to adjust the C<"./"> above.
+       open FILE, "<", "  file  ";  # filename is "   file   "
+       open FILE, ">", ">file";     # filename is ">file"
+       
 
-It would be a lot clearer to use sysopen(), though:
+It may be a lot clearer to use sysopen(), though:
 
     use Fcntl;
     $badpath = "<<<something really wicked   ";
     sysopen (FH, $badpath, O_WRONLY | O_CREAT | O_TRUNC)
        or die "can't open $badpath: $!";
 
-For more information, see also the new L<perlopentut> if you have it
-(new for 5.6).
-
 =head2 How can I reliably rename a file?
 
 If your operating system supports a proper mv(1) utility or its functional
@@ -688,14 +663,17 @@ Don't forget them or you'll be quite sorry.
 
 =head2 How do I get a file's timestamp in perl?
 
-If you want to retrieve the time at which the file was last read,
-written, or had its meta-data (owner, etc) changed, you use the B<-M>,
-B<-A>, or B<-C> file test operations as documented in L<perlfunc>.  These
-retrieve the age of the file (measured against the start-time of your
-program) in days as a floating point number.  To retrieve the "raw"
-time in seconds since the epoch, you would call the stat function,
-then use localtime(), gmtime(), or POSIX::strftime() to convert this
-into human-readable form.
+If you want to retrieve the time at which the file was last
+read, written, or had its meta-data (owner, etc) changed,
+you use the B<-M>, B<-A>, or B<-C> file test operations as
+documented in L<perlfunc>.  These retrieve the age of the
+file (measured against the start-time of your program) in
+days as a floating point number. Some platforms may not have
+all of these times.  See L<perlport> for details. To
+retrieve the "raw" time in seconds since the epoch, you
+would call the stat function, then use localtime(),
+gmtime(), or POSIX::strftime() to convert this into
+human-readable form.
 
 Here's an example: