Search code examples
perl

Refer to a subroutine with a scalar


Is it possible to get the example below to work so that the name of the subroutine is stored and called via a scalar variable?

use strict;
use warnings;

sub doit {
    my ($who) = @_;
    print "Make us some coffee $who!\n";
}

sub sayit {
    my ($what) = @_;
    print "$what\n";
}

my $action = 'doit';
$action('john');

Solution

  • You could put it in a hash:

    my %hash;
    $hash{'doit'} = \&doit;
    $hash{'doit'}->('Mike');
    

    Or you could make it an anonymous sub right away

    my %hash = ( doit  => sub {  ... },
                 sayit => sub { .... },
                ....);
    

    As Dada mentions, it is a scalar value, so it can also be put in a scalar variable:

    my $command = \&doit;
    $command->('Mike');
    

    Technically you can also put a string into a scalar, and use that as a subroutine:

    my $action = 'doit';
    $action->('Mike');      # breaks strict 'refs'
    

    But if you are using use strict, like you should, it will not allow you, and will die with the error:

    Can't use string ("doit") as a subroutine ref while "strict refs" in use...
    

    So don't do that. If you want to use strings to refer to subs, using a hash is the proper way. But if you still want to, you can

    no strict 'refs';
    

    To get away with it.