=head1 NAME
-perlfaq - frequently asked questions about Perl ($Revision: 1.26 $, $Date: 2005/10/13 19:50:54 $)
+perlfaq - frequently asked questions about Perl ($Date: 2005/11/10 00:36:18 $)
=head1 DESCRIPTION
=item *
-How do I find out my hostname/domainname/IP address?
+How do I find out my hostname, domainname, or IP address?
=item *
=head1 NAME
-perlfaq3 - Programming Tools ($Revision: 1.52 $, $Date: 2005/10/13 19:43:13 $)
+perlfaq3 - Programming Tools ($Revision: 1.54 $, $Date: 2005/11/17 17:22:02 $)
=head1 DESCRIPTION
=head2 Is there a Perl shell?
-The psh (Perl sh) is currently at version 1.8. The Perl Shell is a
-shell that combines the interactive nature of a Unix shell with the
-power of Perl. The goal is a full featured shell that behaves as
-expected for normal shell activity and uses Perl syntax and
-functionality for control-flow statements and other things.
-You can get psh at http://sourceforge.net/projects/psh/ .
+The psh (Perl sh) is currently at version 1.8. The Perl Shell is a shell
+that combines the interactive nature of a Unix shell with the power of
+Perl. The goal is a full featured shell that behaves as expected for
+normal shell activity and uses Perl syntax and functionality for
+control-flow statements and other things. You can get psh at
+http://sourceforge.net/projects/psh/ .
Zoidberg is a similar project and provides a shell written in perl,
configured in perl and operated in perl. It is intended as a login shell
or your local CPAN mirror.
The Shell.pm module (distributed with Perl) makes Perl try commands
-which aren't part of the Perl language as shell commands. perlsh
-from the source distribution is simplistic and uninteresting, but
-may still be what you want.
+which aren't part of the Perl language as shell commands. perlsh from
+the source distribution is simplistic and uninteresting, but may still
+be what you want.
=head2 How do I find which modules are installed on my system?
-You can use the ExtUtils::Installed module to show all
-installed distributions, although it can take awhile to do
-its magic. The standard library which comes with Perl just
-shows up as "Perl" (although you can get those with
-Module::CoreList).
+You can use the ExtUtils::Installed module to show all installed
+distributions, although it can take awhile to do its magic. The
+standard library which comes with Perl just shows up as "Perl" (although
+you can get those with Module::CoreList).
use ExtUtils::Installed;
my @files;
find(
- sub { push @files, $File::Find::name if -f $File::Find::name && /\.pm$/ },
+ sub {
+ push @files, $File::Find::name
+ if -f $File::Find::name && /\.pm$/
+ },
+
@INC
- );
+ );
- print "$_\n" for @files;
+ 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
=head1 NAME
-perlfaq4 - Data Manipulation ($Revision: 1.69 $, $Date: 2005/10/14 15:34:06 $)
+perlfaq4 - Data Manipulation ($Revision: 1.71 $, $Date: 2005/11/23 07:46:45 $)
=head1 DESCRIPTION
The localtime function returns the day of the year. Without an
argument localtime uses the current time.
- $day_of_year = (localtime)[7];
+ $day_of_year = (localtime)[7];
The POSIX module can also format a date as the day of the year or
week of the year.
=head2 How do I sort a hash (optionally by value instead of key)?
-Internally, hashes are stored in a way that prevents you from imposing
-an order on key-value pairs. Instead, you have to sort a list of the
-keys or values:
-
- @keys = sort keys %hash; # sorted by key
- @keys = sort {
- $hash{$a} cmp $hash{$b}
- } keys %hash; # and by value
-
-Here we'll do a reverse numeric sort by value, and if two keys are
-identical, sort by length of key, or if that fails, by straight ASCII
-comparison of the keys (well, possibly modified by your locale--see
-L<perllocale>).
-
- @keys = sort {
- $hash{$b} <=> $hash{$a}
- ||
- length($b) <=> length($a)
- ||
- $a cmp $b
- } keys %hash;
+(contributed by brian d foy)
+
+To sort a hash, start with the keys. In this example, we give the list of
+keys to the sort function which then compares them ASCIIbetically (which
+might be affected by your locale settings). The output list has the keys
+in ASCIIbetical order. Once we have the keys, we can go through them to
+create a report which lists the keys in ASCIIbetical order.
+
+ my @keys = sort { $a cmp $b } keys %hash;
+
+ foreach my $key ( @keys )
+ {
+ printf "%-20s %6d\n", $key, $hash{$value};
+ }
+
+We could get more fancy in the C<sort()> block though. Instead of
+comparing the keys, we can compute a value with them and use that
+value as the comparison.
+
+For instance, to make our report order case-insensitive, we use
+the C<\L> sequence in a double-quoted string to make everything
+lowercase. The C<sort()> block then compares the lowercased
+values to determine in which order to put the keys.
+
+ my @keys = sort { "\L$a" cmp "\L$b" } keys %hash;
+
+Note: if the computation is expensive or the hash has many elements,
+you may want to look at the Schwartzian Transform to cache the
+computation results.
+
+If we want to sort by the hash value instead, we use the hash key
+to look it up. We still get out a list of keys, but this time they
+are ordered by their value.
+
+ my @keys = sort { $hash{$a} <=> $hash{$b} } keys %hash;
+
+From there we can get more complex. If the hash values are the same,
+we can provide a secondary sort on the hash key.
+
+ my @keys = sort {
+ $hash{$a} <=> $hash{$b}
+ or
+ "\L$a" cmp "\L$b"
+ } keys %hash;
=head2 How can I always keep my hash sorted?
=head1 NAME
-perlfaq5 - Files and Formats ($Revision: 1.38 $, $Date: 2005/10/13 19:49:13 $)
+perlfaq5 - Files and Formats ($Revision: 1.40 $, $Date: 2005/11/10 16:06:07 $)
=head1 DESCRIPTION
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
+you use the B<-A>, B<-M>, 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
=head1 NAME
-perlfaq7 - General Perl Language Issues ($Revision: 1.26 $, $Date: 2005/10/13 19:43:13 $)
+perlfaq7 - General Perl Language Issues ($Revision: 1.27 $, $Date: 2005/10/28 17:38:32 $)
=head1 DESCRIPTION
with lexical variables, though.
You can fake a static variable by using a lexical variable which goes
-of scope. In this example, you define the subroutine C<counter>, and
+out of scope. In this example, you define the subroutine C<counter>, and
it uses the lexical variable C<$count>. Since you wrap this in a BEGIN
block, C<$count> is defined at compile-time, but also goes out of
scope at the end of the BEGIN block. The BEGIN block also ensures that
=head1 NAME
-perlfaq9 - Networking ($Revision: 1.24 $, $Date: 2005/10/13 19:43:13 $)
+perlfaq9 - Networking ($Revision: 1.26 $, $Date: 2005/11/21 17:43:13 $)
=head1 DESCRIPTION
=head2 How do I decode or create those %-encodings on the web?
-
If you are writing a CGI script, you should be using the CGI.pm module
that comes with perl, or some other equivalent module. The CGI module
automatically decodes queries for you, and provides an escape()
function to handle encoding.
-
The best source of detailed information on URI encoding is RFC 2396.
Basically, the following substitutions do it:
s/([^\w()'*~!.-])/sprintf '%%%02x', ord $1/eg; # encode
- s/%([A-Fa-f\d]{2})/chr hex $1/eg; # decode
+ s/%([A-Fa-f\d]{2})/chr hex $1/eg; # decode
+ s/%([[:xdigit:]]{2})/chr hex $1/eg; # same thing
However, you should only apply them to individual URI components, not
the entire URI, otherwise you'll lose information and generally mess
$msg[$msgno] .= $_;
END { print @msg[ sort { $sub[$a] cmp $sub[$b] || $a <=> $b } (0 .. $#msg) ] }
-=head2 How do I find out my hostname/domainname/IP address?
+=head2 How do I find out my hostname, domainname, or IP address?
+X<hostname, domainname, IP address, host, domain, hostfqdn, inet_ntoa,
+gethostbyname, Socket, Net::Domain, Sys::Hostname>
-The normal way to find your own hostname is to call the C<`hostname`>
-program. While sometimes expedient, this has some problems, such as
-not knowing whether you've got the canonical name or not. It's one of
-those tradeoffs of convenience versus portability.
+(contributed by brian d foy)
-The Sys::Hostname module (part of the standard perl distribution) will
-give you the hostname after which you can find out the IP address
-(assuming you have working DNS) with a gethostbyname() call.
+The Net::Domain module, which is part of the standard distribution starting
+in perl5.7.3, can get you the fully qualified domain name (FQDN), the host
+name, or the domain name.
- use Socket;
- use Sys::Hostname;
- my $host = hostname();
- my $addr = inet_ntoa(scalar gethostbyname($host || 'localhost'));
+ use Net::Domain qw(hostname hostfqdn hostdomain);
+
+ my $host = hostfqdn();
+
+The C<Sys::Hostname> module, included in the standard distribution since
+perl5.6, can also get the hostname.
-Probably the simplest way to learn your DNS domain name is to grok
-it out of /etc/resolv.conf, at least under Unix. Of course, this
-assumes several things about your resolv.conf configuration, including
-that it exists.
+ use Sys::Hostname;
+
+ $host = hostname();
-(We still need a good DNS domain name-learning method for non-Unix
-systems.)
+To get the IP address, you can use the C<gethostbyname> built-in function
+to turn the name into a number. To turn that number into the dotted octet
+form (a.b.c.d) that most people expect, use the C<inet_ntoa> function
+from the <Socket> module, which also comes with perl.
+
+ use Socket;
+
+ my $address = inet_ntoa(
+ scalar gethostbyname( $host || 'localhost' )
+ );
=head2 How do I fetch a news article or the active newsgroups?