Perl:如何使所需脚本中的变量在所需脚本中可用
示例
out.pl:
(my|our|local|global|whatever???) var = "test";
require("inside.pm");
inside.pm:
print $var;
我不想使用包 - 它超出了我的需求:) 谢谢!
example
out.pl:
(my|our|local|global|whatever???) var = "test";
require("inside.pm");
inside.pm:
print $var;
I don't want to use packages - it's overwhelming my needs :)
thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
即使您不使用
package
声明,您总是使用包。默认情况下,您正在包main
中工作。您使用
our
声明的所有变量都是包变量,并且应该在包范围内可用。下面是一个例子:由于
$foo
被声明为包变量,因此它将在其他程序中可用:现在我已经给了你足够的绳索,我要告诉你不要用它来吊死自己它。
这是一个非常非常糟糕的想法。请注意,
$foo
从某种几乎无法弄清楚的神秘机制中获取了一个值?包太复杂?真的吗?这并不难!看这个例子:
与之前没有太大不同,只是我添加了
package
声明,现在调用我的程序test2.pm
而不是test2.pl
。以下是我访问它的方法:
我所要做的就是使用变量中的包名称。这是一个糟糕的想法,但它比上面显示的非常非常糟糕的想法要好得多。
至少,你知道价值从何而来。它来自
test2.pm
。而且,如果您在子例程中设置该变量,则可以访问该变量。请注意,
$foo
是在子例程fooloader
中设置的。而且,这是我访问它的另一个程序:现在,您可以使用导出器导出您的子例程(甚至变量),但这不再是您看到的太多。主要是因为这是一个非常糟糕的想法。不像原来的非常糟糕的想法那么糟糕,但比上面的糟糕的想法更糟糕:
现在,我可以使用不带包名的子例程
fooloader
:当然,问题是您并不真正知道子例程
fooloader
来自哪里。如果您使用@EXPORT_OK
而不是@EXPORT
,则可以使用use test2 qw(fooloader);
并记录fooloader
函数来自。它还将帮助您了解不要在自己的程序中创建自己的 fooloader 函数并覆盖您导入的函数。然后,想知道为什么你的程序不再起作用。顺便说一句,您还可以导出变量而不仅仅是函数。然而,这变成了一个真的、真的、真的很糟糕——不是一个可怕的想法,因为它违背了你首先使用包的所有原因。如果你打算这样做,为什么还要费心去打包呢?为什么不直接拿起枪搬起石头砸自己的脚呢?
最好和首选的方法是使用面向对象的 Perl 并以完全正确的方式进行操作。一种让您确切知道发生了什么以及为什么发生的方法。而且,可以很容易地弄清楚你的代码在做什么。一种将错误降至最低的方法。
看一下完全面向对象的 Test2 类:
并使用该
Test2
类:这是最好的方法,因为即使您使用包,您也可以操纵
$test2 的值::foo
并且它将在您的整个程序中更改。想象一下,如果是$constants::pi
并且在某处将其从 3.14159 更改为 3。从那时起,使用$constants::pi
会给你错误的值。如果使用面向对象的方法,则无法更改方法 Constant->Pi 的值。它将始终是 3.14159。那么,今天我们学到了什么?
我们了解到,在 Perl 中很容易做一些非常非常糟糕的想法,但是使用包并不需要做太多的工作,所以它只会变成一个坏主意。而且,如果您开始学习一些面向对象的 Perl,实际上您无需付出太多努力,就能以完全正确的方式完成这一切。
选择权在于您。请记住,您拍摄的脚可能是您自己的。
You are always using a package, even if you don't use the
package
declaration. By default, you're working in packagemain
.All variables you declare with
our
are package variables and should be available package wide. Here's an example:Since
$foo
is declared as a package variable, it will be available in other programs:Now I've given you enough rope, I'm going to tell you not to hang yourself with it.
This is a REALLY, REALLY BAD IDEA. Notice that
$foo
gets a value from some sort of mysterious mechanism that's almost impossible to figure out?Packages are too complex? Really? It's not that hard! Look at this example:
Not much different than before except I added the
package
declaration and now call my programtest2.pm
instead oftest2.pl
.Here's how I access it:
All I had to do was use the package name in the variable. This is a BAD IDEA, but it's way better than the REALLY, REALLY BAD IDEA shown above.
At least, you know where the value came from. It came from
test2.pm
. And, you could access the variable if you set it in a subroutine.Notice that
$foo
is set in the subroutinefooloader
. And, here's my other program to access it:Now, you could use the Exporter to export your subroutines (and even variables), but that's not something you see too much anymore. Mainly because it is a REALLY BAD IDEA. Not as bad as the original REALLY REALLY BAD IDEA, but worse than the BAD IDEA above:
Now, I can use subroutine
fooloader
without the package name:The problem, of course, is that you have no real idea where the subroutine
fooloader
is coming from. If you used@EXPORT_OK
instead of@EXPORT
, you could have then useuse test2 qw(fooloader);
and document where thefooloader
function was coming from. It'll also help you to know not to create your ownfooloader
function in your own program and override the one you imported. Then, wonder why your program no longer works.By the way, you could also export variables and not just functions. However, that becomes a REALLY, REALLY, REALLY BAD -- NO TERRIBLE IDEA because it violates every reason why you use packages in the first place. If you're going to do that, why bother with packages? Why not simple take a gun and shoot yourself in the foot?
The best and preferred way is to use object oriented Perl and do it in the THOROUGHLY CORRECT WAY. A way where you know exactly what's going on and why. And, makes it easy to figure out what your code is doing. A way that keeps errors at a minimum.
Behold the thoroughly object oriented Test2 class:
And using that
Test2
class:The reason this is the best way to do it is because even if you use packages, you could manipulate the value of
$test2::foo
and it will be changed in your entire program. Imagine if this was say$constants::pi
and somewhere you changed it from 3.14159 to 3. From then on, using$constants::pi
would give you the wrong value. If you use the object oriented method, you couldn't change the value of the method Constant->Pi. It will always be 3.14159.So, what did we learn today?
We learned that it is very easy in Perl to do something that's a REALLY, REALLY BAD IDEA, but it doesn't take all that much work to use packages, so it merely becomes a BAD IDEA. And, if you start learning a bit of object oriented Perl, you can actually, without too much effort, do it all in the THOROUGHLY CORRECT WAY.
The choice is yours to make. Just remember the foot you're shooting will probably be your own.
它将与
我们的
一起使用。这是有效的,因为
our
使$var
成为全局的,并且inside.pm
正在$var
的作用域中执行定义的。不确定这是推荐的技术,但这仍然是一个有趣的问题!编辑:需要根据评论澄清(好的补丁)答案:
来自 关于 Perl 函数
我们的
的文档:因此,使用
our
,我们得到当前包(这里可能是main
)的$var
,并且我们可以在其范围内使用它。实际上,它对于您需要的文件中的代码来说是“全局”的。引入真正的全局时没有
our
,因为变量默认为全局。但我不知道有谁会推荐他们。It will work with
our
.This works because
our
makes$var
global, andinside.pm
is being executed in the scope with$var
defined. Not sure it is recommended technique, but it is an interesting question nevertheless!EDIT: Need to clarify (okay patch) the answer based on a comment:
From the documentation on the Perl function
our
:So using
our
, we get$var
with the current package (here probablymain
) and we can use it in its scope. In effect it is then "global" to the code in the file you are requiring-in.A true global is introduced without the
our
, because variables default to global. But I don't know anyone that would recommend them.