http://qs321.pair.com?node_id=1080736

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

Hello,
is there a way to conditionally execute a subroutine defined as hash value?
In the example below I get both subroutines executed, while I'd like to only execute one of them based on the value of $test.
Thanks


use strict; my $calls = { A => \&print_A(), B => \&print_B(), }; my $test = 'A'; $calls->{$test}; sub print_A { print "\nA\n"; } sub print_B { print "\nB\n"; }

Replies are listed 'Best First'.
Re: How to conditionally execute a subroutine defined as hash value
by BrowserUk (Patriarch) on Apr 02, 2014 at 10:25 UTC

    By adding parens, where you are attempting to store the address of your subs:      A => \&print_A(),, you are invoking the subs and then string the address of whatever is returned (the value 1 from print).

    Try it this way:

    sub print_A { print "\nA\n"; } sub print_B { print "\nB\n"; } $calls = { A=> \&print_A, B=> \&print_B };; $calls->{'A'}();; A

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Thanks, but if I have to pass some parameters to the call like this?
      use strict; my %config_A = (A=>'a'); my %config_B = (B=>'b'); my $calls = { A => \&print_A(\%config_A), B => \&print_B(\%config_B), }; my $test = 'A'; $calls->{$test}; sub print_A { my $config = shift(); print $config->{A},"\n"; } sub print_B { my $config = shift(); print $config->{B},"\n"; }

        Then you'll need to wrap the calls in anonymous subs:

        my $calls = { A => sub{ print_A( \%config_A ); }, B => sub{ print_B( \%config_B ); }, }; my $test = 'A'; $calls->{$test}();

        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.

        You need to pass the parameters when you call the function, not when you store the reference.

        See tye's References Quick Reference.

        # Here you take the reference to the subroutine my $calls = { A => \&print_A, B => \&print_B, }; # Here you call the subroutine $calls->{ $test }->(\%config_A);

        When taking the reference, you should never use parentheses.

        Using Data::Dumper on %calls would show you what Perl stored in %calls.