如何从未命名的 Perl 模块导入所有“我们的”变量而不列出它们?
我需要从未命名 Perl 模块 (Module.pm) 导入所有我们的变量,并在 Perl 脚本 (Script.pl) 中使用它们。
以下代码在没有“use strict”的情况下运行良好,但在使用时失败了。如何更改此代码以与 "use strict" 一起使用,而无需手动列出所有导入的变量(如 其他问题)?
非常感谢您的帮助!
Script.pl:Module.pm
use strict;
require Module;
print $Var1;
:
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
区分开来。
I need to import all our variables from the unnamed Perl module (Module.pm) and use them inside the Perl script (Script.pl).
The following code works well without the "use strict", but failed with it. How can I change this code to work with "use strict" without the manual listing of all imported variables (as described in the answer to other question)?
Thanks a lot for your help!
Script.pl:
use strict;
require Module;
print $Var1;
Module.pm:
our $Var1 = "1\n";
...
our $VarN = "N\n";
return 1;
Run the script:
gt; perl Script.pl
Errors:
Global symbol "$Var1" requires explicit package name at Script.pl line 3.
Execution of Script.pl aborted due to compilation errors.
NOTE (1): The module is unnamed, so using a Module::
prefix is not the option.
NOTE (2): Module.pm
contains also a set of functions configured by global variables.
NOTE (3): Variables are different and should NOT be stored in one array.
NOTE (4): Design is NOT good, but the question is not about the design. It's about forcing of the listed code to work with minimal modifications with the complexity O(1)
, i.e. a few lines of code that don't depend on the N
.
Solution Candidate (ACCEPTED): Add $::
before all imported variables. It's compliant with strict
and also allows to differ my
variables from imported
in the code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
将脚本更改为:
问题是
$Var1
不在主命名空间中,而是在Module
的命名空间中。编辑:正如下面的评论所指出的,您还没有命名您的模块(即顶部没有说
package Module;
)。因此,没有Module
命名空间。将脚本更改为:...允许脚本正确打印出
1\n
。Change your script to:
The problem is the
$Var1
isn't in the main namespace, it's inModule
's namespace.Edit: As is pointed out in comments below, you haven't named your module (i.e. it doesn't say
package Module;
at the top). Because of this, there is noModule
namespace. Changing your script to:...allows the script to correctly print out
1\n
.如果您必须在每个模块中导入所有我们的变量,那么您的设计就存在严重错误。我建议您重新设计程序以分离元素,以便将它们之间的串扰降至最低。这称为解耦。
If you have to import all the our variables in every module, there's something seriously wrong with your design. I suggest that you redesign your program to separate the elements so there is a minimum of cross-talk between them. This is called decoupling.
您想要从模块中导出所有变量,并且您想要以一种您甚至不知道您正在导出什么的方式来执行此操作?忘记
使用严格
和使用警告
吧,因为如果你把它们放在你的程序中,它们就会尖叫着跑出去,然后蜷缩在角落里歇斯底里地哭泣。我从来没有,我的意思是几乎从来没有,从不导出变量。我总是创建一种方法来提取所需的值。它使我能够对向外界公开的内容进行至关重要的控制,并保持用户命名空间的纯净。
让我们看看您的想法可能存在的问题。
$foo
和@bar
可供使用。如果你必须这样做,为什么不简单地谨慎行事呢?正如我所提到的,您必须知道程序可以使用的模块中正在使用的内容,因此无论如何您都必须记录下来。如果您坚持导入变量,至少使用
EXPORT_OK
数组和 Exporter 模块。这将有助于限制损害。这样,您的程序可以声明它所依赖的变量,并且您的模块可以声明它知道程序可能使用的变量。如果我正在修改模块,我会特别小心我看到的正在导出的任何变量。而且,如果您必须在程序中指定要导入的变量,您就知道要对这些特定变量保持谨慎。否则,为什么还要麻烦模块呢?为什么不简单地回到 Perl 3.0 并使用
require
而不是use
并忘记使用package
语句。You want to export all variables from a module, and you want to do it in such a way that you don't even know what you're exporting? Forget about
use strict
anduse warnings
because if you put them in your program, they'll just run screaming out, and curl up in a corner weeping hysterically.I never, and I don't mean hardly ever, never export variables. I always create a method to pull out the required value. It gives me vital control over what I'm exposing to the outside world and it keeps the user's namespace pure.
Let's look at the possible problems with your idea.
$foo
and@bar
are available for use. If you have to do that, why not simply play it safe?As I mentioned, you have to know somewhere what is being used in your module that the program can use, so you have to document it anyway. If you're going to insist on importing variables, at least use the
EXPORT_OK
array and the Exporter module. That will help limit the damage. This way, your program can declare what variables its depending upon and your module can declare what variables it knows programs might be using. If I am modifying the module, I would be extra careful of any variable I see I am exporting. And, if you must specify in your program what variables you're importing, you know to be cautious about those particular variables.Otherwise, why bother with modules? Why not simply go back to Perl 3.0 and use
require
instead ofuse
and forget about using thepackage
statement.听起来您的文件中有数据并且正在尝试将该数据加载到您的程序中。
现在,模块中的
our
声明仅声明该文件范围的变量。文件运行完成后,要访问变量,您需要使用它们的完全限定名称。如果您的模块有package xyz;
行,则完全限定名称为$xzy::Var1
。如果没有package
声明,则使用默认包main
,将变量命名为$main::Var1
但是,任何时候如果您正在使用数字名称更改来创建许多变量,那么您可能应该使用数组。
将您的模块更改为类似以下内容:
然后按索引访问项目:
It sounds like you have data in a file and are trying to load that data into your program.
As it is now, the
our
declarations in the module only declare variables for the scope of that file. Once the file finshes running, to access the variables, you need to use their fully qualified name. If your module has apackage xyz;
line, then the fully qualified name is$xzy::Var1
. If there is nopackage
declaration, then the default packagemain
is used, giving your variables the name$main::Var1
However, any time that you are making many variables all with numeric name changes, you probably should be using an array.
Change your module to something like:
and then access the items by index: