Dynamic creation and calling of functions is one of the most flexible mechanisms in Perl, inherited from the traditions of latex and shell scripts. Since early versions, Perl has allowed calling functions by string (through symbolic references/globs), storing references to subroutines in variables and associative arrays, as well as the AUTOLOAD construct for generating functions on the fly.
The main issues with this approach are security (the potential for calling an unwanted function via a substituted string) and performance (symbolic name resolution is slower than direct calls). It is also important to control the scope of functions and the passing of the correct number of arguments.
The solution is to use a hash dispatcher (mapping from string/keyword to coderef), avoid using eval to execute user code, and clearly define the list of functions allowed for invocation.
Example code (dispatch by key):
my %dispatch = ( add => sub { $_[0] + $_[1] }, sub => sub { $_[0] - $_[1] }, mult => sub { $_[0] * $_[1] }, ); my $key = 'add'; if (exists $dispatch{$key}) { print $dispatch{$key}->(2, 3); # Will output 5 } else { die "Unknown action $key"; }
Key features:
Can you call a function by its name using only a string?
Answer: Yes, but it is dangerous - calling $fn_name->() or through direct symbolic reference &$fn_name(); is not recommended with external (user) data, as it can lead to potential vulnerabilities.
Is there a difference between a code reference and a function name in Perl?
Answer: Yes, a function name is always global, while a function reference (coderef) can be lexical, local, passed between subroutines, and can hold an anonymous function.
my $coderef = sub { ... }; my $named = \&fn_name;
What happens if a non-existent function is called through a hash dispatcher?
Answer: If the key is absent, an error will occur. Therefore, it is always necessary to check exists before calling and handle unrecognized commands; otherwise, there will be an attempt to call undef (fatal error).
A command on the website takes the function name from the GET parameter and calls it via eval - any user can invoke system, unlink, and other dangerous functions.
Pros:
Cons:
A hash with a whitelist of functions is used, all parameters are validated, eval is not used, errors are caught and logged.
Pros:
Cons: