Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are @@, @!, @, etc. not interpolated in strings?

Tags:

First, please note that I ask this question out of curiosity, and I'm aware that using variable names like @@ is probably not a good idea.

When using doubles quotes (or qq operator), scalars and arrays are interpolated :

$v = 5; say "$v"; # prints: 5 $@ = 6; say "$@"; # prints: 6 @a = (1,2); say "@a"; # prints: 1 2 

Yet, with array names of the form @+special char like @@, @!, @,, @%, @; etc, the array isn't interpolated :

@; = (1,2); say "@;"; # prints nothing say @; ; # prints: 1 2 

So here is my question : does anyone knows why such arrays aren't interpolated? Is it documented anywhere?

I couldn't find any information or documentation about that. There are too many articles/posts on google (or SO) about the basics of interpolation, so maybe the answer was just hidden in one of them, or at the 10th page of results..

If you wonder why I could need variable names like those :

  • The -n (and -p for that matter) flag adds a semicolon ; at the end of the code (I'm not sure it works on every version of perl though). So I can make this program perl -nE 'push@a,1;say"@a"}{say@a' shorter by doing instead perl -nE 'push@;,1;say"@;"}{say@', because that last ; convert say@ to say@;. Well, actually I can't do that because @; isn't interpolated in double quotes. It won't be useful every day of course, but in some golfing challenges, why not!

  • It can be useful to obfuscate some code. (whether obfuscation is useful or not is another debate!)

like image 315
Dada Avatar asked Sep 15 '16 22:09

Dada


People also ask

Which strings do not interpolate variables?

Interpolation: The variable parsing is allowed when the string literal is enclosed with double quotes or with heredocs. Single quoted string or nowdocs, does not supports variable interpolation.

What is the purpose of string interpolation?

In computer programming, string interpolation (or variable interpolation, variable substitution, or variable expansion) is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values.

What is interpolated string in C#?

An interpolated string is a string literal that might contain interpolation expressions. When an interpolated string is resolved to a result string, items with interpolation expressions are replaced by the string representations of the expression results. This feature is available starting with C# 6.

What is the correct syntax for string interpolation?

Syntax of string interpolation starts with a '$' symbol and expressions are defined within a bracket {} using the following syntax. Where: interpolatedExpression - The expression that produces a result to be formatted.


2 Answers

Unfortunately I can't tell you why, but this restriction comes from code in toke.c that goes back to perl 5.000 (1994!). My best guess is that it's because Perl doesn't use any built-in array punctuation variables (except for @- and @+, added in 5.6 (2000)).

The code in S_scan_const only interprets @ as the start of an array if the following character is

  • a word character (e.g. @x, @_, @1), or
  • a : (e.g. @::foo), or
  • a ' (e.g. @'foo (this is the old syntax for ::)), or
  • a { (e.g. @{foo}), or
  • a $ (e.g. @$foo), or
  • a + or - (the arrays @+ and @-), but not in regexes.

As you can see, the only punctuation arrays that are supported are @- and @+, and even then not inside a regex. Initially no punctuation arrays were supported; @- and @+ were special-cased in 2000. (The exception in regex patterns was added to make /[\c@-\c_]/ work; it used to interpolate @- first.)

There is a workaround: Because @{ is treated as the start of an array variable, the syntax "@{;}" works (but that doesn't help your golf code because it makes the code longer).

like image 74
melpomene Avatar answered Oct 07 '22 18:10

melpomene


Perl's documentation says that the result is "not strictly predictable".

The following, from perldoc perlop (Perl 5.22.1), refers to interpolation of scalars. I presume it applies equally to arrays.

Note also that the interpolation code needs to make a decision on where the interpolated scalar ends. For instance, whether "a $x -> {c}" really means:

"a " . $x . " -> {c}"; 

or:

"a " . $x -> {c}; 

Most of the time, the longest possible text that does not include spaces between components and which contains matching braces or brackets. because the outcome may be determined by voting based on heuristic estimators, the result is not strictly predictable. Fortunately, it's usually correct for ambiguous cases.

like image 33
Keith Thompson Avatar answered Oct 07 '22 16:10

Keith Thompson