in reply to Interpolation requires a spurious variable. Why?

This is a precedence problem. See Symbolic Unary Operators in perlop.

When the expression
    \ $name || $default
is evaulated, the sub-expression  \ $name has highest precedence. A reference is always true, so the second sub-expression (i.e., the  $default scalar) is never evaluated.

I would prefer the approach given by moritz above, but if you absolutely must do code interpolation within a string, here are a couple of approaches:

>perl -wMstrict -le "my $default = q{''}; for my $name ('', 'fred') { print qq{name = ${ \ do { $name || $default }}}; print qq{name = @{[ $name || $default ]}}; } " name = '' name = '' name = fred name = fred

Replies are listed 'Best First'.
Re^2: Interpolation requires a spurious variable. Why?
by ikegami (Patriarch) on Sep 23, 2009 at 22:13 UTC
    The most straightforward way to resolve precedence issues is to add parens.
    ${\( $name || $default )}
Re^2: Interpolation requires a spurious variable. Why?
by LanX (Saint) on Sep 23, 2009 at 22:18 UTC
    why not  print " ${\ ($name||$default) }" ???

    Works fine for me! 8)

    Cheers Rolf

Re^2: Interpolation requires a spurious variable. Why?
by AnomalousMonk (Archbishop) on Sep 24, 2009 at 03:10 UTC
    I missed the parenthesization approach of ikegami and LanX, but my personal preference (after moritz's approach, of course) would be  "@{[ ... code ... ]}" temporary array interpolation. This is probably more expensive computationally, but it appeals to me as 'cleaner' code.
      Why should it be cleaner? It's just another case and depends on the context you want for the inner code.

      Instead of a scalar you require a list to be interpolated into a string!

      (which also involves the extra complication of setting $" appropiately.)

      Cheers Rolf

        It's just another case and depends on the context you want for the inner code.
        Not really.
        "@{[ ... list context ... ]}";
        That's what everyone expects. But:
        "${\(... list context ... )}";
        The reference operator (\) provides list context to its arguments. I've been bitten by this in the past as well.

        Update please disregard, I should have read more carefully...

        It's cleaner because it also works when multiple elements are present:

        use strict; use warnings; use 5.010; my ($a, $b) = (4, 5); say "@{ [$a // 2, $b] }"; # 4 5 say "@{\($a // 2, $b) }"; # Not an ARRAY reference at foo.pl l +ine 8.

        The feature of \( LIST ) to return the same as map \$_, LIST is not always intuitive.

        Perl 6 - links to (nearly) everything that is Perl 6.

      It's not so much that it's "cleaner". The reason I'd prefer it myself is that it's idiomatic. It's a fairly well-known construct. Even if you don't use it yourself, it's worth knowing because it's something you'll probably see in others' code.

      I don't think the same is as true of "${\()}" -- I can't recall ever seeing that before today.