【问题标题】:imported perl variable imports with no value导入的 perl 变量导入没有值
【发布时间】:2011-12-28 16:24:11
【问题描述】:

已解决: 事实证明,我的问题根源在于我没有在 @EXPORT_OK 赋值中的 DEBUGVAR 前面加上 $ 并且 "使用 config_global qw(config DEBUGVAR);"线。由于它没有引发错误,我无法知道这是问题所在。因此,解决方法是在这些点将正确的语法放在变量前面。

所以我试图掌握编写和导入 perl 模块的窍门。我不知道为什么这样做变得如此困难,但我在这个看似微不足道的任务上遇到了很多麻烦。这是我的模块的内容:

package global_config;
use strict;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(DEBUGVAR);

our ($DEBUGVAR);

our $DEBUGVAR = "Hello, World!";

return 1;

以下是我导入模块的 perl 脚本的内容:

use strict;

use config_global qw(config, DEBUGVAR);
our %config;
our $DEBUGVAR;


print "variable imported with value: ".$DEBUGVAR;

输出是“使用值导入的变量:”,仅此而已。我的变量似乎正在失去它的价值。我做错了什么?

编辑:在摆弄了一下并打开警告之后,我将问题隔离为 $DEBUGVAR 从未真正导入。当我通过 $config_global:DEBUGVAR 使用它时,它按预期工作。现在的问题是它没有导入命名空间。什么给了?

【问题讨论】:

    标签: perl exporter


    【解决方案1】:

    我发现了几个问题:

    • 您不应该在qw() 语法中使用逗号。 qw 将每个空格分隔的短语放入一个数组元素中。

    这两个是一样的:

    my @bar = qw(foo bar barfu);          #No commas!
    my @bar = ("foo", "bar", "barfu");    #Commas Required
    
    • 如果要导出变量,则需要在其前面加上sigil

    你有:

    our @EXPORT_OK = qw(DEBUGVAR);
    

    应该是:

    our @EXPORT_OK = qw($DEBUGVAR);
    
    • 您应该使用较新的 Exporter 语法:

    这是更新的导出器语法:

    package global_config;
    use strict;
    use warnings;
    
    use Exporter 'import';   #Not "require". No need for "@ISA"
    
    our @EXPORT_OK = qw(DEBUGVAR);
    
    our $DEBUGVAR = "Hello, World";
    
    1;    #Makes no real difference, but you shouldn't say "return 1". Just standard.
    
    • 最后,你在做什么导出变量?这只是一个不好的做法。
      • 现在导出任何东西都受到质疑——甚至是函数。它污染了用户的命名空间。 (至少您使用的是@EXPORT_OKAY)。看看File::Spec。默认情况下,它为其子例程使用完全限定的包名称。
      • 有问题的变量可以通过完整的包名$global_config::DEBUGVAR 访问,因此没有必要导出它。
      • 如果每个人都这样做呢?是的,你最后一次听说这个借口是在幼儿园,但它适用于这里。想象一下,如果有几个模块导出了$DEBUGVAR

    有几种方法可以解决您的难题,但最好的方法是使用面向对象的 Perl 来帮助设置此变量,甚至允许用户更改它。

    package MyPackage;
    
    use strict;
    use warnings;
    use feature qw(say);
    
    sub new {
       my $class = shift;
       my $debug = shift;  #Optional Debug Value
    
       my $self = {};
       bless $self, $class;
    
       if (not defined $debug) {
          $debug = "Hello, world!";
    
       $self->Debug($debug);
       return $self;
    }
    
    sub Debug {
       my $self  = shift;
       my $debug = shift;
    
       if (defined $debug) {
          $self->{DEBUG} = $debug;
       }
       return $debug;
    }
    
    1;
    

    要使用这个模块,我只需创建一个新对象,然后会为我设置 Debug:

    use strict;
    use warnings;
    use MyPackage               #No exporting needed
    
    #Create an object w/ Debug value;
    my $obj = MyPackage->new;   #Debug is the default.
    say $obj->Debug;            #Prints "Hello, world!"
    
    # Change the value of Debug
    $obj->Debug("Foo!");
    say $obj->Debug;            #Now prints "Foo!"
    
    #Create a new object with a different default debug
    $obj2 = MyPackage->new("Bar!");
    say $obj2->Debug;           #Print "Bar!";
    

    这解决了几个问题:

    • 它允许调试多个值,因为每个对象现在都有自己的值
    • 无需担心命名空间污染或访问包变量。同样,您需要的一切都包含在对象本身中。
    • 由于复杂性隐藏在对象本身中,因此更容易调试问题。
    • 这是新的首选方法,因此您不妨习惯这种语法并能够阅读面向对象的 Perl 代码。你会越来越多地看到它。

    【讨论】:

      【解决方案2】:

      虽然从包中导出变量不一定是推荐做法,但要这样做,您需要使用要导出的变量的实际名称。在这种情况下,它是 $DEBUGVAR 而不是 DEBUGVAR,这将是子例程的名称。

      在使用 config 模块的脚本中,您不需要将 $DEBUGVAR 变量声明为 our,因为导入的变量不受严格变量的约束。

      【讨论】:

        【解决方案3】:

        你把名字弄混了,看起来像:

        use config_global ...
        
        package global_config;
        

        虽然有人会认为这会发出警告。除非你没有使用警告...?

        预计到达时间:

        our @EXPORT_OK = qw($DEBUGVAR);
                            ^  
        

        此外,您对该变量有两个声明。调试时确实需要使用警告,否则,您将一事无成。

        【讨论】:

        • 哈哈是的。哇。接得好。我刚刚修复了它,但不幸的是我仍然有同样的问题。 =/
        【解决方案4】:

        您确定要在此处使用逗号吗:

        use config_global qw(config, DEBUGVAR);
        

        另外,你没有导出配置,所以它可能会更好:

        use config_global qw(DEBUGVAR);
        

        我还会删除最后一个our $DEBUGVAR;,因为它可能会将其设置为 undef(或至少将其放在“使用”行之前)——不过我不确定这一点。

        【讨论】:

          猜你喜欢
          • 2015-09-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-06
          • 2021-12-02
          • 1970-01-01
          • 1970-01-01
          • 2020-09-22
          • 2016-04-22
          相关资源
          最近更新 更多