ago*_*dis 3 variables perl scope require required
例
out.pl:
(my|our|local|global|whatever???) var = "test";
require("inside.pm");
Run Code Online (Sandbox Code Playgroud)
inside.pm:
print $var;
Run Code Online (Sandbox Code Playgroud)
我不想使用包 - 它压倒了我的需求:)谢谢!
您总是用一个包,即使你不使用的package声明.默认情况下,您正在使用包main.
您声明的所有变量our都是包变量,并且应该在包范围内可用.这是一个例子:
#! /usr/bin/env perl
# test2.pl
use strict;
use warnings;
our $foo = "bar";
1;
Run Code Online (Sandbox Code Playgroud)
由于$foo声明为包变量,因此它将在其他程序中可用:
#! /usr/bin/env perl
use strict;
use warnings;
require "test2.pl";
our $foo;
print "The value of \$foo is $foo\n";
Run Code Online (Sandbox Code Playgroud)
现在我给了你足够的绳子,我要告诉你不要把它挂起来.
这真是一个非常糟糕的想法.请注意,$foo从某种几乎无法弄清楚的神秘机制中获取值?
套餐太复杂了?真?这并不难!看看这个例子:
#! /usr/bin/env perl
# test2.pm
package test2;
use strict;
use warnings;
our $foo = "bar";
1;
Run Code Online (Sandbox Code Playgroud)
与之前没什么不同,除了我添加了package声明,现在调用我的程序test2.pm而不是test2.pl.
这是我访问它的方式:
#! /usr/bin/env perl
use strict;
use warnings;
use test2;
print "The value of \$foo from package test2 is $test2::foo\n";
Run Code Online (Sandbox Code Playgroud)
我所要做的就是在变量中使用包名.这是一个不好的想法,但它比上面显示的真正,糟糕的想法更好.
至少,你知道价值来自哪里.它来自test2.pm.并且,如果在子例程中设置变量,则可以访问该变量.
#! /usr/bin/env perl
# test2.pm
package test2;
use strict;
use warnings;
sub fooloader {
our $foo = "bar";
}
1;
Run Code Online (Sandbox Code Playgroud)
请注意,$foo在子例程中设置fooloader.而且,这是我的另一个访问它的程序:
#! /usr/bin/env perl
use strict;
use warnings;
use test2;
&test2::fooloader();
print "The value of \$foo from package test2 is $test2::foo\n";
Run Code Online (Sandbox Code Playgroud)
现在,你可以使用Exporter来导出子程序(甚至变量),但这不是你看得太多了.主要是因为它是一个真正糟糕的想法.没有原来真正糟糕的想法那么糟糕,但比上面的BAD IDEA更糟糕:
#! /usr/bin/env perl
# test2.pm
package test2;
use base qw(Exporter);
our @EXPORT = qw(fooloader);
use strict;
use warnings;
sub fooloader {
our $foo = "bar";
}
1;
Run Code Online (Sandbox Code Playgroud)
现在,我可以使用fooloader不带包名的子程序:
#! /usr/bin/env perl
use strict;
use warnings;
use test2;
fooloader();
print "The value of \$foo from package test2 is $test2::foo\n";
Run Code Online (Sandbox Code Playgroud)
当然,问题在于你不知道子程序fooloader的来源.如果您使用@EXPORT_OK而不是@EXPORT,那么您可以使用use test2 qw(fooloader);并记录fooloader函数的来源.它还可以帮助您了解不要fooloader在自己的程序中创建自己的功能并覆盖您导入的功能.然后,想知道为什么你的程序不再有效.
顺便说一下,您还可以导出变量而不仅仅是函数.然而,这成为一个真正的,真的,真的很糟糕 - 没有可怕的想法,因为它违反了你首先使用包裹的所有原因.如果你打算这样做,为什么要打扰包裹呢?为什么不简单地拿枪并用脚射击自己?
最好和首选的方法是使用面向对象的Perl并以完全正确的方式进行.一种让您确切了解正在发生的事情以及原因的方法.并且,可以很容易地弄清楚您的代码在做什么.一种将错误保持在最低限度的方法.
看看彻底面向对象的Test2类:
#! /usr/bin/env perl
# Test2.pm
package Test2;
sub new {
my $class = shift;
my $self = {};
bless $self, $class;
return $self;
}
sub FooValue {
return "bar";
}
1;
Run Code Online (Sandbox Code Playgroud)
并使用Test2该类:
#! /usr/bin/env perl
use strict;
use warnings;
use Test2;
my $tester = Test2->new;
print "The value of foo from package test2 is " . $tester->FooValue . "\n";
Run Code Online (Sandbox Code Playgroud)
这是最好的方法,因为即使您使用包,您也可以操纵它的值,$test2::foo它将在整个程序中更改.想象一下,如果这是说$constants::pi,在某处您将其从3.14159更改为3.从那时起,使用$constants::pi会给你错误的值.如果使用面向对象的方法,则无法更改方法Constant-> Pi的值.它总是3.14159.
那么,我们今天学到了什么?
我们了解到Perl很容易做一些真正令人难以置信的事情,但是使用软件包并不需要太多工作,所以它只是一个不好的想法.而且,如果你开始学习一些面向对象的Perl,你实际上可以毫不费力地以完全正确的方式完成所有工作.
你可以选择.只记得你拍摄的脚可能是你自己的.
它将与our.
$ cat out.pl
our $var = "test";
require("inside.pm");
$ cat inside.pm
print "Testing...\n";
print "$var\n";
$ perl out.pl
Testing...
test
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为our它是$var全局的,并且inside.pm正在定义的范围内执行$var。不确定这是推荐的技术,但这仍然是一个有趣的问题!
编辑:需要根据评论澄清(好的补丁)答案:
our将一个简单名称与当前包中的包(读取:全局)变量关联起来,以便在当前词法范围内使用。换句话说,与或our具有相同的作用域规则,但不一定创建变量。mystate
因此,使用our,我们得到$var当前的包(这里可能是main),并且我们可以在其范围内使用它。实际上,它对于您需要的文件中的代码来说是“全局”的。
真正的全局变量是在没有 的情况下引入的our,因为变量默认为全局变量。但我不知道有谁会推荐他们。
| 归档时间: |
|
| 查看次数: |
5349 次 |
| 最近记录: |