【问题标题】:Why are variables declared with "our" visible across files?为什么用“我们的”声明的变量在文件中可见?
【发布时间】:2011-04-07 06:32:57
【问题描述】:

来自“我们的”perldoc:

our 与 my 具有相同的范围规则,但不一定创建变量。

这意味着用our 声明的变量不应该跨文件可见,因为文件是最大的词法范围。但是这是错误的。为什么?

【问题讨论】:

    标签: perl variables lexical-scope


    【解决方案1】:

    您已经有了一个很好的答案,但也许这也会有所帮助。

    our 声明结合了my 和use vars 的各个方面。它的功能类似于use vars,因为它声明了包变量;但是,以这种方式声明的变量是词法范围的,不能在声明它们的范围之外访问(除非您使用变量的完全限定名称)。此外,使用our 声明的变量在其整个词法范围内可见,甚至跨越包边界。

    这是我不久前添加到 Perl 笔记中的表格。示例见this SO answer。

                  Scope/     Package
                  Namespace  Variable    Private    New
    ---------------------------------------------------
    my            Lexical    No          Yes        Yes
    our           Lexical    Yes         No         No
    use vars      Package    Yes         No         No
    

    【讨论】:

    • 人们必须记住,包不会创建范围:Know what creates a scope。
    • @brian 我同意你的观点,你写的文章很好,但我想知道包是否具有某些类似范围的特征。例如:perl -le 'package Foo; $x += 10; print $x; package B; $x += 10; print $x'。也许有比“范围”更好的词来描述该示例的情况?感谢您的意见。
    • 更好的词是“默认包”。不过,该包不会限制变量的可见性。它根本不像一个范围。
    • @brian 我想我更愿意用不那么鲜明的方式来描述事情。包确实限制了变量的可见性——但仅限于有限的程度。在package Bar、$Foo::x 里面可能不是看不见,但它是模糊的。或者也许有人可以说它隐藏在命名空间后面,这可能是我正在寻找的替代词。如果我们允许使用黑魔法,即使是词法范围的变量在其词法域之外也不是完全不可见的。在任何情况下,作用域和命名空间都不是无关的。如果不出意外,他们分享了一些潜在的动机。
    • 你的想法是错误的。包不会限制可见性。说别的都是错的。
    【解决方案2】:

    您可以考虑使用our 为包全局变量创建一个词法范围的别名。包全局变量可以从任何地方访问;这就是使它们全球化的原因。但our 创建的名称仅在our 声明的词法范围内可见。

    package A;
    use strict;
    {
      our $var; # $var is now a legal name for $A::var
      $var = 42; # LEGAL
    }
    
    say $var; # ILLEGAL: "global symbol $var requires explicit package name"
    say $A::var; # LEGAL (always)
    
    {
      our $var; # This is the same $var as before, back in scope
      $var *= 2; # LEGAL
      say $var; # 84
    }
    

    【讨论】:

    • 它确实是一个别名,如果它只是对strict 的豁免,那么perl -le 'our $foo = 42; package A; print "$foo $main::foo"' 42 42 将打印与perl -le 'use vars qw/$foo/; $foo = 42; package A; print "$foo $main::foo"' 相同的内容,这是一个豁免,我们不需要@ 987654328@.
    猜你喜欢
    • 2021-12-21
    • 2011-05-14
    • 2023-03-24
    • 1970-01-01
    • 2016-09-18
    • 2015-05-02
    • 2013-04-16
    • 1970-01-01
    相关资源
    最近更新 更多