Search code examples
perlhashcoderef

Is it possible to define anonymous subroutines in a hash constructor in Perl?


Is it possible to define anonymous subroutines in a hash constructor in Perl?

I'm trying to do something like this:

my %array = { one   => sub { print "first $_[0]" },
              two   => sub { print "next  $_[0]" },
              three => sub { print "last  $_[0]" }};

$array{$foo}->('thing');

But it isn't working. The code seems to run and compile, but the values in the array are blank. If I do this:

my %array;

$array{'one'}   = sub { print "first $_[0]" };
$array{'two'}   = sub { print "next  $_[0]" };
$array{'three'} = sub { print "last  $_[0]" };

$array{$foo}->('thing');

Then it seems to work fine. So I have a workaround, but it's just bugging me and I wondered if anyone knows whether it's possible and, if so, what the syntax is.


Solution

  • It looks like you're assigning into the hash incorrectly. Using {} constructs an anonymous hash reference, which you assign to a scalar. But you're assigning to a named hash (%array).

    You need to assign into a scalar:

    my $array = { one   => sub { print "first $_[0]" },
                  two   => sub { print "next  $_[0]" },
                  three => sub { print "last  $_[0]" }};
    
    $array->{$foo}->('thing');
    

    Or to not use the anon constructor syntax:

    my %array = ( one   => sub { print "first $_[0]" },
                  two   => sub { print "next  $_[0]" },
                  three => sub { print "last  $_[0]" });
    
    $array{$foo}->('thing');