Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to use something like the code below to check an argument to a perl program before loading any modules. This idea came from the Perl Cookbook. The problem is that when I run the code below, it can not find the help sub. It returns "Undefined subroutine &main::help". How do I make this code find the help subroutine?

Thanks in advance.
BEGIN { if (@ARGV[0] != 1) { &help; } } help { print "Show help message and exit\n"; exit; } use SomeModule;

Replies are listed 'Best First'.
Re: Trouble finding a subroutine
by Jenda (Abbot) on Jan 06, 2005 at 17:40 UTC

    BEGIN{} blocks are executed as soon as they are compiled, before the rest of the file gets compiled. So you tried to call the subroutine before it was compiled.

    You need to move the sub help {...} into the BEGIN{} block.

    I assume the missing sub keyword was just a typo in the example.

    Jenda
    We'd like to help you learn to help yourself
    Look around you, all you see are sympathetic eyes
    Stroll around the grounds until you feel at home
       -- P. Simon in Mrs. Robinson

Re: Trouble finding a subroutine
by Zaxo (Archbishop) on Jan 06, 2005 at 17:42 UTC

    Take a look at Getopt::Long. Its pod has examples of that very thing, in a robust and extensible setting. Pod::Usage automates help, extracting the text from your own pod. The two work well together. Very useful!

    holli has correctly identified your syntax error. You can avoid the ampersand before the help() call by defining the sub before calling it, or by calling it with empty parens.

    After Compline,
    Zaxo

Re: Trouble finding a subroutine
by Limbic~Region (Chancellor) on Jan 06, 2005 at 17:42 UTC
    Anonymous Monk,
    like the code below to check an argument to a perl program before loading any modules

    Argument handling is typically handled by a module in the Getopt family. The second part of the sentence indicates that you want to check the arguments before using a module though. This is a bit harder since use statements are handle at compile time, not run time. Typically this is handled by using require in lieu of use and running the import manually. Messing with BEGIN blocks as indicated elsewhere may work, but YMMV.

    In this case, your code is complaining because you have not defined the help subroutine properly (see answer above for how). Typically, you should get out of the habit of calling subroutines as &sub_name and use sub_name() instead. This is because it affects @_. If none of this makes sense to you, see perldoc perlsub and perldoc perlvar.

    Cheers - L~R

Re: Trouble finding a subroutine
by holli (Abbot) on Jan 06, 2005 at 17:35 UTC
Re: Trouble finding a subroutine
by fauria (Deacon) on Jan 06, 2005 at 18:34 UTC
    Hi!

    Im new to perlmonks, and also ive not been using perl for as much time as other people here, so this may not be as accurate as it could. Anyway, here is what i usually do:

    sub help{ print "Whatever youd like to write\n"; return; } die &help unless scalar(@ARGV) == 1;


    Or, alternatively:

    use strict; use Getopt::Long; my $var; sub usage{ print "Usage: $0 --foo=bar\n"; return; } GetOptions("foo=s" => \$var) and defined($var) or die &usage; print "You typed: $var\n";
Re: Trouble finding a subroutine
by dragonchild (Archbishop) on Jan 06, 2005 at 19:02 UTC
    I'm trying to use something like the code below to check an argument to a perl program before loading any modules.

    Unless your modules are doing really crazy things, a reasonable number of modules will load on any modern* machine in less time than a human can register. In other words, don't worry about it, use Getopt::Long, and be about your business.

    *: "Reasonable" as in less than 100. "Modern" as in newer than 1995.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.