http://qs1969.pair.com?node_id=687750

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

Hi,

I am using a cgi. I have some condition and based upon that I want to call different methods in the cgi file.

Eg:
_upload_table1 { } _upload_table2 { }
I will get the table1, table2 value from cgi
$tablename=cgi->param('tablename'); _upload_$tablename(args);

How can i call the method dynamically

Replies are listed 'Best First'.
Re: Calling different methods based on a CGI parameter
by Corion (Patriarch) on May 21, 2008 at 11:45 UTC

    Simple, by using a dispatch table:

    my %handlers = ( table1 => \&_upload_table1, table2 => \&_upload_table2, ); $tablename=cgi->param('tablename'); my $handler = $handlers{$tablename}; $handler->(args);
Re: Calling different methods based on a CGI parameter
by wfsp (Abbot) on May 21, 2008 at 11:46 UTC
    A dispatch table is often used for this. It helps separate your input data from your code and helps trap invalid data. It works under strict and warnings and is prettier than a string of if/elses. :-)
    #!/usr/bin/perl use strict; use warnings; my %dispatch = ( table1 => \&_upload_table1, table2 => \&_upload_table1, ); my $tablename = cgi->param('tablename'); die qq{bad param\n} unless exists $dispatch{$tablename}; $dispatch{$tablename}->(); sub _upload_table1 { } sub _upload_table2 { }
    update: <cough> added the call to the sub :-)
      Thankyou, but I was more interested to find out the way to build the dispatch hash in a dynamic way using an array of table names.
        I had a feeling you'd say that. :-)

        You would be generating code based on user input (data from outside). Most monks will argue quite strenuously that this is a bad idea. Really.

        You will be tempted to turn off strict and warnings, you will probably have to turn off taint mode too.

        Your code should decide which sub to run, not the the user. Have a look at the Tutorials on web programing (particularly Security in CGI Programming) and, please, take another look at dispatch tables.

        update: added link

Re: Calling different methods based on a CGI parameter
by moritz (Cardinal) on May 21, 2008 at 12:46 UTC
    Although dispatch tables are the prefered way to do it, you can use variables as sub names:
    #!/usr/bin/perl use strict; use warnings; sub sa { print "sub sa\n"; } sub sb { print "sub sb\n"; } my $name = 'a'; # using the symbol table $main::{'s' . $name}->(); $name = 'b'; # using symbolic references: no strict 'refs'; &{"s$name"}();

    Be aware that this might open some security holes depending on your application. You have been warned!