=head1 NAME
-perlfaq - frequently asked questions about Perl ($Date: 2002/11/13 06:23:50 $)
+perlfaq - frequently asked questions about Perl ($Date: 2003/01/03 20:00:25 $)
=head1 DESCRIPTION
-The perlfaq is structured into the following documents:
+The perlfaq is divided into several documents based on topics. A table
+of contents is at the end of this document.
+=head2 Where to get the perlfaq
+
+Extracts of the perlfaq are posted regularly to
+comp.lang.perl.misc. It is available on many web sites:
+http://www.perldoc.com/ and http://faq.perl.org/
+
+=head2 How to contribute to the perlfaq
+
+You may mail corrections, additions, and suggestions to
+perlfaq-workers@perl.org . This alias should not be used to
+I<ask> FAQs. It's for fixing the current FAQ. Send
+questions to the comp.lang.perl.misc newsgroup. You can
+view the source tree at http://cvs.perl.org/cvsweb/perlfaq/
+(which is outside of the main Perl source tree). The CVS
+repository notes all changes to the FAQ.
+
+=head2 What will happen if you mail your Perl programming problems to the authors
+
+Your questions will probably go unread, unless they're
+suggestions of new questions to add to the FAQ, in which
+case they should have gone to the perlfaq-workers@perl.org
+instead.
+
+You should have read section 2 of this faq. There you would
+have learned that comp.lang.perl.misc is the appropriate
+place to go for free advice. If your question is really
+important and you require a prompt and correct answer, you
+should hire a consultant.
+
+=head1 Credits
+
+The original perlfaq was written by Tom Christiansen, then expanded
+by collaboration between Tom and Nathan Torkington. The current
+document is maintained by the perlfaq-workers (perlfaq-workers@perl.org).
+Several people have contributed answers, corrections, and comments.
+
+=head1 Author and Copyright Information
+
+Copyright (c) 1997-2003 Tom Christiansen, Nathan Torkington, and
+other contributors noted in the answers.
+
+All rights reserved.
+
+=head2 Bundled Distributions
+
+This documentation is free; you can redistribute it and/or modify it
+under the same terms as Perl itself.
+
+Irrespective of its distribution, all code examples in these files
+are hereby placed into the public domain. You are permitted and
+encouraged to use this code in your own programs for fun
+or for profit as you see fit. A simple comment in the code giving
+credit would be courteous but is not required.
+
+=head2 Disclaimer
+
+This information is offered in good faith and in the hope that it may
+be of use, but is not guaranteed to be correct, up to date, or suitable
+for any particular purpose whatsoever. The authors accept no liability
+in respect of this information or its use.
+
+=head1 Table of Contents
=head2 perlfaq: Structural overview of the FAQ.
=back
-=head1 About the perlfaq documents
-
-=head2 Where to get the perlfaq
-
-This document is posted regularly to comp.lang.perl.announce and
-several other related newsgroups. It is available on many
-web sites: http://www.perldoc.com/ and http://perlfaq.cpan.org/ .
-
-=head2 How to contribute to the perlfaq
-
-You may mail corrections, additions, and suggestions to
-perlfaq-workers@perl.org . This alias should not be
-used to I<ask> FAQs. It's for fixing the current FAQ.
-Send questions to the comp.lang.perl.misc newsgroup.
-
-=head2 What will happen if you mail your Perl programming problems to the authors
-
-Your questions will probably go unread, unless they're suggestions of
-new questions to add to the FAQ, in which case they should have gone
-to the perlfaq-workers@perl.org instead.
-
-You should have read section 2 of this faq. There you would have
-learned that comp.lang.perl.misc is the appropriate place to go for
-free advice. If your question is really important and you require a
-prompt and correct answer, you should hire a consultant.
-
-=head1 Credits
-
-When I first began the Perl FAQ in the late 80s, I never realized it
-would have grown to over a hundred pages, nor that Perl would ever become
-so popular and widespread. This document could not have been written
-without the tremendous help provided by Larry Wall and the rest of the
-Perl Porters.
-
-=head1 Author and Copyright Information
-
-Copyright (c) 1997-2002 Tom Christiansen and Nathan Torkington.
-All rights reserved.
-
-=head2 Bundled Distributions
-
-This documentation is free; you can redistribute it and/or modify it
-under the same terms as Perl itself.
-
-Irrespective of its distribution, all code examples in these files
-are hereby placed into the public domain. You are permitted and
-encouraged to use this code in your own programs for fun
-or for profit as you see fit. A simple comment in the code giving
-credit would be courteous but is not required.
-
-=head2 Disclaimer
-
-This information is offered in good faith and in the hope that it may
-be of use, but is not guaranteed to be correct, up to date, or suitable
-for any particular purpose whatsoever. The authors accept no liability
-in respect of this information or its use.
-
-=back
=head1 NAME
-perlfaq1 - General Questions About Perl ($Revision: 1.10 $, $Date: 2002/08/29 03:34:00 $)
+perlfaq1 - General Questions About Perl ($Revision: 1.11 $, $Date: 2002/12/06 07:40:11 $)
=head1 DESCRIPTION
perl source code from releases 1 through 4. It has been modularized,
object-oriented, tweaked, trimmed, and optimized until it almost doesn't
look like the old code. However, the interface is mostly the same, and
-compatibility with previous releases is very high.
+compatibility with previous releases is very high.
See L<perltrap/"Perl4 to Perl5 Traps">.
To avoid the "what language is perl5?" confusion, some people prefer to
=head2 What is perl6?
-At The Second O'Reilly Open Source Software Convention, Larry Wall
+At The Second O'Reilly Open Source Software Convention, Larry Wall
announced Perl6 development would begin in earnest. Perl6 was an oft
used term for Chip Salzenberg's project to rewrite Perl in C++ named
Topaz. However, Topaz provided valuable insights to the next version
-of Perl and its implementation, but was ultimately abandoned.
+of Perl and its implementation, but was ultimately abandoned.
-If you want to learn more about Perl6, or have a desire to help in
-the crusade to make Perl a better place then peruse the Perl6 developers
+If you want to learn more about Perl6, or have a desire to help in
+the crusade to make Perl a better place then peruse the Perl6 developers
page at http://dev.perl.org/perl6/ and get involved.
Perl6 is not scheduled for release yet, and Perl5 will still be supported
=head1 NAME
-perlfaq2 - Obtaining and Learning about Perl ($Revision: 1.17 $, $Date: 2002/11/16 23:33:08 $)
+perlfaq2 - Obtaining and Learning about Perl ($Revision: 1.18 $, $Date: 2002/12/06 07:40:11 $)
=head1 DESCRIPTION
If you're just looking for software, first use Google
( http://www.google.com ), Google's usenet search interface
-( http://groups.google.com ), and CPAN Search ( http://search.cpan.org ).
+( http://groups.google.com ), and CPAN Search ( http://search.cpan.org ).
This is faster and more productive than just posting a request.
=head2 Perl Books
=head2 Archives of comp.lang.perl.misc
The Google search engine now carries archived and searchable newsgroup
-content.
+content.
http://groups.google.com/groups?group=comp.lang.perl.misc
=head1 NAME
-perlfaq3 - Programming Tools ($Revision: 1.29 $, $Date: 2002/11/13 06:23:50 $)
+perlfaq3 - Programming Tools ($Revision: 1.31 $, $Date: 2003/01/03 20:10:11 $)
=head1 DESCRIPTION
Mod::CoreList).
use ExtUtils::Installed;
-
+
my $inst = ExtUtils::Installed->new();
my @modules = $inst->modules();
can use File::Find::Rule.
use File::Find::Rule;
-
+
my @files = File::Find::Rule->file()->name( '*.pm' )->in( @INC );
If you do not have that module, you can do the same thing
-with File::Find which is part of the standard library.
+with File::Find which is part of the standard library.
use File::Find;
my @files;
@INC;
print join "\n", @files;
-
+
If you simply need to quickly check to see if a module is
available, you can check for its documentation. If you can
-read the documentation the module is most likely installed.
+read the documentation the module is most likely installed.
If you cannot read the documentation, the module might not
have any (in rare cases).
perl finds it.
perl -MModule::Name -e1
-
+
=head2 How do I debug my Perl programs?
-Have you tried C<use warnings> or used C<-w>? They enable warnings
+Have you tried C<use warnings> or used C<-w>? They enable warnings
to detect dubious practices.
Have you tried C<use strict>? It prevents you from using symbolic
=head2 How do I profile my Perl programs?
You should get the Devel::DProf module from the standard distribution
-(or separately on CPAN) and also use Benchmark.pm from the standard
-distribution. The Benchmark module lets you time specific portions of
-your code, while Devel::DProf gives detailed breakdowns of where your
+(or separately on CPAN) and also use Benchmark.pm from the standard
+distribution. The Benchmark module lets you time specific portions of
+your code, while Devel::DProf gives detailed breakdowns of where your
code spends its time.
Here's a sample use of Benchmark:
=head2 How do I cross-reference my Perl programs?
-The B::Xref module can be used to generate cross-reference reports
+The B::Xref module can be used to generate cross-reference reports
for Perl programs.
perl -MO=Xref[,OPTIONS] scriptname.plx
When the files you're processing are small, it doesn't much matter which
way you do it, but it makes a huge difference when they start getting
-larger.
+larger.
=item * Use map and grep selectively
return \@a;
}
- for $i ( 1 .. 10 ) {
+ for ( 1 .. 10 ) {
push @many, makeone();
}
try http://www.perldoc.com/ , but consider upgrading your perl.)
A good book on OO on Perl is the "Object-Oriented Perl"
-by Damian Conway from Manning Publications,
+by Damian Conway from Manning Publications,
http://www.manning.com/Conway/index.html
=head2 Where can I learn about linking C with Perl? [h2xs, xsubpp]
=head1 NAME
-perlfaq4 - Data Manipulation ($Revision: 1.37 $, $Date: 2002/11/13 06:04:00 $)
+perlfaq4 - Data Manipulation ($Revision: 1.39 $, $Date: 2003/01/03 20:06:21 $)
=head1 DESCRIPTION
To limit the number of decimal places in your numbers, you
can use the printf or sprintf function. See the
-L<perlop|"Floating Point Arithmetic"> for more details.
+L<"Floating Point Arithmetic"|perlop> for more details.
printf "%.2f", 10/3;
-
+
my $number = sprintf "%.2f", 10/3;
-
+
=head2 Why isn't my octal data interpreted correctly?
Perl only understands octal and hex numbers as such when they occur as
"%o" or "%O" sprintf() formats.
This problem shows up most often when people try using chmod(), mkdir(),
-umask(), or sysopen(), which by widespread tradition typically take
+umask(), or sysopen(), which by widespread tradition typically take
permissions in octal.
chmod(644, $file); # WRONG
chmod(0644, $file); # right
-Note the mistake in the first line was specifying the decimal literal
+Note the mistake in the first line was specifying the decimal literal
644, rather than the intended octal literal 0644. The problem can
be seen with:
Surely you had not intended C<chmod(01204, $file);> - did you? If you
want to use numeric literals as arguments to chmod() et al. then please
-try to express them as octal constants, that is with a leading zero and
+try to express them as octal constants, that is with a leading zero and
with the following digits restricted to the set 0..7.
=head2 Does Perl have a round() function? What about ceil() and floor()? Trig functions?
for ($i = 0; $i < 1.01; $i += 0.05) { printf "%.1f ",$i}
- 0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
+ 0.0 0.1 0.1 0.2 0.2 0.2 0.3 0.3 0.4 0.4 0.5 0.5 0.6 0.7 0.7
0.8 0.8 0.9 0.9 1.0 1.0
Don't blame Perl. It's the same as in C. IEEE says we have to do this.
Use the following simple functions:
- sub get_century {
+ sub get_century {
return int((((localtime(shift || time))[5] + 1999))/100);
- }
- sub get_millennium {
+ }
+ sub get_millennium {
return 1+int((((localtime(shift || time))[5] + 1899))/1000);
- }
+ }
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;
can use the Date::Calc module.
use Date::Calc qw(Today Add_Delta_Days);
-
+
my @date = Add_Delta_Days( Today(), -1 );
-
+
print "@date\n";
Most people try to use the time rather than the calendar to
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
while (s/BEGIN((?:(?!BEGIN)(?!END).)*)END//gs) {
# do something with $1
- }
+ }
A more complicated and sneaky approach is to make Perl's regular
expression engine do it for you. This is courtesy Dean Inada, and
You can access the first characters of a string with substr().
To get the first character, for example, start at position 0
-and grab the string of length 1.
+and grab the string of length 1.
$string = "Just another Perl Hacker";
argument which is the replacement string.
substr( $string, 13, 4, "Perl 5.8.0" );
-
+
You can also use substr() as an lvalue.
substr( $string, 13, 4 ) = "Perl 5.8.0";
-
+
=head2 How do I change the Nth occurrence of something?
You have to keep track of N yourself. For example, let's say you want
SAR001,"","Cimetrix, Inc","Bob Smith","CAM",N,8,1,0,7,"Error, Core Dumped"
Due to the restriction of the quotes, this is a fairly complex
-problem. Thankfully, we have Jeffrey Friedl, author of
+problem. Thankfully, we have Jeffrey Friedl, author of
I<Mastering Regular Expressions>, to handle these for us. He
suggests (assuming your string is contained in $text):
This idiom takes advantage of the C<foreach> loop's aliasing
behavior to factor out common code. You can do this
-on several strings at once, or arrays, or even the
+on several strings at once, or arrays, or even the
values of a hash if you use a slice:
- # trim whitespace in the scalar, the array,
+ # trim whitespace in the scalar, the array,
# and all the values in the hash
foreach ($scalar, @array, @hash{keys %hash}) {
s/^\s+//;
=head2 How do I pad a string with blanks or pad a number with zeroes?
(This answer contributed by Uri Guttman, with kibitzing from
-Bart Lateur.)
+Bart Lateur.)
In the following examples, C<$pad_len> is the length to which you wish
to pad the string, C<$text> or C<$num> contains the string to be padded,
# Right padding a string with blanks (no truncation):
$padded = sprintf("%-${pad_len}s", $text);
- # Left padding a number with 0 (no truncation):
+ # Left padding a number with 0 (no truncation):
$padded = sprintf("%0${pad_len}d", $num);
# Right padding a string with blanks using pack (will truncate):
=head2 How do I extract selected columns from a string?
Use substr() or unpack(), both documented in L<perlfunc>.
-If you prefer thinking in terms of columns instead of widths,
+If you prefer thinking in terms of columns instead of widths,
you can use this kind of thing:
# determine the unpack format needed to split Linux ps output
# arguments are cut columns
my $fmt = cut2fmt(8, 14, 20, 26, 30, 34, 41, 47, 59, 63, 67, 72);
- sub cut2fmt {
+ sub cut2fmt {
my(@positions) = @_;
my $template = '';
my $lastpos = 1;
for my $place (@positions) {
- $template .= "A" . ($place - $lastpos) . " ";
+ $template .= "A" . ($place - $lastpos) . " ";
$lastpos = $place;
}
$template .= "A*";
It's probably better in the general case to treat those
variables as entries in some special hash. For example:
- %user_defs = (
+ %user_defs = (
foo => 23,
bar => 19,
);
The problem is that those double-quotes force stringification--
coercing numbers and references into strings--even when you
don't want them to be strings. Think of it this way: double-quote
-expansion is used to produce new strings. If you already
+expansion is used to produce new strings. If you already
have a string, why do you need more?
If you get used to writing odd things like these:
number, such as the magical C<++> autoincrement operator or the
syscall() function.
-Stringification also destroys arrays.
+Stringification also destroys arrays.
@lines = `command`;
print "@lines"; # WRONG - extra blanks
=over 4
-=item 1. There must be no space after the << part.
+=item There must be no space after the << part.
-=item 2. There (probably) should be a semicolon at the end.
+=item There (probably) should be a semicolon at the end.
-=item 3. You can't (easily) have any space in front of the tag.
+=item You can't (easily) have any space in front of the tag.
=back
-If you want to indent the text in the here document, you
+If you want to indent the text in the here document, you
can do this:
# all in one
HERE_TARGET
But the HERE_TARGET must still be flush against the margin.
-If you want that indented also, you'll have to quote
+If you want that indented also, you'll have to quote
in the indentation.
($quote = <<' FINIS') =~ s/^\s+//gm;
@bad[0] = `same program that outputs several lines`;
-The C<use warnings> pragma and the B<-w> flag will warn you about these
+The C<use warnings> pragma and the B<-w> flag will warn you about these
matters.
=head2 How can I remove duplicate elements from a list or array?
@a = @b = ( "this", "that", [ "more", "stuff" ] );
printf "a and b contain %s arrays\n",
- cmpStr(\@a, \@b) == 0
- ? "the same"
+ cmpStr(\@a, \@b) == 0
+ ? "the same"
: "different";
This approach also works for comparing hashes. Here
%a = %b = ( "this" => "that", "extra" => [ "more", "stuff" ] );
$a{EXTRA} = \%b;
- $b{EXTRA} = \%a;
+ $b{EXTRA} = \%a;
printf "a and b contain %s hashes\n",
cmpStr(\%a, \%b) == 0 ? "the same" : "different";
Perl 5.8. This example finds the first element that contains "Perl".
use List::Util qw(first);
-
+
my $element = first { /Perl/ } @array;
-
+
If you cannot use List::Util, you can make your own loop to do the
same thing. Once you find the element, you stop the loop with last.
and check the array element at each index until you find one
that satisfies the condition.
- my( $found, $i ) = ( undef, -1 );
- for( $i = 0; $i < @array; $i++ )
+ my( $found, $index ) = ( undef, -1 );
+ for( $i = 0; $i < @array; $i++ )
{
- if( $array[$i] =~ /Perl/ )
- {
+ if( $array[$i] =~ /Perl/ )
+ {
$found = $array[$i];
- $index = $i;
+ $index = $i;
last;
}
}
$_ **= 3;
$_ *= (4/3) * 3.14159; # this will be constant folded
}
-
+
which can also be done with map() which is made to transform
one list into another:
case), you modify the value.
for $orbit ( values %orbits ) {
- ($orbit **= 3) *= (4/3) * 3.14159;
+ ($orbit **= 3) *= (4/3) * 3.14159;
}
Prior to perl 5.6 C<values> returned copies of the values,
$element = $array[$index];
Make sure you I<only call srand once per program, if then>.
-If you are calling it more than once (such as before each
+If you are calling it more than once (such as before each
call to rand), you're almost certainly doing something wrong.
=head2 How do I permute N elements of a list?
print "next permutation: (@perm)\n";
}
+For even faster execution, you could do:
+
+ use Algorithm::Permute;
+ my @array = 'a'..'d';
+ Algorithm::Permute::permute {
+ print "next permutation: (@array)\n";
+ } @array;
+
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
@ints = $vector->Index_List_Read();
Bit::Vector provides efficient methods for bit vector, sets of small integers
-and "big int" math.
+and "big int" math.
Here's a more extensive illustration using vec():
# vec demo
$vector = "\xff\x0f\xef\xfe";
- print "Ilya's string \\xff\\x0f\\xef\\xfe represents the number ",
+ print "Ilya's string \\xff\\x0f\\xef\\xfe represents the number ",
unpack("N", $vector), "\n";
$is_set = vec($vector, 23, 1);
print "Its 23rd bit is ", $is_set ? "set" : "clear", ".\n";
set_vec(0,32,17);
set_vec(1,32,17);
- sub set_vec {
+ sub set_vec {
my ($offset, $width, $value) = @_;
my $vector = '';
vec($vector, $offset, $width) = $value;
print "vector length in bytes: ", length($vector), "\n";
@bytes = unpack("A8" x length($vector), $bits);
print "bits are: @bytes\n\n";
- }
+ }
=head2 Why does defined() return true on empty arrays and hashes?
$num_keys = keys %hash;
-The keys() function also resets the iterator, which means that you may
-see strange results if you use this between uses of other hash operators
+The keys() function also resets the iterator, which means that you may
+see strange results if you use this between uses of other hash operators
such as each().
=head2 How do I sort a hash (optionally by value instead of key)?
return undef;
} else {
return $num;
- }
- }
+ }
+ }
- sub is_numeric { defined getnum($_[0]) }
+ sub is_numeric { defined getnum($_[0]) }
Or you could check out the L<String::Scanf|String::Scanf> module on the CPAN
instead. The POSIX module (part of the standard Perl distribution) provides
of the standard distribution. Here's one example using Storable's C<store>
and C<retrieve> functions:
- use Storable;
+ use Storable;
store(\%hash, "filename");
- # later on...
+ # later on...
$href = retrieve("filename"); # by ref
%hash = %{ retrieve("filename") }; # direct to hash
for printing out data structures. The Storable module, found on CPAN,
provides a function called C<dclone> that recursively copies its argument.
- use Storable qw(dclone);
+ use Storable qw(dclone);
$r2 = dclone($r1);
Where $r1 can be a reference to any kind of data structure you'd like.
=head1 NAME
-perlfaq5 - Files and Formats ($Revision: 1.26 $, $Date: 2002/09/21 21:04:17 $)
+perlfaq5 - Files and Formats ($Revision: 1.27 $, $Date: 2002/12/06 07:40:11 $)
=head1 DESCRIPTION
print() or write(). Setting $| affects buffering only for
the currently selected default file handle. You choose this
handle with the one argument select() call (see
-L<perlvar/$|> and L<perlfunc/select>).
+L<perlvar/$E<verbar>> and L<perlfunc/select>).
Use select() to choose the desired handle, then set its
per-filehandle variables.
Use the File::Temp module, see L<File::Temp> for more information.
- use File::Temp qw/ tempfile tempdir /;
+ use File::Temp qw/ tempfile tempdir /;
$dir = tempdir( CLEANUP => 1 );
($fh, $filename) = tempfile( DIR => $dir );
# 15158 p5 T 0:00 perl /home/tchrist/scripts/now-what
$PS_T = 'A6 A4 A7 A5 A*';
open(PS, "ps|");
- print scalar <PS>;
+ print scalar <PS>;
while (<PS>) {
($pid, $tt, $stat, $time, $command) = unpack($PS_T, $_);
for $var (qw!pid tt stat time command!) {
That block is a proper block like any other, so you can put more
complicated code there. This sends the message out to one of two places:
- $ok = -x "/bin/cat";
+ $ok = -x "/bin/cat";
print { $ok ? $fd[1] : $fd[2] } "cat stat $ok\n";
- print { $fd[ 1+ ($ok || 0) ] } "cat stat $ok\n";
+ print { $fd[ 1+ ($ok || 0) ] } "cat stat $ok\n";
This approach of treating C<print> and C<printf> like object methods
calls doesn't work for the diamond operator. That's because it's a
open(FH, "+> /path/name"); # WRONG (almost always)
Whoops. You should instead use this, which will fail if the file
-doesn't exist.
+doesn't exist.
open(FH, "+< /path/name"); # open for update
Normally perl ignores trailing blanks in filenames, and interprets
certain leading characters (or a trailing "|") to mean something
-special.
+special.
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
+special mode characters and whitespace in the filename as
literals
open FILE, "<", " file "; # filename is " file "
Slavish adherence to portability concerns shouldn't get in the way of
your getting your job done.)
-For more information on file locking, see also
+For more information on file locking, see also
L<perlopentut/"File Locking"> if you have it (new for 5.6).
=back
You can use the File::Slurp module to do it in one step.
use File::Slurp;
-
+
$all_of_it = read_file($filename); # entire file in scalar
@all_lines = read_file($filename); # one line perl element
while (<INPUT>) {
chomp;
# do something with $_
- }
+ }
close(INPUT) || die "can't close $file: $!";
This is tremendously more efficient than reading the entire file into
$var = <INPUT>;
}
-That temporarily undefs your record separator, and will automatically
+That temporarily undefs your record separator, and will automatically
close the file at block exit. If the file is already open, just use this:
$var = do { local $/; <INPUT> };
for instance, gets treated as two paragraphs and not three), or
C<"\n\n"> to accept empty paragraphs.
-Note that a blank line must have no blanks in it. Thus
+Note that a blank line must have no blanks in it. Thus
S<C<"fred\n \nstuff\n\n">> is one paragraph, but C<"fred\n\nstuff\n\n"> is two.
=head2 How can I read a single character from a file? From the keyboard?
Note that "<&STDIN" makes a copy, but "<&=STDIN" make
an alias. That means if you close an aliased handle, all
-aliases become inaccessible. This is not true with
+aliases become inaccessible. This is not true with
a copied one.
Error checking, as always, has been left as an exercise for the reader.
Or, just use the fdopen(3S) feature of open():
- {
- local *F;
+ {
+ local *F;
open F, "<&=$fd" or die "Cannot reopen fd=$fd: $!";
close F;
}
=head1 NAME
-perlfaq6 - Regular Expressions ($Revision: 1.18 $, $Date: 2002/10/30 18:44:21 $)
+perlfaq6 - Regular Expressions ($Revision: 1.20 $, $Date: 2003/01/03 20:05:28 $)
=head1 DESCRIPTION
littered with answers involving regular expressions. For example,
decoding a URL and checking whether something is a number are handled
with regular expressions, but those answers are found elsewhere in
-this document (in L<perlfaq9>: ``How do I decode or create those %-encodings
+this document (in L<perlfaq9>: ``How do I decode or create those %-encodings
on the web'' and L<perlfaq4>: ``How do I determine whether a scalar is
a number/whole/integer/float'', to be precise).
# now choose between them
} continue {
reset if eof(); # fix $.
- }
+ }
=head2 I put a regular expression into $/ but it didn't work. What's wrong?
-As of Perl 5.8.0, $/ has to be a string. This may change in 5.10,
+Up to Perl 5.8.0, $/ has to be a string. This may change in 5.10,
but don't get your hopes up. Until then, you can use these examples
if you really need to do this.
-Use the four argument form of sysread to continually add to
-a buffer. After you add to the buffer, you check if you have a
+Use the four argument form of sysread to continually add to
+a buffer. After you add to the buffer, you check if you have a
complete line (using your regular expression).
local $_ = "";
# do stuff here.
}
}
-
+
You can do the same thing with foreach and a match using the
c flag and the \G anchor, if you do not mind your entire file
being in memory at the end.
-
+
local $_ = "";
while( sysread FH, $_, 8192, length ) {
foreach my $record ( m/\G((?s).*?)your_pattern/gc ) {
my $mask = uc $old ^ $old;
uc $new | $mask .
- substr($mask, -1) x (length($new) - length($old))
+ substr($mask, -1) x (length($new) - length($old))
}
$a = "this is a TEsT case";
No matter which locale you are in, the alphabetic characters are
the characters in \w without the digits and the underscore.
As a regex, that looks like C</[^\W\d_]/>. Its complement,
-the non-alphabetics, is then everything in \W along with
-the digits and the underscore, or C</[\W\d_]/>.
+the non-alphabetics, is then everything in \W along with
+the digits and the underscore, or C</[\W\d_]/>.
=head2 How can I quote a variable to use in a regex?
Use the split function:
while (<>) {
- foreach $word ( split ) {
+ foreach $word ( split ) {
# do something with $word here
- }
+ }
}
Note that this isn't really a word in the English sense; it's just
If you wanted to do the same thing for lines, you wouldn't need a
regular expression:
- while (<>) {
+ while (<>) {
$seen{$_}++;
}
while ( ($line, $count) = each %seen ) {
@popstates = qw(CO ON MI WI MN);
while (defined($line = <>)) {
for $state (@popstates) {
- if ($line =~ /\b$state\b/i) {
+ if ($line =~ /\b$state\b/i) {
print $line;
last;
}
}
- }
+ }
That's because Perl has to recompile all those patterns for each of
the lines of the file. As of the 5.005 release, there's a much better
{
print "Found $1\n";
}
-
+
After the match fails at the letter C<a>, perl resets pos()
and the next match on the same string starts at the beginning.
For each line, the PARSER loop first tries to match a series
of digits followed by a word boundary. This match has to
start at the place the last match left off (or the beginning
-of the string on the first match). Since C<m/ \G( \d+\b
+of the string on the first match). Since C<m/ \G( \d+\b
)/gcx> uses the C<c> flag, if the string does not match that
regular expression, perl does not reset pos() and the next
match starts at the same position to try a different
(?:[A-Z][A-Z])*?
GX
/x;
-
+
This succeeds if the "martian" character GX is in the string, and fails
otherwise. If you don't like using (?!<), you can replace (?!<[A-Z])
with (?:^|[^A-Z]).
=head1 NAME
-perlfaq7 - General Perl Language Issues ($Revision: 1.11 $, $Date: 2002/11/10 17:35:47 $)
+perlfaq7 - General Perl Language Issues ($Revision: 1.12 $, $Date: 2002/12/06 07:40:11 $)
=head1 DESCRIPTION
Note that <FILE> is I<neither> the type specifier for files
nor the name of the handle. It is the C<< <> >> operator applied
to the handle FILE. It reads one line (well, record--see
-L<perlvar/$/>) from the handle FILE in scalar context, or I<all> lines
+L<perlvar/$E<sol>>) from the handle FILE in scalar context, or I<all> lines
in list context. When performing open, close, or any other operation
besides C<< <> >> on files, or even when talking about the handle, do
I<not> use the brackets. These are correct: C<eof(FH)>, C<seek(FH, 0,
Another way is to use undef as an element on the left-hand-side:
($dev, $ino, undef, undef, $uid, $gid) = stat($file);
-
+
You can also use a list slice to select only the elements that
you need:
open my $fh, $filename or die "Cannot open $filename! $!";
func( $fh );
-
+
sub func {
my $passed_fh = shift;
-
+
my $line = <$fh>;
}
-
+
Before Perl 5.6, you had to use the C<*FH> or C<\*FH> notations.
These are "typeglobs"--see L<perldata/"Typeglobs and Filehandles">
and especially L<perlsub/"Pass by Reference"> for more information.
variables. It gives a global variable a temporary value. my() is
what you're looking for if you want private variables.
-See L<perlsub/"Private Variables via my()"> and
+See L<perlsub/"Private Variables via my()"> and
L<perlsub/"Temporary Values via local()"> for excruciating details.
=head2 How can I access a dynamic variable while a similarly named lexical is in scope?
elsif (/pat2/) { } # do something else
elsif (/pat3/) { } # do something else
else { } # default
- }
+ }
Here's a simple example of a switch based on pattern matching, this
time lined up in a way to make it look more like a switch statement.
}
-See C<perlsyn/"Basic BLOCKs and Switch Statements"> for many other
+See C<perlsyn/"Basic BLOCKs and Switch Statements"> for many other
examples in this style.
Sometimes you should change the positions of the constant and the variable.
elsif ("LIST" =~ /^\Q$answer/i) { print "Action is list\n" }
elsif ("EDIT" =~ /^\Q$answer/i) { print "Action is edit\n" }
-A totally different approach is to create a hash of function references.
+A totally different approach is to create a hash of function references.
my %commands = (
"happy" => \&joy,
$commands{$string}->();
} else {
print "No such command: $string\n";
- }
+ }
=head2 How can I catch accesses to undefined variables, functions, or methods?
sub scrub_package {
no strict 'refs';
my $pack = shift;
- die "Shouldn't delete main package"
+ die "Shouldn't delete main package"
if $pack eq "" || $pack eq "main";
my $stash = *{$pack . '::'}{HASH};
my $name;
}
}
-Or, if you're using a recent release of Perl, you can
+Or, if you're using a recent release of Perl, you can
just use the Symbol::delete_package() function instead.
=head2 How can I use a variable as a variable name?
$name = "fred";
$$name{WIFE} = "wilma"; # set %fred
- $name = "barney";
+ $name = "barney";
$$name{WIFE} = "betty"; # set %barney
This is still a symbolic reference, and is still saddled with the
for my $name (@colors) {
no strict 'refs'; # renege for the block
*$name = sub { "<FONT COLOR='$name'>@_</FONT>" };
- }
+ }
All those functions (red(), blue(), green(), etc.) appear to be separate,
but the real code in the closure actually was compiled only once.
=head1 NAME
-perlfaq8 - System Interaction ($Revision: 1.14 $, $Date: 2002/11/10 17:35:47 $)
+perlfaq8 - System Interaction ($Revision: 1.16 $, $Date: 2003/01/03 20:03:57 $)
=head1 DESCRIPTION
Controlling input buffering is a remarkably system-dependent matter.
On many systems, you can just use the B<stty> command as shown in
L<perlfunc/getc>, but as you see, that's already getting you into
-portability snags.
+portability snags.
open(TTY, "+</dev/tty") or die "no tty: $!";
system "stty cbreak </dev/tty >/dev/tty 2>&1";
=head2 How do I get the screen size?
-If you have Term::ReadKey module installed from CPAN,
+If you have Term::ReadKey module installed from CPAN,
you can use it to fetch the width and height in characters
and in pixels:
use Term::ReadKey;
($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
-This is more portable than the raw C<ioctl>, but not as
+This is more portable than the raw C<ioctl>, but not as
illustrative:
require 'sys/ioctl.ph';
If you expect characters to get to your device when you print() them,
you'll want to autoflush that filehandle. You can use select()
-and the C<$|> variable to control autoflushing (see L<perlvar/$|>
+and the C<$|> variable to control autoflushing (see L<perlvar/$E<verbar>>
and L<perlfunc/select>, or L<perlfaq5>, ``How do I flush/unbuffer an
output filehandle? Why must I do this?''):
You have to be prepared to "reap" the child process when it finishes.
$SIG{CHLD} = sub { wait };
-
+
$SIG{CHLD} = 'IGNORE';
-
-You can also use a double fork. You immediately wait() for your
-first child, and the init daemon will wait() for your grandchild once
+
+You can also use a double fork. You immediately wait() for your
+first child, and the init daemon will wait() for your grandchild once
it exits.
unless ($pid = fork) {
properly, the getpw*() functions described in L<perlfunc> should in
theory provide (read-only) access to entries in the shadow password
file. To change the file, make a new shadow password file (the format
-varies from system to system--see L<passwd(5)> for specifics) and use
-pwd_mkdb(8) to install it (see L<pwd_mkdb(8)> for more details).
+varies from system to system--see L<passwd> for specifics) and use
+pwd_mkdb(8) to install it (see L<pwd_mkdb> for more details).
=head2 How do I set the time and date?
Release 5 of Perl added the END block, which can be used to simulate
atexit(). Each package's END block is called when the program or
-thread ends (see L<perlmod> manpage for more details).
+thread ends (see L<perlmod> manpage for more details).
For example, you can use this to make sure your filter program
managed to finish its output without filling up the disk:
END {
close(STDOUT) || die "stdout close failed: $!";
- }
+ }
The END block isn't called when untrapped signals kill the program,
though, so if you use END blocks you should also use
L<perlfunc>).
Remember to check the modules that came with your distribution, and
-CPAN as well--someone may already have written a module to do it.
+CPAN as well---someone may already have written a module to do it. On
+Windows, try Win32::API. On Macs, try Mac::Carbon. If no module
+has an interface to the C function, you can inline a bit of C in your
+Perl source with Inline::C.
=head2 Where do I get the include files to do ioctl() or syscall()?
The IPC::Open2 module (part of the standard perl distribution) is an
easy-to-use approach that internally uses pipe(), fork(), and exec() to do
the job. Make sure you read the deadlock warnings in its documentation,
-though (see L<IPC::Open2>). See
-L<perlipc/"Bidirectional Communication with Another Process"> and
+though (see L<IPC::Open2>). See
+L<perlipc/"Bidirectional Communication with Another Process"> and
L<perlipc/"Bidirectional Communication with Yourself">
You may also use the IPC::Open3 module (part of the standard perl
way to write maintainable code. Perl has several operators for
running external commands. Backticks are one; they collect the output
from the command for use in your program. The C<system> function is
-another; it doesn't do this.
+another; it doesn't do this.
Writing backticks in your program sends a clear message to the readers
of your code that you wanted to collect the output of the command.
process are not reflected in its parent--only in any children
created after the change. There is shell magic that may allow you to
fake it by eval()ing the script's output in your shell; check out the
-comp.unix.questions FAQ for details.
+comp.unix.questions FAQ for details.
=back
=item *
-Open /dev/tty and use the TIOCNOTTY ioctl on it. See L<tty(4)>
+Open /dev/tty and use the TIOCNOTTY ioctl on it. See L<tty>
for details. Or better yet, you can just use the POSIX::setsid()
function, so you don't have to worry about process groups.
passes the signal on to the subprocess. Or you can check for it:
$rc = system($cmd);
- if ($rc & 127) { die "signal death" }
+ if ($rc & 127) { die "signal death" }
=head2 How do I open a file without blocking?
=head2 How do I install a module from CPAN?
The easiest way is to have a module also named CPAN do it for you.
-This module comes with perl version 5.004 and later.
+This module comes with perl version 5.004 and later.
$ perl -MCPAN -e shell
cpan shell -- CPAN exploration and modules installation (v1.59_54)
ReadLine support enabled
- cpan> install Some::Module
+ cpan> install Some::Module
-To manually install the CPAN module, or any well-behaved CPAN module
+To manually install the CPAN module, or any well-behaved CPAN module
for that matter, follow these steps:
=over 4
=head1 AUTHOR AND COPYRIGHT
-Copyright (c) 1997-2002 Tom Christiansen and Nathan Torkington.
+Copyright (c) 1997-2003 Tom Christiansen and Nathan Torkington.
All rights reserved.
This documentation is free; you can redistribute it and/or modify it
=head1 NAME
-perlfaq9 - Networking ($Revision: 1.13 $, $Date: 2002/11/13 06:07:58 $)
+perlfaq9 - Networking ($Revision: 1.14 $, $Date: 2002/12/06 07:40:11 $)
=head1 DESCRIPTION
(Alan Flavell <flavell+www@a5.ph.gla.ac.uk> answers...)
-The Common Gateway Interface (CGI) specifies a software interface between
-a program ("CGI script") and a web server (HTTPD). It is not specific
-to Perl, and has its own FAQs and tutorials, and usenet group,
-comp.infosystems.www.authoring.cgi
+The Common Gateway Interface (CGI) specifies a software interface between
+a program ("CGI script") and a web server (HTTPD). It is not specific
+to Perl, and has its own FAQs and tutorials, and usenet group,
+comp.infosystems.www.authoring.cgi
The original CGI specification is at: http://hoohoo.ncsa.uiuc.edu/cgi/
Other relevant documentation listed in: http://www.perl.org/CGI_MetaFAQ.html
-These Perl FAQs very selectively cover some CGI issues. However, Perl
+These Perl FAQs very selectively cover some CGI issues. However, Perl
programmers are strongly advised to use the CGI.pm module, to take care
-of the details for them.
+of the details for them.
The similarity between CGI response headers (defined in the CGI
specification) and HTTP response headers (defined in the HTTP
http://www.perl.org/troubleshooting_CGI.html
-If, after that, you can demonstrate that you've read the FAQs and that
+If, after that, you can demonstrate that you've read the FAQs and that
your problem isn't something simple that can be easily answered, you'll
probably receive a courteous and useful reply to your question if you
post it on comp.infosystems.www.authoring.cgi (if it's something to do
questions but are really CGI ones that are posted to comp.lang.perl.misc
are not so well received.
-The useful FAQs, related documents, and troubleshooting guides are
+The useful FAQs, related documents, and troubleshooting guides are
listed in the CGI Meta FAQ:
http://www.perl.org/CGI_MetaFAQ.html
You can easily extract all sorts of URLs from HTML with
C<HTML::SimpleLinkExtor> which handles anchors, images, objects,
-frames, and many other tags that can contain a URL. If you need
-anything more complex, you can create your own subclass of
-C<HTML::LinkExtor> or C<HTML::Parser>. You might even use
+frames, and many other tags that can contain a URL. If you need
+anything more complex, you can create your own subclass of
+C<HTML::LinkExtor> or C<HTML::Parser>. You might even use
C<HTML::SimpleLinkExtor> as an example for something specifically
suited to your needs.
You can use URI::Find to extract URLs from an arbitrary text document.
-Less complete solutions involving regular expressions can save
+Less complete solutions involving regular expressions can save
you a lot of processing time if you know that the input is simple. One
solution from Tom Christiansen runs 100 times faster than most
module based approaches but only extracts URLs from anchors where the first
-attribute is HREF and there are no other attributes.
+attribute is HREF and there are no other attributes.
#!/usr/bin/perl -n00
# qxurl - tchrist@perl.com
print redirect($url);
-But if coded directly, it could be as follows (the final "\n" is
+But if coded directly, it could be as follows (the final "\n" is
shown separately, for clarity), using either a complete URL or
-an absolute URLpath.
+an absolute URLpath.
print "Location: $url\n"; # CGI response header
print "\n"; # end of headers
$msg->send;
-This defaults to using L<sendmail(1)> but can be customized to use
+This defaults to using L<sendmail> but can be customized to use
SMTP via L<Net::SMTP>.
=head2 How do I read mail?