开发者

How to execute functions from packages using function reference in perl?

开发者 https://www.devze.com 2023-03-04 21:39 出处:网络
I wanted to use function reference for dynamically executing functions from other packages. I have been trying different solutions for a while for the idea and nothing seemed to work!

I wanted to use function reference for dynamically executing functions from other packages.

I have been trying different solutions for a while for the idea and nothing seemed to work! So, i thought of asking this question and while attempting to do so, solution worked! but I'm not sure if it's the correct way to do so: it requires manual work and is a bit "hacky". Can it be improved?

  1. A package to support required functionality

    package Module;
    
    # $FctHash is intended to  be a Look-up table, on-reception 
    # of command.. execute following functions
    
    $FctHash ={
        'FctInitEvaluate' => \&FctInitEvaluate,
        'FctInitExecute' => \&FctInitExecute
    };
    
    sub FctInitEvaluate()
    {
        //some code for the evalute function
    }
    
    sub FctInitExecute()
    {
        //some code for the execute function
    }
    1;
    

2. Utility Script needs to use the package using function reference

    use strict;
    use warnings 'all';
    no strict 'refs';

    require Module;

    sub ExecuteCommand()
    {
      my ($InputCommand,@Arguments) =@_;
      my $SupportedCommandRefenece = $Module::FctHash;
         #verify if the command is supported before 
         #execution, check if the key is supported
         if(exists($SupportedCommandRefenece->{$InputCommand}) )
         {
           // execute the function with arguments
           $SupportedCommandRefenece->{$InputCommand}(@Arguments开发者_开发技巧);
         }
      }

      # now, evaluate the inputs first and then execute the function
      &ExecuteCommand('FctInitEvaluate', 'Some input');
      &ExecuteCommand('FctInitExecute', 'Some input');
    }

But now, this technique seems to work! Still, is there a way to improve it?


You can use can. Please see perldoc UNIVERSAL for details.

use strict;
use warnings;
require Module;

sub ExecuteCommand {
    my ($InputCommand, @Arguments) = @_;
    if (my $ref = Module->can($InputCommand)) {
        $ref->(@Arguments);
    }
    # ...
}


You've built a fairly standard implementation for using a hash as a dispatch table. If that's your intention, I don't seen any reason to do more than clean it up a little. can is a good alternative if you're attempting to build something OO-ish, but that's not necessary if all you're after is a command lookup table.

Here's a version that a) is runnable Perl as it stands (your attempt to mark comments with // in the question's version is a syntax error; in Perl, // is the 5.10-and-higher "defined-or" operator, not a comment marker) and b) has more of a perlish accent:

Module.pm

package Module;

use strict;
use warnings;
use 5.010;

our $function_lookup = {
    FctInitEvaluate => \&init_evaluate,
    FctInitExecute  => \&init_execute,
};

sub init_evaluate {
    say 'In init_evaluate';
}

sub init_execute {
    say 'In init_execute';
}

1;

script.pl

#!/usr/bin/env perl

use strict;
use warnings;

require Module;

execute_command('FctInitEvaluate', 'Some input');
execute_command('FctInitExecute',  'Some input');

sub execute_command {
    my ($input_command, @arguments) = @_;
    $Module::function_lookup->{$input_command}(@arguments)
      if exists($Module::function_lookup->{$input_command});
}
0

精彩评论

暂无评论...
验证码 换一张
取 消