导入的perl变量导入没有任何值

时间:2011-12-28 16:24:11

标签: perl exporter

已解决:事实证明,我的问题源于这样一个事实:我在@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使用它时,它按预期工作。现在的问题是它没有导入命名空间。是什么给了什么?

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分: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语法:

这是较新的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 :(得分:0)

您确定要在此处输入逗号:

use config_global qw(config, DEBUGVAR);

此外,您没有导出配置,因此它可能更好地工作:

use config_global qw(DEBUGVAR);

我还会移除最后一个our $DEBUGVAR;,因为它可能会将其设置为undef(或者至少将它放在“use”行之前) - 虽然我不确定。

答案 3 :(得分:0)

你的名字已经混淆了,它看起来像是:

use config_global ...

package global_config;

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

ETA:

our @EXPORT_OK = qw($DEBUGVAR);
                    ^  

此外,您对该变量有两个声明。你真的需要在调试时使用警告,否则,你将永远无法到达任何地方。