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

Given a simple subroutine:

sub q { print "q" };

What is it that causes the following to output nothing?

eval \&q;

While these others output as expected?

eval \q; eval \q(); eval \&q();

I've read about the ampersand and prototyping, but I'm not understanding this.

Replies are listed 'Best First'.
Re: eval'ing coderef with ampersand
by jwkrahn (Abbot) on Sep 04, 2010 at 03:36 UTC

    \q, \q() and \&q() first call the subroutine and then take a reference to its return value while \&q takes a reference to the subroutine itself.

      That is a subtle and significant difference. What I'm really doing is forking a list of processes; and I was alarmed that one process executed when I defined the list, prior to forking.

      Do you know where this is documented? I haven't seen it in perlref, my Cookbook, or elsewhere.

      Thanks!

        perlop says "Unary '\' creates a reference to whatever follows it." and refers you to perlref.

        perlref shows special that \&handler is the means of getting a reference to a function.

        \handler and \handler() are clearly not special cases, so the \ applies to the value returned by the expressions that follows. They could be written \( handler ) and \( handler() ).

        The behaviour of \&handler() is not documented, but there's only one parsing that wouldn't result in an error: \( &handler() ).

Re: eval'ing coderef with ampersand
by AnomalousMonk (Archbishop) on Sep 04, 2010 at 07:51 UTC

    ... and just as an addendum to jwkrahn's reply, prototyping is not used in and has no bearing on the behavior of any of the OPed statements.

    Update: This may also throw some light on what is happening:

    >perl -wMstrict -le "sub S { print 's' } print '[', eval \S, ']'; print $@; " s [] Undefined subroutine &main::SCALAR called at (eval 1) line 1.
      prototyping is not used in and has no bearing

      Agreed. My point was, prototyping is the only thing I can find regarding ampersands and subroutines.

      Thanks!