我需要从未命名的 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
区别开来。
答案 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 strict
和use warnings
,因为如果你把它们放在你的程序中,它们就会尖叫出来,然后蜷缩在歇斯底里地哭泣的角落里。
我从来没有,而且我并不意味着,永远不会导出变量。我总是创建一个方法来提取所需的值。它使我能够对我暴露于外部世界的内容进行重要控制,并使用户的名称空间保持纯粹。
让我们看看你的想法可能存在的问题。
$foo
和@bar
可供使用。如果你必须这样做,为什么不简单地安全地玩呢?正如我所提到的,你 有 来了解程序可以使用的模块中正在使用的内容,因此无论如何都必须记录它。如果您要坚持导入变量,至少使用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]