如何从未命名的Perl模块导入所有“我们的”变量而不列出它们?

时间:2011-09-12 17:00:35

标签: perl import module global-variables

我需要从未命名的 Perl模块(Module.pm)导入所有我们的变量,并在Perl脚本(Script.pl)中使用它们。

以下代码在没有“use strict”的情况下运行良好,但失败了。如何更改此代码以使用“use strict”,而无需手动列出所有导入的变量(如other question的答案中所述)?

非常感谢你的帮助!

Script.pl:

use strict;
require Module;
print $Var1;

Module.pm:

our $Var1 = "1\n";
...
our $VarN = "N\n";
return 1;

运行脚本:

$> perl Script.pl

错误:

Global symbol "$Var1" requires explicit package name at Script.pl line 3.
Execution of Script.pl aborted due to compilation errors.

注意(1):模块未命名,因此不能使用Module::前缀。

注意(2)Module.pm还包含一组由全局变量配置的函数。

注意(3):变量不同,不应存储在一个数组中。

注意(4):设计不好,但问题不在于设计。这是强制列出的代码使用复杂性O(1)进行最少的修改,即几行代码不依赖于N

解决方案候选人(已接受):在所有导入的变量之前添加$::。它符合strict,并且允许在代码中将my变量与imported区别开来。

4 个答案:

答案 0 :(得分:7)

将您的脚本更改为:

use strict;
require Module;
print $Module::Var1;

问题是$Var1不在主命名空间中,而是在Module的命名空间中。

修改:正如下面的评论所指出的那样,您尚未命名模块(即顶部没有说出package Module;)。因此,没有Module命名空间。将脚本更改为:

use strict;
require Module;
print $main::Var1;

...允许脚本正确打印出1\n

答案 1 :(得分:4)

如果您必须在每个模块中导入所有我们的变量,那么您的设计就会出现严重问题。我建议您重新设计程序以分离元素,以便它们之间存在最少的串扰。这称为decoupling

答案 2 :(得分:2)

您想要从模块中导出所有变量,并且您希望以甚至不知道您要导出的内容的方式进行导出吗?忘记use strictuse warnings,因为如果你把它们放在你的程序中,它们就会尖叫出来,然后蜷缩在歇斯底里地哭泣的角落里。

我从来没有,而且我并不意味着,永远不会导出变量。我总是创建一个方法来提取所需的值。它使我能够对我暴露于外部世界的内容进行重要控制,并使用户的名称空间保持纯粹。

让我们看看你的想法可能存在的问题。

  1. 您不知道模块中的导出内容。使用该模块的程序如何知道要使用什么?在某处,您必须记录变量$foo@bar可供使用。如果你必须这样做,为什么不简单地安全地玩呢?
  2. 您遇到有人更改模块的问题,并且突然使用该模块将新变量导出到程序中。想象一下,如果该变量已被使用。该程序突然出现了一个错误,你永远无法搞清楚。
  3. 您正在模块中导出变量,开发人员决定修改该变量,甚至将其从程序中删除。同样,因为你不知道导入或导出的是什么,所以无法知道为什么程序中突然出现了一个错误。
  4. 正如我所提到的,你 来了解程序可以使用的模块中正在使用的内容,因此无论如何都必须记录它。如果您要坚持导入变量,至少使用EXPORT_OK数组和Exporter模块。这将有助于限制损害。这样,您的程序可以声明它所依赖的变量,并且您的模块可以声明它知道程序可能使用的变量。如果我正在修改模块,我会特别注意我看到的导出的任何变量。并且,如果您必须在程序中指定要导入的变量,那么您应该对这些特定变量保持谨慎。

    否则,为什么要打扰模块呢?为什么不回到Perl 3.0并使用require而不是use而忘记使用package语句。

答案 3 :(得分:1)

听起来你在文件中有数据,并且正在尝试将这些数据加载到你的程序中。

就像现在一样,模块中的our声明只声明该文件范围的变量。文件快速运行后,要访问变量,您需要使用其完全限定名称。如果您的模块有package xyz;行,则完全限定名称为$xzy::Var1。如果没有package声明,则使用默认包main,为您的变量命名$main::Var1

但是,每当你使用数字名称更改制作许多变量时,你可能应该使用数组。

将模块更改为:

@My::Module::Data = ("1\n", "2\n" ... )

然后按索引访问项目:

$My::Module::Data[1]