Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical


by dna (Beadle)
on Jun 22, 2004 at 00:09 UTC ( #368587=perlcraft: print w/replies, xml ) Need Help??

   1: #!/usr/bin/perl -w
   2: # rtfm - read the friendly manual/s
   3: #
   4: # Usage: rtfm [number of man pages to read]
   5: #
   6: # Originally written by Daniel N. Andersen, June 2004
   7: # Modified by just about everyone at
   9: use strict;
  11: my $lines = 0;
  12: my $loop  = 1;
  13: my $select;
  15: if($ARGV[0])
  16: {
  17:     $loop = $ARGV[0] unless($ARGV[0] =~ /\D/);
  18: }
  20: while($loop)
  21: {
  22:     foreach my $path (split(/:/, $ENV{'PATH'}))
  23:     {
  24:         opendir(PATH, $path);
  25:         while(defined($_ = readdir(PATH)))
  26:         {
  27:             if(-f "$path/$_")
  28:             {
  29:                 $lines++;
  30:                 $select = $_ if int(rand($lines)) == 0;
  31:             }
  32:         }
  33:         closedir(PATH);
  34:     }
  35:     system(man => $select);
  36:     $lines = 0;
  37:     $loop--;
  38: }

Replies are listed 'Best First'.
Re: rtfm
by grinder (Bishop) on Jun 22, 2004 at 09:42 UTC

    Heh! This gave me a big laugh (but then that's my sense of humour). On my fifth try I pulled up the perl manpage. How odd.

    I would humbly suggest filtering out the directories returned by readdir:

    push(@bins, grep { -f $_ } @content);

    Normally I would suggest $_ ne '.' and $_ ne '..' but as in this case we don't care to see directories or any other weird things, the -f will do the trick nicely.

    Another thing, if system is the last statement in your program you may want to consider execing the program instead, as you really don't need/care to hang around to see what happens.

    - another intruder with the mooring of the heat of the Perl

Re: rtfm
by Roy Johnson (Monsignor) on Jun 22, 2004 at 16:21 UTC
    You could also reduce memory overhead (at the expense of more calls to rand) by doing your random keep/toss within the loop:
    my $lines = 0; my $selection; foreach my $path (split /:/, $ENV{'PATH'}) { opendir(PATH, $path); while (defined($_ = readdir(PATH))) { if (-f "$path/$_") { ++$lines; $selection = $_ if int(rand($lines)) == 0; } } closedir(PATH) } exec(man => $selection);

    We're not really tightening our belts, it just feels that way because we're getting fatter.
      Done. The code seems less logical to me now, but what do I know? All we need now is some sort of GUI... :)
Re: rtfm
by Ven'Tatsu (Deacon) on Jun 22, 2004 at 13:27 UTC
    You should really use the list form of system (or exec as grinder points out).
    system('man', $bins[int(rand(@bins))]);
    It will avoid calling a shell to handle parsing the options to the external program saving you the trouble of making sure no one has named a file something that may cause your system trouble.
Re: rtfm
by dna (Beadle) on Jun 22, 2004 at 13:39 UTC

    Thanks for the help.

    This program was meant as a little joke, so I didn't think I'd ever have to see or edit it again. I have updated the code though, and if you discover any other braindamages, let me know.

    Oh, btw, thanks for pointing out the diffrence between 'system' and 'exec'. Didn't know 'cause I never really use either.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlcraft [id://368587]
Approved by grinder
Front-paged by grinder
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2023-09-22 23:07 GMT
Find Nodes?
    Voting Booth?

    No recent polls found