Perl internal variables. Are next expressions same?

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

I have two expressions:

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

and

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

are these tw

相关标签:
2条回答
  • 2021-01-15 03:23

    Almost

    ${ "::_<$filename" } is the scalar variable in the default/main namespace with the name given by "_<$filename"

    %{"main::"} is the stash variable for the default/main namespace, and ${"main::"}{"_<$filename"} is a typeglob which can be derefenced with any of the dereferencing operators to retrieve the values in the main namespace with the name given by "_<$filename".

    So it's these two expressions are equivalent:

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

    A short demo:

    $ perl -de 1
    
    Loading DB routines from perl5db.pl version 1.37
    Editor support available.
    
    Enter h or 'h h' for help, or 'man perldebug' for more help.
    
    main::(-e:1):   1
      DB<1> $main::foo = 42                                                                                    
    
      DB<2> @main::foo = (1,2,3,"bacon")                                                                       
    
      DB<3> x ${"main::"}{"foo"}                                                                               
    0  *main::foo
      DB<4> x ${${"main::"}{"foo"}}, @{${"main::"}{"foo"}}                                                     
    0  42
    1  1
    2  2
    3  3
    4  'bacon' 
      DB<5> x @{"::foo"}, ${"::foo"}                                                                           
    0  1
    1  2
    2  3
    3  'bacon'
    4  42
    
    0 讨论(0)
  • 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" }
    
    0 讨论(0)
提交回复
热议问题