Dada
Dada

Reputation: 6626

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

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 :

Upvotes: 23

Views: 1845

Answers (3)

Randal Schwartz
Randal Schwartz

Reputation: 44091

Some things are just because "Larry coded it that way". Or as I used to say in class, "It works the way you think, provided you think like Larry thinks", sometimes adding "and it's my job to teach you how Larry thinks."

Upvotes: 3

melpomene
melpomene

Reputation: 85767

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).

Upvotes: 17

Keith Thompson
Keith Thompson

Reputation: 263317

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.

Upvotes: 6

Related Questions