in reply to Re: Calling a hash member
in thread Calling a hash member

Your first snippet doesn't work. For example, the following doesn't print 1 and 2.
{ package ProjectA; { my $i; sub prepare { print ++$i, "\n"; } } } my $project = 'ProjectA'; my %ThingsToDo = (firstTask => \{$project->prepare}); $ThingsToDo{firstTask}; $ThingsToDo{firstTask};

Replies are listed 'Best First'.
Re^3: Calling a hash member
by geekphilosopher (Friar) on Dec 14, 2006 at 01:46 UTC

    Hrm, good catch. Do you happen to know why this doesn't work? Does the coderef not maintain the closure or something?

      • my $r = \{expr};

        is the same thing as

        my @rv = expr; my %h = @rv; my $hr = \%h; my $r = \$hr;

        There's no coderef anywhere in there. That sets the value at key firstTask to a reference to a reference to a hash which was initialized with the result of prepare.

      • Furthermore,

        $ThingsToDo{firstTask};

        is a no-op. Even if $ThingsToDo{firstTask} returned a code reference, there's nothing to cause the referenced code to get executed. To execute the code referenced by $ThingsToDo{firstTask}, use

        &{$ThingsToDo{firstTask}}();

        or better yet,

        $ThingsToDo{firstTask}->();
      • Finally, $project needs to be variable. It needs to be an argument.

      I think you meant

      my %ThingsToDo = ( firstTask => sub { my $pkg = shift; $pkg->prepare(@_) }, ); ... $ThingsToDo{firstTask}->($project);

      But that's much more complex than required, and would involve lots of redundancy (sub { my $pkg = shift; $pkg->XXX(@_) }.

        Thanks a lot - I figured this was a good opportunity for a code ref, but I don't actually have much experience using them. Next time I'll have a go at a few sample programs before I offer (dubious) advice.