Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

How can I run only part of a script determined by a posted variable?

( #138815=categorized question: print w/ replies, xml ) Need Help??
Contributed by einerwitzen on Jan 15, 2002 at 09:47 UTC
Q&A  > CGI programming


Description:

I have a cgi file that recieves $function and $file. and has if/then statements saying things like
if ($function eq "open") { open (BLAH, "$file"); #actions close (BLAH); } elsif ($function eq "create") { open (NETH, ">$file"); #actions close (NETH); } else { #actions }
it's messy and hard to work with this way (a lot more funstions than i showed :), is there a way to do the same sort of thing without if then statements?

Answer: How can I run only part of a script determined by a posted variable?
contributed by hossman

You can use a hashtable lookup of closures (aka: code refs)

This would let you build up the hashtable in any order you want, possibly adding to it in multiple files (maintained by different people), possibly refering to methods / coderefs written by other people, in other packages.

Understanding how the example below works is left as an excersize fo the reader.
(hint: look at perldoc perlref)

#!/usr/local/bin/perl -wl use strict; my $function = $ARGV[0]; my $input_file = $ARGV[1];; sub create_file { my $file = shift; open (NETH, ">$file"); #actions print "Creating $file"; close (NETH); } my %function_registry = ( 'open' => sub { my $file = shift; open (BLAH, "$file"); #actions print "Opening $file"; close (BLAH); }, 'create' => \&create_file ); &{$function_registry{$function}}($input_file); __END__ [hossman@laptop ~]$ monk.pl create /tmp/file Creating /tmp/file [hossman@laptop ~]$ monk.pl open /tmp/file Opening /tmp/file
Answer: How can I run only part of a script determined by a posted variable?
contributed by gt8073a

is there a way to do the same sort of thing without if then statements?

You can use references to subroutines in a hash, then check if the key exists.
The following example does not do any real error checking, security, or check any return values, but it should help point you in the correct direction.

#!/usr/bin/perl -w use strict; print "Starting.\n\n"; my %actions = ( 'open' => \&fileOpen, 'create' => \&fileCreate, 'delete' => \&Nono::fileDelete, 'test' => \&fileTest, ); while ( <DATA> ) { chomp; next if /^\s*$/; my ( $function, $file ) = split( /\s+/, $_, 2); print "Testing '$function' -> '$file' . . ."; exists( $actions{ $function } ) ? &{$actions{ $function }}( $file ) : print "\t'$function' does not exist\n"; } print "Done.\n\n"; exit(0); sub fileOpen { my $open = shift; ## open( BLAH, $open ) or die; ## actions ## close( BLAH ); print "\tGot file '$open' to open.\n"; return; } sub fileCreate { my $create = shift; ## open( BLAH, ">$create" ) or die; ## actions ## close( BLAH ); print "\tGot file '$create' to create.\n"; return; } package Nono; sub fileDelete { my $delete = shift; ## actions print "\tGot file '$delete' to delete.\n"; return; } package main; sub fileTest { my $test = shift; ## actions print "\tGot file '$test' to test.\n"; return; } __DATA__ open line1 test line2 create line3 test line 4 blah blah delete line5 open line 6 nothing line 7 fails xxx line8 fails too fail This will fail
Answer: How can I run only part of a script determined by a posted variable?
contributed by gav^

Use a hash table containing coderefs (without creating the temporary hash):

({ 'open' => \&func1, 'create' => \&func2, 'delete' => \&func3, }->{$action} || \&default)->();

gav^

Answer: How can I run only part of a script determined by a posted variable?
contributed by Lucky

I think CGI::Application will help you. Here is an article about it's usage. Small example:

# YourApp.pm package YourApp; use base 'CGI::Application'; sub setup { my $self = shift; $self->start_mode('open'); $self->mode_param('function'); $self->run_modes( 'open' => 'do_open', 'create' => 'do_create', ); } # yourapp.cgi use YourApp; my $app = YourApp->new; $app->run;
Sorry if you hate OO design :-) Lucky

Please (register and) log in if you wish to add an answer



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others imbibing at the Monastery: (13)
    As of 2014-09-18 10:46 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      How do you remember the number of days in each month?











      Results (111 votes), past polls