Как вы узнали, когда вы используете my
, вы создаете локальную переменную non-package .Чтобы создать переменную пакета, вы используете our
, а не my
:
my $foo = "this is a locally scoped, non-package variable";
our $bar = "This is a package variable that's visible in the entire package";
Еще лучше:
{
my $foo = "This variable is only available in this block";
our $bar = "This variable is available in the whole package":
}
print "$foo\n"; #Whoops! Undefined variable
print "$bar\n"; #Bar is still defined even out of the block
Когда вы не включаете use strict
в вашу программувсе определенные переменные являются переменными пакета.Вот почему, когда вы не помещаете это, оно работает так, как вы думаете, и помещает это в разрывает вашу программу.
Однако, как вы можете видеть в следующем примере, используяour
решит вашу дилемму:
Файл Local/Foo.pm
#! /usr/local/bin perl
package Local::Foo;
use strict;
use warnings;
use feature qw(say);
use Exporter 'import';
our @EXPORT = qw(testme);
our $bar = "This is the package's bar value!";
sub testme {
# $foo is a locally scoped, non-package variable. It's undefined and an error
say qq(The value of \$main::foo is "$main::foo");
# $bar is defined in package main::, and will print out
say qq(The value of \$main::bar is "$main::bar");
# These both refer to $Local::Foo::bar
say qq(The value of \$Local::Foo::bar is "$Local::Foo::bar");
say qq(The value of bar is "$bar");
}
1;
Файл test.pl
#! /usr/local/bin perl
use strict;
use warnings;
use feature qw(say);
use Local::Foo;
my $foo = "This is foo";
our $bar = "This is bar";
testme;
say "";
$Local::Foo::bar = "This is the NEW value for the package's bar";
testme
И вывод:
Use of uninitialized value $foo in concatenation (.) or string at Local/Foo.pm line 14.
The value of $main::foo is ""
The value of $main::bar is "This is bar"
The value of $Local::Foo::bar is "This is the package's bar value!"
The value of bar is "This is the package's bar value!"
Use of uninitialized value $foo in concatenation (.) or string at Local/Foo.pm line 14.
The value of $main::foo is ""
The value of $main::bar is "This is bar"
The value of $Local::Foo::bar is "This is the NEW value for the package's bar"
The value of bar is "This is the NEW value for the package's bar"
Сообщение об ошибке, которое вы получаете, является результатом того, что $foo
является локальной переменной и, следовательно, не виден внутри пакета.Между тем, $bar
является переменной пакета и является видимой.
Иногда это может быть немного сложно:
if ($bar -eq "one") {
my $foo = 1;
}
else {
my $foo = 2;
}
print "Foo = $foo\n";
Это не работает, потому что $foo
только основывает значениевнутри блока if
.Вы должны сделать это:
my $foo;
if ($bar -eq "one") {
$foo = 1;
}
else {
$foo = 2;
}
print "Foo = $foo\n"; #This works!
Да, сначала может быть немного обернуто вокруг него, но использование use strict;
и use warnings;
в настоящее время не совсем правильно и по уважительным причинам.,Использование use strict;
и use warnings;
, вероятно, устранило 90% ошибок, которые люди делают в Perl.Вы не можете ошибиться, установив значение $foo
в одной части программы и попытавшись использовать $Foo
в другой.Это одна из вещей, которые мне действительно не хватает в Python.