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

发布于 2024-12-04 02:44:34 字数 1262 浏览 1 评论 0原文

我需要从未命名 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

揽月 2024-12-11 02:44:34

将脚本更改为:

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

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

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

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

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

Change your script to:

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

The problem is the $Var1 isn't in the main namespace, it's in Module'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 no Module namespace. Changing your script to:

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

...allows the script to correctly print out 1\n.

浅笑依然 2024-12-11 02:44:34

如果您必须在每个模块中导入所有我们的变量,那么您的设计就存在严重错误。我建议您重新设计程序以分离元素,以便将它们之间的串扰降至最低。这称为解耦

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.

烟沫凡尘 2024-12-11 02:44:34

您想要从模块中导出所有变量,并且您想要以一种您甚至不知道您正在导出什么的方式来执行此操作?忘记使用严格使用警告吧,因为如果你把它们放在你的程序中,它们就会尖叫着跑出去,然后蜷缩在角落里歇斯底里地哭泣。

我从来没有,我的意思是几乎从来没有,从不导出变量。我总是创建一种方法来提取所需的值。它使我能够对向外界公开的内容进行至关重要的控制,并保持用户命名空间的纯净。

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

  1. 您不知道模块中正在导出什么。使用该模块的程序如何知道要使用什么?在某个地方,您必须记录变量 $foo@bar 可供使用。如果你必须这样做,为什么不简单地谨慎行事呢?
  2. 您遇到了有人更改模块的问题,突然一个新变量被导出到使用该模块的程序中。想象一下该变量是否已被使用。程序突然有一个bug,你永远也搞不出来。
  3. 您正在模块中导出一个变量,开发人员决定修改该变量,甚至将其从程序中删除。同样,因为您不知道正在导入或导出什么,所以无法知道为什么程序中突然出现错误。

正如我所提到的,您必须知道程序可以使用的模块中正在使用的内容,因此无论如何您都必须记录下来。如果您坚持导入变量,至少使用 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 and use 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.

  1. You have no idea what is being exported in your module. How is the program that uses that module going to know what to use? Somewhere, you have to document that the variable $foo and @bar are available for use. If you have to do that, why not simply play it safe?
  2. You have the issue of someone changing the module, and suddenly a new variable is being exported into the program using that module. Imagine if that variable was already in use. The program suddenly has a bug, and you'll never be able to figure it out.
  3. You are exporting a variable in your module, and the developer decides to modify that variable, or even removes it from the program. Again, because you have no idea what is being imported or exported, there's no way of knowing why a bug suddenly appeared in the program.

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 of use and forget about using the package statement.

迷雾森÷林ヴ 2024-12-11 02:44:34

听起来您的文件中有数据并且正在尝试将该数据加载到您的程序中。

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

但是,任何时候如果您正在使用数字名称更改来创建许多变量,那么您可能应该使用数组。

将您的模块更改为类似以下内容:

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

然后按索引访问项目:

$My::Module::Data[1]

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 a package xyz; line, then the fully qualified name is $xzy::Var1. If there is no package declaration, then the default package main 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:

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

and then access the items by index:

$My::Module::Data[1]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文