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

Hi Monks,

I'm trying to split up a script into a number of component scripts on the advice at All-in-one script vs independent scripts. In the code below, login.pl is loaded at the start of the script, whether or not it's actually needed.

######### Main script ######### index.pl #!C:/perl5.8/bin/perl.exe use CGI qw(:cgi); my $query = get_param('action') || 'default'; # login.pl contains the subroutine do_login() require "login.pl"; my %actions = ( default => \&default, login => \&do_login ); &{ $actions{$query} } sub default { # show default page } ######### Auxiliary script ######### login.pl sub do_login { #process login } 1;
That works but I would like to load login.pl as and when it's called. How do I achieve that? Something like:
######### Main script ######### index.pl #!C:/perl5.8/bin/perl.exe use CGI qw(:cgi); my $query = get_param('action') || 'default'; my %actions = ( default => \&default, login => \&login ); &{ $actions{$query} } sub default { # show default page } sub login { require "login.pl"; } ######### Auxiliary script ######### login.pl sub do_login { #process login } 1;
How do I accomplish what I'm trying to do above?

Replies are listed 'Best First'.
•Re: How to use require...
by merlyn (Sage) on Jan 03, 2004 at 07:10 UTC
    Simply:
    sub do_login { require "login.pl"; goto &do_login; }
    The problem is that if you have warnings on, you'll get a "subroutine redefined" message. You can turn your login library into a login ".pm" file rather easily and then you can use autouse, which is core.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Thanks, merlyn!

      The following uses 'autouse' and I'm getting the results as desired. I just want to make sure I'm getting it correctly...:)

      ######### Main script ######### index.pl #!C:/perl5.8/bin/perl.exe use CGI qw(:cgi); use Login; use autouse Login => qw(&do_login &do_login2); my $query = get_param('action') || 'default'; my %actions = ( default => \&default, login => \&do_login, login2 => \&do_login2 ); &{ $actions{$query} } ######## Auxiliary script ######## Login.pm sub do_login { # show login page } sub do_login2 { # process login } 1;
      updated

      I commented out "use autouse Login => qw(&do_login &do_login2);" and it still works. Am I missing something?

        I commented out "use autouse Login => qw(&do_login &do_login2);" and it still works. Am I missing something?
        Ahh, you don't need both that and the previous line. That's like wearing both suspenders and a belt.

        Comment out the use Login line.

        -- Randal L. Schwartz, Perl hacker
        Be sure to read my standard disclaimer if this is a reply.

Re: How to use require...
by fruiture (Curate) on Jan 03, 2004 at 09:54 UTC

    Ok, autouse is of course ver elegant. I'd probably used something like the following, to save subroutne names.

    my %actions = ( 'login' => sub { require Login; do_login(); }, ... );

    But anyway, there's a slight problem about your code. Imagine somehow the "action" parameter is filled with nonsense, which should happen at least when you want to test your script. You'll get:

    Use of uninitialized value in subroutine entry at ... Can't use string ("") as a subroutine ref while "strict refs" in use a +t .....

    Simply because $query might contain "foo" (which does not exist in %actions). Just add a check to your code:

    $query = 'default' unless exists $actions{ $query };

    HTH.

    --
    http://fruiture.de