Groups | Search | Server Info | Login | Register


Groups > comp.lang.perl.misc > #4787

Re: Embedding code in qq{}?

From tmcd@panix.com (Tim McDaniel)
Newsgroups comp.lang.perl.misc
Subject Re: Embedding code in qq{}?
Date 2012-03-18 07:07 +0000
Organization Tim McDaniel's at Panix
Message-ID <jk41js$p48$1@reader1.panix.com> (permalink)
References <87limyk471.fsf@Gmail.com>

Show all headers | View raw


In article <87limyk471.fsf@Gmail.com>, XeCycle  <XeCycle@Gmail.com>
wrote:
>Is it possible to use something like "${1+2}" -> "3"?

You made it clear in the rest of the article (which I trimmed) that
you were thinking about the right-hand side of a s///.  It turns out
that, in string contexts in general, you can do it.

Short answer:
    ${\(1+2)}

There are a couple of replies in
http://stackoverflow.com/questions/2332815/why-does-perl-evaluate-code-in-during-string-interpolation
that explain it.  I'll try to distill it.

There's a crucial sentence in "man perlref":

    Anywhere you'd put an identifier (or chain of identifiers) as part
    of a variable or subroutine name, you can replace the identifier
    with a BLOCK returning a reference of the correct type.

What does that mean?  Consider a simple scalar variable
    $foo
The identifier is "foo", so you can replace it with a block:
    ${ almost arbitrary code that evaluates to a ref to a scalar}
The only constraint is that the code has to evaluate to a reference to
a scalar.  Similarly for the array sigil
    @{ almost arbitrary code that evaluates to a ref to an array}
And I presume % and & too, though I didn't try them.

And I believe any of those can also appear in a double-quoted string.

Here's my example program (it happens to be my eighty-seventh test
script).  The stuff commented out with "##" causes the syntax errors
noted after them.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#! /usr/bin/perl
use strict;
use warnings;

my $x = 'hello';
my $y = 'world';
print "${ \$x }\n";
print "${ if (0) { \$x; } else { \$y }; }\n";
## print "hey@{1+2}there\n"; # Can't use string ("3") as an ARRAY ref while "strict refs" in use at local/test/087.pl line 9.
print "hey${\(1+2)}there\n";
$" = '<blort>';
print "hey@{[1+2, 3*4]}there\n";
## print "hey${ { \$x; last; }; \$y }there\n";
# syntax error at local/test/087.pl line 13, near "; last"
# syntax error at local/test/087.pl line 13, near "};"
# Execution of local/test/087.pl aborted due to compilation errors.
print "hey${ ; { \$x; last; }; \$y }there\n"; # Useless use of single ref constructor in void context at local/test/087.pl line 17.
print ${ \$x }, "\n";
exit 0;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The output is

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Useless use of single ref constructor in void context at
local/test/087.pl line 17.
hello
world
hey3there
hey3<blort>12there
heyworldthere
hello

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If the block evaluates to a string, then it's looked up as the name of
a dynamic variable (as in "our", not "my").  I believe that's what
it's erroring about when line 9 is uncommented.

Note that the block parsing is not quite right (in Perl 5.10),
apparently when confronted with leading "{ {", as in
    ${ { \$x; last; }; \$y }
above.  As shown above, putting in a null statement at the start
unconfuses it.

It's a "block" in the same way as do { ... } instead of { ... }: it
doesn't allow "last" (though you can throw in interior {...} to make
it work, as shown in the example), and "return" returns from an
enclosing sub rather than the block.

So, back to your original question, see
    print "hey${\(1+2)}there\n";
above, which outputs
    hey3there

-- 
Tim McDaniel, tmcd@panix.com

Back to comp.lang.perl.misc | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

Embedding code in qq{}? XeCycle <XeCycle@Gmail.com> - 2012-03-18 10:56 +0800
  Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-17 23:04 -0400
    Re: Embedding code in qq{}? XeCycle <XeCycle@Gmail.com> - 2012-03-18 12:14 +0800
  Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-18 07:07 +0000
    Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-18 08:37 +0000
      Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-18 22:28 +0000
        Re: Embedding code in qq{}? merlyn@stonehenge.com (Randal L. Schwartz) - 2012-03-18 16:18 -0700
          Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 02:21 +0000
            Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-19 00:14 -0400
              Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 06:42 +0000
                Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-19 16:40 +0000
        Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 19:29 -0400
    Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 15:24 -0400
      Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-18 22:33 +0000
        Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 19:24 -0400
          Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-19 00:49 +0000
            Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-18 22:05 -0400
          Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 02:55 +0000
            Re: Embedding code in qq{}? Uri Guttman <uri@stemsystems.com> - 2012-03-19 00:12 -0400
              Re: Embedding code in qq{}? tmcd@panix.com (Tim McDaniel) - 2012-03-19 07:00 +0000
                Re: Embedding code in qq{}? Ben Morrow <ben@morrow.me.uk> - 2012-03-19 16:43 +0000

csiph-web