raygun has asked for the wisdom of the Perl Monks concerning the following question:

Greetings, I present an elementary question for a bored monk.
$ perl -e 'print "\@hi\n";' @hi

I understand why the backslash before the @ is required here to get a literal @ in an interpolating string: without it, the @ would be interpreted as indicating an array named hi.

It is not needed (though adding it is harmless) in strings where there is no ambiguity about what the @ might represent:

$ perl -e 'print "@=hi\n";' @=hi
But why is it needed to signal a literal @ in the following?
$ perl -e 'print "@$0\n";' $ perl -e 'print "\@$0\n";' @-e

How can an @ followed by a $ be interpreted as a valid array name? (The reverse, $@, is a predefined variable, but @$ is not.) And if it can't, why is the backslash needed to indicate this @ is literal?

Replies are listed 'Best First'.
Re: escaping the @ in an interpolating string
by Corion (Patriarch) on Aug 10, 2024 at 17:54 UTC
    @$0 is seen as @{ $0 }, which takes $0 as a symbolic reference to the array named -e:

    perl -e '@{q(-e)} = qw(Hello World); print "$0: @$0\n"'
    -e: Hello World

    If you enable strict, symbolic references are disallowed though:

    perl -Mstrict -e '@{q(-e)} = qw(Hello World); print "$0: @$0\n"'
    Can't use string ("-e") as an ARRAY ref while "strict refs" in use at +-e line 1.
      Also, if you are unsure what $0 means see 'perldoc perlvar' and search for $0.

        Or

        perldoc -v '$0'

        See also: perldoc

      I guess I should have been less specific!
      @$0 is seen as @{ $0 }
      The issue isn't limited to $0 following the @: no matter what variable follows it—whether it exists or not—the @ is not interpreted literally.
      $ perl -e 'print "@$$\n";' $ perl -e 'print "@$undefined_variable\n";' $ perl -e 'print "@$]\n";' ] $ perl -e 'print "@$(\n";' (
      Interestingly, sometimes the entire @$foo seems to be interpreted as a unit, printing nothing, and other times @$ seems to be interpreted as one unit, printing whatever follows it literally. In no case is the @ interpreted literally. And, of course, in all cases preceding the @ with a backslash solves that, and allows the following variable to be interpolated:
      $ perl -e 'print "\@$$\n";' @24477 $ perl -e 'print "\@$undefined_variable\n";' @ $ perl -e 'print "\@$]\n";' @5.030003 $ perl -e 'print "\@$(\n";' @500 7 10 11 16 18 19 27 35 80 85 100 105 500
        Those are all doing the same thing that Corion explained. They are inferring that $$, $undefined_variable etc are symbolic references to an array. If you 'use strict' it will give an error. Without 'use strict' you can do something like:
        perl -e '@hi = (1,2,3), my $x = "hi"; print "@$x\n";'
        and it will output:
        1 2 3
        More to the point, @$foo is perfectly useful syntax even with strict enabled:
        use strict; use warnings; my $foo= [ 1, 2, 3 ]; for (@$foo) { say $_ }
        In the case of those punctuation variables (e.g. $] and $(), Perl interprets "@$]" as "@$" and "]", and since @$ is empty, you get nothing, followed by the punctuation character.
        Jeffrey Pinyan (TypeScript, JavaScript, PHP, Perl; in that order nowadays)
        @JeffPinyan@NightSkyJeff
        Melius servire volo