Re: How can I list down all builtin functions?(Re: Read a text file starting from the bottom)
- From: krahnj@xxxxxxxxx (John W. Krahn)
- Date: Mon, 15 Jan 2007 10:17:04 -0800
Bill Jones wrote:
On 1/15/07, Michael Alipio <daem0nb0y@xxxxxxxxx> wrote:
Is there a way to list down all builtin functions so that I may know
what to "perldoc -f"?
Here is an example (from Apache2Triad on Windows.)
This doesn't list "all builtin functions", it lists all environment variables
and modules.
#!C:/apache2triad/perl/bin/perl.exe
You should include these two pragmas at the start of your program:
use warnings;
use strict;
print "Content-type: text/html\n\n";
#
# general info
#
print <<HTML;
<html><link rel=stylesheet href=style.css>
<h2 align=center>general info</h2>
<p>
<table class=table border=0 cellpadding=4 cellspacing=1 width=100%>
<tr>
<td width=35% class=tdd><b>perl version:</b></td>
<td width=65% class=tdl>$]</td>
</tr>
<tr>
<td class=tdd><b>perl compiled on:</b></td>
<td class=tdl>$^O</td>
</tr>
<tr>
<td class=tdd><b>perl executable:</b></td>
<td class=tdl>$^X</td>
</tr>
<tr>
<td class=tdd><b>location of perl:</b></td>
<td class=tdl>
HTML
$per = $^X ;
$per =~ s/perl.exe|PERL.EXE//;
@perlloc = ("$per");
perldoc -q quoting
Found in /usr/lib/perl5/5.8.6/pod/perlfaq4.pod
What’s wrong with always quoting "$vars"?
Also the precedence is unambiguous so the parentheses are not required.
foreach $loc(@perlloc){
print "$loc<br>\n";
}
You just assigned a single value to the array and are using a loop to print it
out??? Why not just:
print "$per<br>\n";
print <<HTML;
</td></tr><tr><td class=tdd> <b>include paths:</b></td><td class=tdl>
HTML
foreach $item(@INC){
if ($item ne "."){
print "$item <br>\n";
}
}
print <<HTML;
</td></tr></table>
HTML
#
# environment variables
#
print <<HTML;
<h2 align=center>environment variables</h2><table class=table
border=0 cellpadding=4 cellspacing=1 width=100%>
<tr><td class=tdark ><b>Server Variable</b></td><td class=tdg
<b>Value</b></td></tr>HTML
foreach $fieldname(keys %ENV){
print "<tr><td width=35% class=tdd><font
size=-1>$fieldname<font></td>\n";
print "<td width=65% class=tdl><font
size=-1>$ENV{$fieldname} <font></td></tr>\n";
}
print <<HTML;
</table>
HTML
#
# perl modules
#
use File::Find;
sub count {
You call this subroutine *count* but it has nothing to do with *counting* or
with a *count* value?
return $found{$a}[1] cmp $found{$b}[1];
}
sub ModuleScanner {
if ($File::Find::name =~ /\.pm$/){
open(FILE,$File::Find::name) || return;
File::Find::find() puts the current file name into $_ so there is no need to
use $File::Find::name:
if ( /\.pm$/ ) {
open FILE, '<', $_ or return;
while(<FILE>){
if (/^ *package +(\S+);/){
push (@modules, $1);
last;
}
}
}
}
find(\&ModuleScanner,@INC);
foreach $line(@modules){
$match = lc($line);
if ($found{$line}[0] >0){
$found{$line} = [$found{$line}[0]+1,$match]
}else{
$found{$line} = ["1",$match];
}
}
Because of autovivification you could simplify that to:
foreach my $line ( @modules ) {
$found{ $line }[ 0 ]++;
$found{ $line }[ 1 ] = lc $line;
}
But you never use $found{ $line }[ 0 ] anywhere else so why is it there?
@modules = sort count keys(%found);
You are sorting based on the lower case values of the keys so why not call
your sub 'ignore_case' instead of 'count'?
print <<HTML;
<h2 align=center>perl modules</h2><table class=table border=0
cellpadding=4 cellspacing=1 width=100%>
HTML
$count=0;
foreach $mod(@modules){
chomp $mod;
Why are you chomp()ing $mod? You used the regular expression /^ *package
+(\S+);/ to get the module names and the character class \S cannot contain any
carriage returns or newlines.
$count++;
if ($count == 1){
print "<tr><td class=tdl>$mod</td>\n";
}
if ($count == 2){
print "<td class=tdl>$mod</td>\n";
}
if ($count == 3){
print "<td class=tdl>$mod</td></tr>\n";
$count = 0;
}
}
You have three tests in that loop. That means that for every three loops you
are performing nine tests. If $count is equal to 1 why bother to also compare
it to 2 and 3 and if $count is equal to 2 why bother to also compare it to 3?
If you change 'if' to 'elsif' in the second and third tests you will reduce
the number of tests by 33% (from nine to six for every three loops.)
my $count = 0;
foreach my $mod ( @modules ) {
$count++;
if ( $count == 1 ) {
print "<tr><td class=tdl>$mod</td>\n";
}
elsif ( $count == 2 ) {
print "<td class=tdl>$mod</td>\n";
}
elsif ( $count == 3 ) {
print "<td class=tdl>$mod</td></tr>\n";
$count = 0;
}
}
However you can remove the "magic numbers" and make the code more flexible:
my @formats = (
"<tr><td class=tdl>%s</td>\n",
"<td class=tdl>%s</td>\n",
"<td class=tdl>%s</td></tr>\n",
);
for my $index ( 0 .. $#modules ) {
printf $formats[ $index % @formats ], $modules[ $index ];
}
print <<HTML;
</table></html>
HTML
exit;
If you are going to use exit() you should at least return something useful to
the OS:
exit 0;
John
--
Perl isn't a toolbox, but a small machine shop where you can special-order
certain sorts of tools at low cost and in short order. -- Larry Wall
.
- References:
- Prev by Date: Re: files download and performance
- Next by Date: Re: Complement of =~
- Previous by thread: Re: How can I list down all builtin functions?(Re: Read a text file starting from the bottom)
- Next by thread: Re: Read a text file starting from the bottom
- Index(es):
Relevant Pages
|