in reply to Calling a hash member

If you really don't want to use a temporary variable (though I don't see why not), it may be possible to store a hard reference instead of a soft reference:

use ProjectA; my $project = 'ProjectA'; my %ThingsToDo = (firstTask => \{$project->prepare}); $ThingsToDo{firstTask};

Alternatively, you could make a dispatcher method in the ProjectA class that executes a given method:

use ProjectA; my $project = 'ProjectA'; my %ThingsToDo = (firstTask => 'prepare'); $project->doMethod($ThingsToDo{firstTask});

Replies are listed 'Best First'.
Re^2: Calling a hash member
by ikegami (Patriarch) on Dec 13, 2006 at 21:27 UTC
    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};

      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(@_) }.

Re^2: Calling a hash member
by revdiablo (Prior) on Dec 13, 2006 at 22:01 UTC

    That should probably have been:

    use ProjectA; my $project = 'ProjectA'; my %ThingsToDo = (firstTask => sub { $project->prepare }); $ThingsToDo{firstTask}->();