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

Hi, i have been trying to find how subroutine is executed.. the reason being
$hash = { key => ' value1 '.get_value2()}
actually works.. and appends output of get_value2 sub to the but
$hash = {key => ' value1 '.\&get_value2()}
prints

key value1 SCALAR(0x604de8)

in first case, when exactly perl runs subroutine? does it runs get_vlaue2() every time we try to access $hash->{key}?

Replies are listed 'Best First'.
Re: subroutine / dot operator / hash vlaue
by kcott (Archbishop) on Dec 10, 2015 at 07:19 UTC

    G'day starfire4444,

    Welcome to the Monastery.

    When you call a subroutine with a leading '&', you are specifying that you wish to ignore whatever prototype you used in the subroutine definition. Did you use a prototype? If so, do you want to ignore it?

    In almost all cases, the answer to first question is NO: consequently, the second conditional question is not applicable. Unless you know exactly what you're doing, and are able to explain with unerring clarity why you're doing it, never call a subroutine with a leading ampersand.

    At this point, it may be useful to read the SYNOPSIS of perlsub.

    I strongly suspect that your definition of get_value2 does not include a prototype. If it does, you need to show it. If it doesn't, adding an ampersand makes no difference; however, its presence suggests that a prototype was involved: be wary of angry maintenance programmers with clenched fists; read about hubris in perlglossary.

    Now, let's just take this one step at a time:

    1. Printing the return value directly:

      $ perl -wE 'sub f { 42 } say f()' 42 $ perl -wE 'sub f { 42 } say &f()' 42
    2. Saving the return value and then printing:

      $ perl -wE 'sub f { 42 } my $x = f(); say $x' 42 $ perl -wE 'sub f { 42 } my $x = &f(); say $x' 42
    3. Saving a reference to the return value and then printing:

      $ perl -wE 'sub f { 42 } my $x = \f(); say $x' SCALAR(0x7fc8f2805480) $ perl -wE 'sub f { 42 } my $x = \&f(); say $x' SCALAR(0x7f9783805480)
    4. Saving a reference to the return value and then printing the dereferenced return value:

      $ perl -wE 'sub f { 42 } my $x = \f(); say $$x' 42 $ perl -wE 'sub f { 42 } my $x = \&f(); say $$x' 42

    As I hope you can now see, adding an ampersand when calling a subroutine, which was defined without a prototype, serves no purpose whatsoever other than to appease whomsoever personifies Confusion in whatever mythos you subscribe to.

    [Aside: What you're referring to as the dot operator is, in fact, the string concatenation operator: see "perlop: Additive Operators".]

    — Ken

Re: subroutine / dot operator / hash vlaue
by tangent (Parson) on Dec 10, 2015 at 02:44 UTC
    in first case, when exactly perl runs subroutine? does it runs get_vlaue2() every time we try to access $hash->{key}?
    You can use a few print statements to find this out:
    print "Start\n"; my $hash = { key => 'value1' . get_value() }; print "hash created\n"; print "accessing hash key\n"; my $key = $hash->{'key'}; print "hash key is '$key'\n"; print "Finish\n"; sub get_value { print "get_value() called\n"; return "value"; }
      return gmtime.' '.rand ;
Re: subroutine / dot operator / hash vlaue ( backslash amperstand operator \& )
by Anonymous Monk on Dec 10, 2015 at 01:42 UTC
Re: subroutine / dot operator / hash vlaue
by dsheroh (Monsignor) on Dec 10, 2015 at 07:57 UTC
    To answer your question more directly, in the first case, Perl runs the subroutine once, when the line of code you showed is run, then prepends 'value 1' to the result and stores that in the hash. You can easily prove this thusly:
    #!/usr/bin/env perl use strict; use warnings; use 5.010; my $hash = { key => ' value1 '.get_value2()}; say $hash->{key}; say $hash->{key}; say $hash->{key}; $hash = { key => ' value2 '.get_value2()}; say $hash->{key}; say $hash->{key}; say $hash->{key}; sub get_value2 { return rand(); }
    Output:
    value1 0.557144237523065 value1 0.557144237523065 value1 0.557144237523065 value2 0.0543176085661514 value2 0.0543176085661514 value2 0.0543176085661514
    Every time my get_value2 is called, it will return a different random number, but you can see in the output that the value printed changed only when I re-set the hash, not each time the hash was accessed.

    But I agree that this smells like an XY Problem. What are you actually trying to accomplish (or what bug are you actually attempting to identify) here?

Re: subroutine / dot operator / hash vlaue
by stevieb (Canon) on Dec 10, 2015 at 01:55 UTC

    Beyond what Anonymonk stated above, this appears to be an XY Problem. Please state what you're trying to achieve here.

    ie. in the second example, you're implanting a reference to the function instead of having it evaluate and placing its value. Why?

      "... a reference to the function ..."

      Sorry for being horribly blunt stevieb, but that's just wrong!

      Reference to the return value of this function (i.e. a scalarref):

      $ perl -wE 'sub f { 42 } say \&f()' SCALAR(0x7f8070805480)

      Reference to a function (i.e. a coderef):

      $ perl -wE 'sub f { 42 } say \&f' CODE(0x7ff5d90314f0)

      Another offering at the altar of "whomsoever personifies Confusion" :-) [reference taken from my reply to OP]

      — Ken