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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.
|
|