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

not sure how to title this....
#!/usr/bin/perl use strict; use Temp::Tool; my $page = 'test'; my $obj; my %states = ( module => \&Temp::Tool->new, ); if ($states{$page}){ $obj = $states{$page}->(); } package Temp::Tool; sub new{ print "test"; } 1;
the error says 'Undefined subroutine &Temp::Tool' what is the correct way to call this? is it possible?

Replies are listed 'Best First'.
Re: howto reference to a external sub/object/constructor thingy
by GrandFather (Saint) on Feb 23, 2006 at 04:20 UTC

    The Temp:: is a trap - Temp.pm would need to reside in a folder called Temp dangling off the @INC path somewhere.

    Code that works and looks somewhat like that which you posted is:

    #!/usr/bin/perl use strict; package Tool; sub new{ print "test"; } 1; package main; my $page = 'module'; my $obj; my %states = ( module => sub {Tool->new ()}, ); if ($states{$page}){ $obj = $states{$page}->(); }

    Prints:

    test

    Update per chromatic's suggestion


    DWIM is Perl's answer to Gödel

      That breaks inheritance. You oughtn't assume anything about how Tool gets or implements new(). I suggest instead:

      my %states = ( module => sub { Tool->new( @_ ) }, );
Re: howto reference to a external sub/object/constructor thingy
by ikegami (Patriarch) on Feb 23, 2006 at 06:43 UTC

    Just to explain the required change:

    \&function returns a reference to function function. Temp::Tool->new is not a function — it's a Perl expression — so \& can't be used. sub { ... } creates an (anonymous) function and returns a reference to it. All you have to do is to create a small function which executes your Perl expression.

    That trick can be used even if you have arguments, thanks to closures. For example,

    my $func; { my $arg1 = 'Hello'; $func = sub { my ($arg2) = @_; print("$arg1 $arg2\n"); } } { my $arg1 = 'Goodbye'; $func->('World'); }
    prints
    Hello World

    Lexical (my) variables are captured when sub is executed, and arguments can still be passed in as a normal function.