Recipe 1.15 Interpolating Functions and Expressions Within Strings1.15.1 ProblemYou want a function call or expression to expand within a string. This lets you construct more complex templates than with simple scalar variable interpolation. 1.15.2 Solution
Break up your expression into distinct
$answer = $var1 . func( ) . $var2; # scalar only Or use the slightly sneaky @{[ LIST EXPR ]} or ${ \(SCALAR EXPR ) } expansions:
$answer = "STRING @{[ LIST EXPR ]} MORE STRING";
$answer = "STRING ${\( SCALAR EXPR )} MORE STRING";
1.15.3 DiscussionThis code shows both techniques. The first line shows concatenation; the second shows the expansion trick:
$phrase = "I have " . ($n + 1) . " guanacos.";
$phrase = "I have ${\($n + 1)} guanacos.";
The first technique builds the final string by concatenating smaller strings, avoiding interpolation but achieving the same end. Because
print
effectively
print "I have ", $n + 1, " guanacos.\n";
When you
In the example:
$phrase = "I have ${\( count_em( ) )} guanacos.";
the function call within the parentheses is not in scalar context; it is still in list context. The following overrules that:
$phrase = "I have ${\( scalar count_em( ) )} guanacos.";
You can do more than simply assign to a variable after interpolation. It's a general mechanism that can be used in any double-quoted string. For instance, this example builds a string with an interpolated expression and
some_func("What you want is @{[ split /:/, $rec ]} items");
You can
die "Couldn't send mail" unless send_mail(<<"EOTEXT", $target);
To: $naughty
From: Your Bank
Cc: @{ get_manager_list($naughty) }
Date: @{[ do { my $now = `date`; chomp $now; $now } ]} (today)
Dear $naughty,
Today, you bounced check number @{[ 500 + int rand(100) ]} to us.
Your account is now closed.
Sincerely,
the management
EOTEXT
Expanding backquotes (
``
) is particularly challenging because you would normally end up with
Although these techniques work, simply breaking your work up into several steps or storing everything in temporary variables is almost always clearer to the reader. The Interpolation module from CPAN provides a more syntactically palatable covering. For example, to make elements of the hash %E evaluate and return its subscript:
use Interpolation E => 'eval';
print "You bounced check number $E{500 + int rand(100)}\n";
Or to make a hash named %money call a suitably defined function of your choice:
use Interpolation money => \¤cy_commify;
print "That will be $money{ 4 * $payment }, right now.\n";
expect to get something like:
That will be ,232.421.04, right now
.
1.15.4 See Alsoperlref (1) and the "Other Tricks You Can Do with Hard References" section in Chapter 8 of Programming Perl ; the Interpolation CPAN module |