Perl internal variables. Are next expressions same?

后端 未结 2 958
醉酒成梦
醉酒成梦 2021-01-15 03:01

I have two expressions:

${ \'main::\' }{ \"_<$filename\" }

and

${ \"::_<$filename\" }

are these tw

2条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-15 03:34

    No, but the following are equivalent:

    ${"_<$filename"}         # When this expression is found in package main
    ${"::_<$filename"}
    ${"main::_<$filename"}
    
    ${ $::{"_<$filename"} }
    ${ ${'::'}{"_<$filename"} }
    
    ${ $main::{"_<$filename"} }
    ${ ${'main::'}{"_<$filename"} }
    

    These are refer to the variable in the root/main namespace whose name is produced by "_<$filename".


    As a clearer example, the following are all equivalent (assuming the code is compiled in package Foo::Bar for the first two):

    @moo                                  # Via hardcoded, unqualified name
    @{'moo'}                              # Via symref using unqualified name
    
    @Foo::Bar::moo                        # Via hardcoded, qualified name
    @{'Foo::Bar::moo'}                    # Via symref using qualified name
    
    @{ *Foo::Bar::moo }                   # Via hardcoded glob
    @{ *{'Foo::Bar::moo'} }               # Via symref to glob
    
    @{ $Foo::Bar::{moo} }                 # Via glob via hardcoded package
    @{ ${'Foo::Bar::'}{moo} }             # Via glob via symref to package
    
    @{ $Foo::{'Bar::'}{moo} }             # Via glob via hardcoded parent package
    @{ ${'Foo'}::{'Bar::'}{moo} }         # Via glob via symref to parent package
    
    @{ $::{'Foo::'}{'Bar::'}{moo} }       # Via glob via root package
    @{ $main::{'Foo::'}{'Bar::'}{moo} }   # Same
    

    Perl allows symbol names to be used as references.

    $ perl -e'%h = ( a => 4, b => 5 ); my $ref = "h"; CORE::say $ref->{a};'
    4
    

    These are called "symbolic references" (and they're not allowed when using use strict;). The following uses main:: as a symbolic reference:

    ${ 'main::' }{ "_<$filename" }
    

    There's no point to doing that, however. Since the name of the variable is hardcoded anyway, we might as well use the following:

    $main::{ "_<$filename" }
    

    Not only is this simpler, it's allowed when using use strict;.


    But what is %main::? Well, that's the symbol table for the package main. The keys of %main:: are the names of the symbols (variables) that exist in the package main (without any sigil).

    The values of %main:: are symbol table entries. We call these "typeglobs", or "globs" for short. Dereferencing a glob as if it was a reference access the variable of the type appropriate for the dereference. For example,

    $main::{a}
    

    returns

    *main::a       # A glob
    

    and

    ${ $main::{a} }
    

    returns

    $main::a
    

    This means that the following returns a glob to the variable in the main namespace whose name is produced by "_<$filename"

    $main::{ "_<$filename" }
    

    The main namespace is also the root namespace. This means that

    $main::a
    

    and

    $::a
    

    both refer to the same variable. It also means that

    %main::
    

    and

    %::
    

    both refer to the same variable. It also means that

    $main::{ "_<$filename" }
    

    and

    $::{ "_<$filename" }
    

    both return the same glob.


    We've established that the following returns a glob to the symbol in the root/main namespace whose name is produced by "_<$filename"

    $::{ "_<$filename" }
    

    We've also established that the following references the scalar in the root/main whose name is produced by "_<$filename":

    ${ $::{ "_<$filename" } }
    

    And finally, we've also established that following is a symbolic reference that references the same scalar:

    ${ "::_<$filename" }
    

提交回复
热议问题