Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

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

by einerwitzen (Sexton)
on Jan 15, 2002 at 09:47 UTC ( [id://138815]=perlquestion: print w/replies, xml ) Need Help??

einerwitzen has asked for the wisdom of the Perl Monks concerning the following question: (cgi programming)

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?

Originally posted as a Categorized Question.

Replies are listed 'Best First'.
Re: How can I run only part of a script determined by a posted variable?
by hossman (Prior) on Jan 15, 2002 at 13:23 UTC
    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
      Can't seem to update my answer, but I should have mentioned: This approach is very similar to the Command Design Pattern
Re: How can I run only part of a script determined by a posted variable?
by gt8073a (Hermit) on Jan 15, 2002 at 13:47 UTC

    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
Re: How can I run only part of a script determined by a posted variable?
by gav^ (Curate) on Jan 16, 2002 at 09:15 UTC
    Use a hash table containing coderefs (without creating the temporary hash):
    ({ 'open' => \&func1, 'create' => \&func2, 'delete' => \&func3, }->{$action} || \&default)->();

    gav^

Re: How can I run only part of a script determined by a posted variable?
by Lucky (Scribe) on Jan 19, 2002 at 14:09 UTC
    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
Re: How can I run only part of a script determined by a posted variable?
by Anonymous Monk on Jan 15, 2002 at 21:41 UTC
    == should be eq

    Originally posted as a Categorized Answer.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://138815]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-03-19 02:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found