1

已解决:事实证明,我的问题根源在于我没有在@EXPORT_OK 分配和“使用 config_global qw(config DEBUGVAR);”中将 $ 放在 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

4 回答 4

1

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

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

于 2011-12-28T16:45:28.673 回答
1

我看到几个问题:

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

这两个是一样的:

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

你有:

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 代码。你会越来越多地看到它。
于 2011-12-28T19:38:57.437 回答
0

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

use config_global qw(config, DEBUGVAR);

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

use config_global qw(DEBUGVAR);

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

于 2011-12-28T16:31:00.593 回答
0

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

use config_global ...

package global_config;

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

预计到达时间:

our @EXPORT_OK = qw($DEBUGVAR);
                    ^  

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

于 2011-12-28T16:31:29.433 回答