in reply to Using Subroutine Returns

So, you're trying to interpolate the return value of a subroutine into a string? That would be:

print "@{[config('username')]} is my username";

(i.e., you fill an anonymous array with one value, and then dereference it with @{} — which works because arrays are interpolated)

Similarly, you could also do (using a scalar ref)

print "${\config('username')} is my username";

Replies are listed 'Best First'.
Re^2: Using Subroutine Returns
by ELISHEVA (Prior) on Apr 23, 2009 at 03:47 UTC

    This is not a general solution for interpolating subroutines. Whether you use "${\foo()}" or "@{[foo()]}", foo() will be running in list context. In contrast, foo() . '...' and "$username" both run in scalar context.

    If the return value is context sensitive, the list context value will be returned instead of the expected scalar context value, as this code snippet demonstrates:

    sub foo { wantarray() ? 10 : 1; } print 'Scalar context: '; print ''. foo(); print ', '; print foo() . "\n"; print 'List context: '; print "@{[foo()]}, "; print "${\foo()}\n"; # outputs Scalar context: 1, 1 List context: 10, 10

    To preserve the scalar context without stuffing the return value into a variable, one must use concatentation, e.g. '' . foo() or  "mumble " . foo() . " the burrowgroves" (or forced scalar context as ig points out below).

    Best, beth

      Or force a scalar context on the interpolated subroutine calls:

      sub foo { wantarray() ? 10 : 1; } print 'Scalar context: '; print ''. foo(); print ', '; print foo() . "\n"; print 'List context: '; print "@{[foo()]}, "; print "${\foo()}\n"; print 'Scalar context: '; print "@{[scalar(foo())]}, "; print "${\scalar(foo())}\n"; __END__ Produces: Scalar context: 1, 1 List context: 10, 10 Scalar context: 1, 1

      But, while this is possible, I can't imagine it being preferable to concatenation for producing a scalar context.

Re^2: Using Subroutine Returns
by perrin (Chancellor) on Apr 23, 2009 at 03:35 UTC
    So complicated and ugly! Just concatenate it with the '.' operator.
      So complicated and ugly!

      That's true, of course... but some people just want to interpolate :) — I have to admit I've also felt that urge at times...

      This is probably the outcome of the generalizing behavior of our brains: we've learnt we can interpolate scalars and arrays, so why not also hashes, functions, anything?  (This behavior, in and of itself, is certainly a Good Thing, BTW, otherwise we probably wouldn't be where we are today, messing with Perl... supported by those little silicon chips, etc.)

      Also, some people just find

      "abc ${\config('username')} xyz";

      easier to read/type than

      "abc ".config('username')." xyz";

      even though they are exactly the same number of chars.

      Anyhow, the nice thing is that with Perl's TIMTOWTDI-ness, everyone can get happy :)

      It is in a print, so a comma would be more natural than a dot. There is no need to build a single scalar when the operator takes a list.
      print config('username'), " is my username";
      Most likely the OP would want a \n in there too, but that isn't really part of the interpolation question.
Re^2: Using Subroutine Returns
by rlang (Novice) on Apr 23, 2009 at 00:23 UTC
    Thank you for your fast response! That's exactly what I needed.