diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1998-07-22 05:10:53 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1998-07-22 05:10:53 +0000 |
commit | 92c2ed055315fc5be2c58f97c40236945f31f32e (patch) | |
tree | ccace68daba971343b831dfc0ce5fd0e0647e385 /pod/perlfaq4.pod | |
parent | 407eff0f25e20d3ed6ccfe2097b366fd28d8e3c4 (diff) | |
download | perl-92c2ed055315fc5be2c58f97c40236945f31f32e.tar.gz |
perlfaq update from From Tom Christiansen and Nathan Torkington
(removes all mention of training courses from perlfaq*.pod)
p4raw-id: //depot/perl@1621
Diffstat (limited to 'pod/perlfaq4.pod')
-rw-r--r-- | pod/perlfaq4.pod | 145 |
1 files changed, 88 insertions, 57 deletions
diff --git a/pod/perlfaq4.pod b/pod/perlfaq4.pod index 21daac6fc1..0a47145a28 100644 --- a/pod/perlfaq4.pod +++ b/pod/perlfaq4.pod @@ -1,6 +1,6 @@ =head1 NAME -perlfaq4 - Data Manipulation ($Revision: 1.24 $, $Date: 1998/07/05 15:07:20 $) +perlfaq4 - Data Manipulation ($Revision: 1.25 $, $Date: 1998/07/16 22:49:55 $) =head1 DESCRIPTION @@ -17,8 +17,8 @@ only be approximate on a computer, since the computer only has a finite number of bits to store an infinite number of, um, numbers. Internally, your computer represents floating-point numbers in binary. -Floating-point numbers read in from a file, or appearing as literals -in your program, are converted from their decimal floating-point +Floating-point numbers read in from a file or appearing as literals +in your program are converted from their decimal floating-point representation (eg, 19.95) to the internal binary representation. However, 19.95 can't be precisely represented as a binary @@ -61,13 +61,20 @@ umask(), or sysopen(), which all want permissions in octal. =head2 Does perl have a round function? What about ceil() and floor()? Trig functions? -Remember that int() merely truncates toward 0. For rounding to a certain -number of digits, sprintf() or printf() is usually the easiest route. +Remember that int() merely truncates toward 0. For rounding to a +certain number of digits, sprintf() or printf() is usually the easiest +route. + + printf("%.3f", 3.1415926535); # prints 3.142 The POSIX module (part of the standard perl distribution) implements ceil(), floor(), and a number of other mathematical and trigonometric functions. + use POSIX; + $ceil = ceil(3.5); # 4 + $floor = floor(3.5); # 3 + In 5.000 to 5.003 Perls, trigonometry was done in the Math::Complex module. With 5.004, the Math::Trig module (part of the standard perl distribution) implements the trigonometric functions. Internally it @@ -83,7 +90,7 @@ need yourself. =head2 How do I convert bits into ints? -To turn a string of 1s and 0s like '10110110' into a scalar containing +To turn a string of 1s and 0s like C<10110110> into a scalar containing its binary value, use the pack() function (documented in L<perlfunc/"pack">): @@ -135,15 +142,20 @@ Get the http://www.perl.com/CPAN/modules/by-module/Roman module. =head2 Why aren't my random numbers random? -John von Neumann said, ``Anyone who attempts to generate random numbers by -deterministic means is, of course, living in a state of sin.'' - The short explanation is that you're getting pseudorandom numbers, not -random ones, because that's how these things work. A longer explanation -is available on http://www.perl.com/CPAN/doc/FMTEYEWTK/random, courtesy -of Tom Phoenix. - -You should also check out the Math::TrulyRandom module from CPAN. +random ones, because computers are good at being predictable and bad +at being random (despite appearances caused by bugs in your programs +:-). A longer explanation is available on +http://www.perl.com/CPAN/doc/FMTEYEWTK/random, courtesy of Tom +Phoenix. John von Neumann said, ``Anyone who attempts to generate +random numbers by deterministic means is, of course, living in a state +of sin.'' + +You should also check out the Math::TrulyRandom module from CPAN. It +uses the imperfections in your system's timer to generate 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://nr.harvard.edu/nr/bookc.html . =head1 Data: Dates @@ -163,36 +175,44 @@ You can find the week of the year by dividing this by 7: $week_of_year = int($day_of_year / 7); -Of course, this believes that weeks start at zero. +Of course, this believes that weeks start at zero. The Date::Calc +module from CPAN has a lot of date calculation functions, including +day of the year, week of the year, and so on. -=head2 How can I compare two date strings? +=head2 How can I compare two dates and find the difference? -Use the Date::Manip or Date::DateCalc modules from CPAN. +If you're storing your dates as epoch seconds then simply subtract one +from the other. If you've got a structured date (distinct year, day, +month, hour, minute, seconds values) then use one of the Date::Manip +and Date::Calc modules from CPAN. =head2 How can I take a string and turn it into epoch seconds? If it's a regular enough string that it always has the same format, -you can split it up and pass the parts to timelocal in the standard -Time::Local module. Otherwise, you should look into one of the -Date modules from CPAN. +you can split it up and pass the parts to C<timelocal> in the standard +Time::Local module. Otherwise, you should look into the Date::Calc +and Date::Manip modules from CPAN. =head2 How can I find the Julian Day? -Neither Date::Manip nor Date::DateCalc deal with Julian days. -Instead, there is an example of Julian date calculation in -http://www.perl.com/CPAN/authors/David_Muir_Sharnoff/modules/Time/JulianDay.pm.gz, -which should help. +Neither Date::Manip nor Date::Calc deal with Julian days. Instead, +there is an example of Julian date calculation that should help you in +http://www.perl.com/CPAN/authors/David_Muir_Sharnoff/modules/Time/JulianDay.pm.gz +. =head2 Does Perl have a year 2000 problem? Is Perl Y2K compliant? -Perl is just as Y2K compliant as your pencil--no more, and no less. -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 an array 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. +Short answer: No, Perl does not have a Year 2000 problem. Yes, Perl +is Y2K compliant. + +Long answer: Perl is just as Y2K compliant as your pencil--no more, +and no less. 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 an array 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. When gmtime() and localtime() are used in scalar context they return a timestamp string that contains a fully-expanded year. For example, @@ -215,17 +235,17 @@ addresses, etc.) for details. =head2 How do I unescape a string? -It depends just what you mean by "escape". URL escapes are dealt with -in L<perlfaq9>. Shell escapes with the backslash (\) +It depends just what you mean by ``escape''. URL escapes are dealt +with in L<perlfaq9>. Shell escapes with the backslash (C<\>) character are removed with: s/\\(.)/$1/g; -Note that this won't expand \n or \t or any other special escapes. +This won't expand C<"\n"> or C<"\t"> or any other special escapes. =head2 How do I remove consecutive pairs of characters? -To turn "abbcccd" into "abccd": +To turn C<"abbcccd"> into C<"abccd">: s/(.)\1/$1/g; @@ -242,20 +262,30 @@ arbitrary expressions: print "That yields ${\($n + 5)} widgets\n"; -See also "How can I expand variables in text strings?" in this section -of the FAQ. +Version 5.004 of Perl had a bug that gave list context to the +expression in C<${...}>, but this is fixed in version 5.005. + +See also ``How can I expand variables in text strings?'' in this +section of the FAQ. =head2 How do I find matching/nesting anything? -This isn't something that can be tackled in one regular expression, no -matter how complicated. To find something between two single characters, -a pattern like C</x([^x]*)x/> will get the intervening bits in $1. For -multiple ones, then something more like C</alpha(.*?)omega/> would -be needed. But none of these deals with nested patterns, nor can they. -For that you'll have to write a parser. +This isn't something that can be done in one regular expression, no +matter how complicated. To find something between two single +characters, a pattern like C</x([^x]*)x/> will get the intervening +bits in $1. For multiple ones, then something more like +C</alpha(.*?)omega/> would be needed. But none of these deals with +nested patterns, nor can they. For that you'll have to write a +parser. + +If you are serious about writing a parser, there are a number of +modules or oddities that will make your life a lot easier. There is +the CPAN module Parse::RecDescent, the standard module Text::Balanced, +the byacc program, and Mark-Jason Dominus's excellent I<py> tool at +http://www.plover.com/~mjd/perl/py/ . -One destructive, inside-out approach that you might try is to pull -out the smallest nesting parts one at a time: +One simple destructive, inside-out approach that you might try is to +pull out the smallest nesting parts one at a time: while (s//BEGIN((?:(?!BEGIN)(?!END).)*)END/gs) { # do something with $1 @@ -287,13 +317,13 @@ Use Text::Wrap (part of the standard perl distribution): use Text::Wrap; print wrap("\t", ' ', @paragraphs); -The paragraphs you give to Text::Wrap may not contain embedded +The paragraphs you give to Text::Wrap should not contain embedded newlines. Text::Wrap doesn't justify the lines (flush-right). =head2 How can I access/change the first N letters of a string? There are many ways. If you just want to grab a copy, use -substr: +substr(): $first_byte = substr($a, 0, 1); @@ -302,15 +332,16 @@ use substr() as an lvalue: substr($a, 0, 3) = "Tom"; -Although those with a regexp kind of thought process will likely prefer +Although those with a pattern matching kind of thought process will +likely prefer: $a =~ s/^.../Tom/; =head2 How do I change the Nth occurrence of something? -You have to keep track. For example, let's say you want -to change the fifth occurrence of "whoever" or "whomever" -into "whosoever" or "whomsoever", case insensitively. +You have to keep track of N yourself. For example, let's say you want +to change the fifth occurrence of C<"whoever"> or C<"whomever"> into +C<"whosoever"> or C<"whomsoever">, case insensitively. $count = 0; s{((whom?)ever)}{ @@ -331,7 +362,7 @@ loop, keeping count of matches. } } -That prints out: "The third fish is a red one." You can also use a +That prints out: C<"The third fish is a red one."> You can also use a repetition count and repeated pattern like this: /(?:\w+\s+fish\s+){2}(\w+)\s+fish/i; @@ -364,7 +395,7 @@ To make the first letter of each word upper case: This has the strange effect of turning "C<don't do it>" into "C<Don'T Do It>". Sometimes you might want this, instead (Suggested by Brian -Foy E<lt>comdog@computerdog.comE<gt>): +Foy): $string =~ s/ ( (^\w) #at the beginning of the line @@ -384,7 +415,7 @@ To force each word to be lower case, with the first letter upper case: You can (and probably should) enable locale awareness of those characters by placing a C<use locale> pragma in your program. -See L<perllocale> for endless details. +See L<perllocale> for endless details on locales. =head2 How can I split a [character] delimited string except when inside [character]? (Comma-separated files) @@ -440,7 +471,7 @@ Or more nicely written as: s/\s+$//; } -This idiom takes advantage of the for(each) loop's aliasing +This idiom takes advantage of the C<for(each)> loop's aliasing behavior to factor out common code. You can do this on several strings at once, or arrays, or even the values of a hash if you use a slide: @@ -504,7 +535,7 @@ variables as entries in some special hash. For example: ); $text =~ s/\$(\w+)/$user_defs{$1}/g; -See also "How do I expand function calls in a string?" in this section +See also ``How do I expand function calls in a string?'' in this section of the FAQ. =head2 What's wrong with always quoting "$vars"? |