Welcome to WebmasterWorld Guest from 54.82.93.116

Forum Moderators: coopster & jatar k & phranque

Calling a function via a variable

     
1:59 am on Oct 15, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month

joined:Mar 15, 2013
posts: 980
votes: 90


I have code that looks like this:

$action = param('action');

if ($action eq 'process_send_pm') { process_send_pm(); }
elsif ($action eq 'process_purge') { process_purge(); }
elsif ($action eq 'process_folders') { process_folders(); }
elsif ($action eq 'process_ignore') { process_ignore(); }
elsif ($action eq 'process_modify_profile') { process_modify_profile(); }


I was thinking about changing it to this, for the sake of brevity:

if (
$action eq 'process_send_pm' ||
$action eq 'process_purge' ||
$action eq 'process_folders' ||
$action eq 'process_ignore' ||
$action eq 'process_modify_profile') { &{$action}; }


I keep reading that this is a bad idea, but... why? If I'm testing to make sure that $action matches pre-approved strings before sending, am I still opening up to an unforeseen problem?
3:38 am on Oct 15, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member Top Contributors Of The Month

joined:Apr 1, 2016
posts:2236
votes: 590


I have very little, in fact almost no experience, in PHP much less Perl. I code in Python and JS. But FWIW in this situation I would create an object of key/value pairs where the key is the action string and value is the function call:

action_map = {'process_send_pm': process_send_pm(),
'process_purge':process_purge(),
'process_folders':process_folders(),
'process_ignore':process_ignore(),
'process_modify_profile': process_modify_profile() }

Then I would take the value of your $action and use it as the key to call the function:

// assuming action = 'process_purge'
action_map[action]
// this would call the function process_purge()

This avoids the entire if else || chain. It is clean and easier to read. Now whether or not that works in Perl is a whole other question.
9:23 am on Oct 15, 2018 (gmt 0)

Full Member

Top Contributors Of The Month

joined:Sept 13, 2018
posts:327
votes: 63


I keep reading that this is a bad idea, but... why? If I'm testing to make sure that $action matches pre-approved strings before sending, am I still opening up to an unforeseen problem?

I think that the main concern is about using a "variable" , which , by definition can "vary". So a good coding practice would be to avoid this kind of usage, because, between the moment the variable is set, and the moment it's used to invoke the procedure, it might have be changed / altered for "some reasons" (bad coding, malicious code injection etc..). However, In your example, I don't see this kind of problem, since you get the value, test it, and call the function in a row.
10:03 am on Oct 15, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month

joined:Sept 25, 2005
posts:1984
votes: 331


Nothing can logically go wrong there, so I don't really see the problem either.

I'm not too proficient in Perl, but, since you like brevity, perhaps you could also do this?

if($action ~~ ('process_send_pm', 'process_purge', 'process_folders', 'process_ignore', 'process_modify_profile')) {
&{$action};
}

Requires Perl 5.10+ and may throw an "experimental" warning, so only if you're feeling adventurous ;-)
7:15 pm on Oct 15, 2018 (gmt 0)

Senior Member

WebmasterWorld Senior Member 5+ Year Member Top Contributors Of The Month

joined:Mar 15, 2013
posts:980
votes: 90


That's pretty cool, Rob! I'm using v5.10.1 but haven't done a huge amount of Perl work in a long time, so I haven't used the ~~ operator. I found some info on it, though, and it seems like I should have been using it all along:

[perlmaven.com...]

Nick, this was already in the middle of an if-else so I was going to have to use an if() statement, anyway; otherwise, your map solution would have been great and easy to read! Thanks for that tip, too.

Thanks for the help, all!
 

Join The Conversation

Moderators and Top Contributors

Hot Threads This Week

Featured Threads

Free SEO Tools

Hire Expert Members