开发者

How to import all "our"-variables from the unnamed Perl module without listing them?

开发者 https://www.devze.com 2023-04-04 03:06 出处:网络
I need to import all our variables from the unnamed Perl module (Module.pm) and use them inside the Perl script (Script.pl).

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:

$> 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 diffe开发者_如何学运维rent 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.


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.


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.


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.


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]
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号