Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

URL linking within script

by FireBird34 (Pilgrim)
on May 13, 2003 at 04:44 UTC ( #257637=perlquestion: print w/replies, xml ) Need Help??
FireBird34 has asked for the wisdom of the Perl Monks concerning the following question:

I'm messing around with trying to link to different sections in a script, so that I can click on a link (ie. script.cgi?abc, and &abc; will run). It works, but with some *issues*.
#!perl -w use strict; use CGI; use CGI::Carp qw(fatalsToBrowser); #errors will show in browser my $q = new CGI; print qq! <a href="script.cgi?one">one</a> <br> <a href="script.cgi?two">two</a> <br> <a href="script.cgi?three">three</a> !; if($q->param){ my $sub = $ENV{'QUERY_STRING'}; if(defined &$sub){ print "<BR><BR>"; &$sub; }else{ print "<BR><BR>"; &error; } } sub one { print "sub... one"; } sub two { print "sub... two"; } sub three { print "sub... three"; } sub error { print "ERROR\!\!"; }
If you comment out 'use strict;', this will work with no problems... but with strict on, it won't allow me to use the call &$sub;. Is there an easy way to get around that problem? Also, is there an easier way of doing what I'm trying to do here? (in that above code, I know that I can take off if($q->param) { }, however I'll be needing it later, so I just left it =P

Any help would be appreciated.

Replies are listed 'Best First'.
Re: URL linking within script
by jgallagher (Pilgrim) on May 13, 2003 at 05:12 UTC
    Try checking out CGI::Application. It's a framework for doing what you're implementing here (multi-page CGI applications (thus the name)), and it automates several of the tasks you may have to do eventually.
      Ok, sounds great. Thanks =) Problem with some of these app's, is that I know basically how to preform the task, however it's hard to find exactally what I want (to many modules) ;) (also, it's not the vote that counts, it's the information within the post :))
Re: URL linking within script
by december (Pilgrim) on May 13, 2003 at 12:12 UTC

    This might seem like a cool idea, and it would be for normal scripts, but the direct passing of arguments and executing them is probably not a good idea for cgi applications. You probably do not want people to be able to call all functions in your code; let alone, when someone finds a way to trick the 'define' clause and gets to run their own perl/machine code. I would use a dispatch method like chromatic already demonstrated, so you have much more control over what gets called and therefore executed.

    If you still really want to do it, you'll have to use no strict "refs";, because this is exactly what strict is meant to stop.



Re: URL linking within script
by pzbagel (Chaplain) on May 13, 2003 at 05:02 UTC

    Move the four sub definitions to the top of your script and strict should stop complaining.

    Update: Uhhh...okay, that was way off. What was I thinking?:P

    I guess what you really need is a:

    no strict "refs";

    in there.

    Sorry bout that...

      I downvoted this post because it's wrong. Please test your advice if you're not sure:

      #!/usr/bin/perl -w use strict; sub foo { print "foo\n" } my $f = 'foo'; &$f;

      I generally prefer a dispatch table:

      my %ops = ( one => \&one, two => \&two, ); my $op = $q->param( 'op' ); die "Invalid operation '$op'\n" unless exists $ops{ $op }; $subs{ $op }->();

      You can also mess with can, though it's less secure -- with the ops hash you can control exactly which subs can ever be called.

      my $op = $q->param( 'op' ); my $sub = __PACKAGE__->can( $op ); die "Invalid op '$op'\n" unless $sub; $sub->();

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://257637]
Approved by Paladin
Front-paged by Tomte
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (8)
As of 2017-02-20 21:38 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (303 votes). Check out past polls.