Why does Perl evaluate code in ${…} during string interpolation?

后端 未结 3 927
死守一世寂寞
死守一世寂寞 2021-01-05 09:26

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 al

3条回答
  •  甜味超标
    2021-01-05 09:35

    From the "Using References" section of the perlref documentation:

    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. In other words, the previous examples could be written like this:

    $bar = ${$scalarref};
    push(@{$arrayref}, $filename);
    ${$arrayref}[0] = "January";
    ${$hashref}{"KEY"} = "VALUE";
    &{$coderef}(1,2,3);
    $globref->print("output\n");  # iff IO::Handle is loaded
    

    Admittedly, it's a little silly to use the curlies in this case, but the BLOCK can contain any arbitrary expression, in particular, subscripted expressions:

    &{ $dispatch{$index} }(1,2,3);    # call correct routine
    

    Because of being able to omit the curlies for the simple case of $$x, people often make the mistake of viewing the dereferencing symbols as proper operators, and wonder about their precedence. If they were, though, you could use parentheses instead of braces. That's not the case. Consider the difference below; case 0 is a short-hand version of case 1, not case 2:

    $$hashref{"KEY"}   = "VALUE";     # CASE 0
    ${$hashref}{"KEY"} = "VALUE";     # CASE 1
    ${$hashref{"KEY"}} = "VALUE";     # CASE 2
    ${$hashref->{"KEY"}} = "VALUE";   # CASE 3
    

    Case 2 is also deceptive in that you're accessing a variable called %hashref, not dereferencing through $hashref to the hash it's presumably referencing. That would be case 3.

    Later in "Symbolic references":

    We said that references spring into existence as necessary if they are undefined, but we didn't say what happens if a value used as a reference is already defined, but isn't a hard reference. If you use it as a reference, it'll be treated as a symbolic reference. That is, the value of the scalar is taken to be the name of a variable, rather than a direct link to a (possibly) anonymous value.

提交回复
热议问题