rkmax
rkmax

Reputation: 18125

How to call a function from hash in perl

i trying yo doing the the following pseudocode in perl

#!/usr/bin/perl -w
#App.pm

use strict;
use OtherModule;
use Other2Module;

sub App::hashF
{
  my $hash_funtion = {
    'login' => OtherModule::login,
    'logout' => Other2Module::logout
  };

  my($module, $params) = @_;

  return $hash->{$module}($params);
}

but i get error like: - Can't use string ("login") as a subroutine ref while "strict refs" - Can't use bareword ("OtherModelo") as a HASH ref while "strict refs"

Upvotes: 0

Views: 1311

Answers (2)

amon
amon

Reputation: 57590

I decided to enhance your code:

#!/usr/bin/perl
#App.pm

use strict; use warnings;

package App;

use OtherModule;
use Other2Module;

my $hash = {
  login  => \&OtherModule::login,
  logout => \&Other2Module::logout,
};

sub hashF
{    
  my($module, @params) = @_;

  return $hash->{$module}->(@params);
}

We cannot assign bare names, but we can pass around code references. The & Sigil denotes the "code" type or a subroutine, and \ gives us a reference to it. (Not getting a reference would execute the code; not something we want. Never execute &subroutine unprovoked.)

BTW: Hashes can only hold scalar values, and (code) references are a kind of scalar.

When we want to call our sub from the hash, we have to use the dereference operator ->. $hash->{$module} returns a code reference as value; ->(@arglist) executes it with the given arguments.

Another BTW: Don't write App::hashF unless you are working inside an external module. You can declare your current namespace by writing package App or whatever name you like (should correspond with path/name of .pm file).

Upvotes: 8

mu is too short
mu is too short

Reputation: 434585

This construct:

my $hash_funtion = {
  'login' => OtherModule::login,
  'logout' => Other2Module::logout
};

is calling the OtherModule::login function and assigning its return value to $hash_funtion->{login}, similarly for logout. You want to store references to the functions in the hash's values:

my $hash_funtion = {
  'login'  => \&OtherModule::login,
  'logout' => \&Other2Module::logout
};

Then the rest will work fine (assuming you correct the typos of course).

Upvotes: 3

Related Questions