Why does the following snippet work at all? And what evil might be possible using this? But seriously, is there any reason, the code in ${}
gets evaluated at all and then used as scalar reference?
use strict;
no strict 'refs';
our $message = "Hello world!";
print "${ lc 'MESSAGE' }\n";
Interpolation in Perl refers to the process where the respective values replace the variable names. It is commonly used inside double-quoted strings.
String interpolation is a technique that enables you to insert expression values into literal strings.
This page shows how variable interpolation works in Perl. Interpolation, meaning "introducing or inserting something", is the name given to replacing a variable with the value of that variable.
We explain this in depth in Intermediate Perl.
The general syntax for variable lookups is:
SIGIL BLOCK INDEXY-THING
For a simple scalar that looks like:
print $ { foo };
You have probably seen this when you need to separate a variable name from things surrounding it:
print "abc${foo}def\n";
If you just have a Perl identifier in the block and no surrounding mess, you can leave off the braces, which is the common case:
print $foo;
However, this is the same thing for dereferencing a reference:
SIGIL BLOCK-RETURNING-REFERENCE INDEXY-THINGS
If the thing that you get in the block is a reference, Perl tries to dereference it like you asked it too:
my $ref = \ '12345';
print $ { $ref };
That's a real block though, and not just sugar. You can have as many statements as you like in there:
print $ { my $ref = \ '1234'; $ref };
Now you're not just specifying a Perl identifier, so Perl doesn't assume that you're giving it an identifier and it executes code and uses the result as a reference. Consider the difference between these almost identical say
statements:
use 5.010;
our $foo = "I'm the scalar";
sub foo { \ "I'm the sub" }
say ${foo};
say ${foo;};
In that second say
Perl sees the semi-colon, realizes it's not an identifier, interprets the code inside the braces as text, and returns the result. Since the result is a reference, it uses the ${...}
to dereference it. It doesn't matter where you do this, so that you do it inside a double-quoted string is not special.
Also, notice the our
there. That's important now that you're going to consider something a bit more tricky:
use 5.010;
our $foo = "I'm the scalar";
sub foo { \ "I'm the sub" }
sub baz { 'foo' }
say ${foo};
say ${foo;};
say ${baz;};
Perl intreprets that last say
as code and sees the result is not a reference; it's the simple string foo
. Perl sees that it's not a reference but it's now in a dereferencing context so it does a symbolic reference (as Greg Bacon describes). Since symbolic references work with variables in the symbol table, that $foo
had to be a package variable.
Since it's easy to mess this up, strict
has a handy check for it. However, when you turn it off, don't be surprised when it bites you. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With