perl декларира и експортира променливи от модул

Трябва да модифицирам куп скриптове, за да правя еквивалента на включване на прав C стил на умерен брой променливи. След като ги изтеглите, трябва да действа точно така, сякаш е включен ред като този:

my $os_name = "Windows"; #declares the variable AND sets its value

Така че те могат да бъдат използвани в извикващия скрипт. Има малко логика в модула, който условно задава стойностите на тези променливи. Всички скриптове имат строго използване. Типичният обаждащ се има:

use strict;
use File::Basename;
use lib dirname (__FILE__);
use os_specific;
print "DEBUG os_name $os_name\n";

и модулът (os_specific.pm) има:

package os_specific;
use warnings;
use strict;
use Exporter;
our @EXPORT = qw($os_name);
our $os_name="Windows";
1

Но не работи, има предупреждения на етапа на компилиране като:

Global symbol "$os_name" requires explicit package name at caller.pl.

Така че декларацията на променливата в модула не е ефективна в обхвата на повикващия.

Може ли това да се направи или всяка от тези променливи също трябва да бъде декларирана в caller.pl? (Всички отговори, моля, използвайте use strict - без това може да се направи с помощта на require. Това обаче не работи с use strict, защото извежда грешка по време на компилиране.)

Знам, че променливите от модула могат да се използват като $os_specific::os_name, въпросът е как да настроя това, така че да могат да се използват само като $os_name.

Благодаря.


person mathog    schedule 27.05.2014    source източник
comment
os_specific и OS_SPECIFIC не са еднакви случаи.   -  person choroba    schedule 28.05.2014
comment
... освен ако не сте на Windows.   -  person mob    schedule 28.05.2014
comment
Perl вече има $^O: вижте perl -E "say $^O"   -  person dolmen    schedule 28.05.2014


Отговори (2)


Проблемът е, че не наследявате никаква функционалност от Exporter, защото не сте задали променливата на пакета @ISA.

Вашият модул трябва да изглежда така след коригиране на името на пакета (пакетите трябва да използват само главни и малки букви по конвенция) и трябва да бъде във файла OSSpecific.pm

package OSSpecific;

use strict;
use warnings;

use Exporter;
our @ISA    = qw/ Exporter /;
our @EXPORT = qw/ $os_name /;

our $os_name = "Windows";

1;
person Borodin    schedule 27.05.2014

Имате нужда от изричен import метод във вашия пакет, както е показано в Exporter.

Трябва също така да коригирате малкия регистър на името на пакета, името на файла и израза за използване, така че всички да съвпадат.

OS_Specific.pm:

package OS_Specific;
use warnings;
use strict;
use Exporter qw(import);

И другият файл:

use OS_Specific;

Разгледайте perlstyle за полезни указания относно избора на имена на пакети:

Perl неофициално запазва имена на модули с малки букви за "pragma" модули като integer и strict. Други модули трябва да започват с главна буква и да използват смесен регистър, но вероятно без долни черти поради ограниченията в представянето на имената на модулите от примитивните файлови системи като файлове, които трябва да се поберат в няколко редки байта.

person Miller    schedule 27.05.2014
comment
Когато добавих qw(import) след употреба Exporter, повикващият все още няма достъп до $os_name, само до $os_specific::os_name. Първата форма предизвиква грешка по време на компилиране „$os_name изисква изрично име на пакет“. - person mathog; 28.05.2014
comment
Името на вашия пакет, името на вашия файл и вашето изявление за употреба трябва да използват един и същ регистър. - person Miller; 28.05.2014
comment
Не е ли така, че само името на pm файла и инструкциите за използване трябва да съвпадат? Името на пакета в този случай дефинира само префикса за $os_specific::os_name. - person mathog; 28.05.2014
comment
Всъщност на Windows можете да се разминете само със съвпадението на use и package и файлът да е с различен регистър. Но недей така! Направете нещата съвпадащи. - person Miller; 28.05.2014
comment
Моля, позволете ми да повторя. Използвайки експортер, няма проблем да зададете $os_name в модула и да го използвате като $os_specific:os_name в perl скрипт, който е използвал OS_Specific. Въпреки това, нито използвайте Exporter qw(import); нито използвайте Exporter; нашият @ISA = qw/ Износител /; елиминира изискването за os_specific:: префикс при всяка употреба. Няма ли някакъв начин да накарате износителя да постави името в пространството на имената на повикващия? - person mathog; 29.05.2014
comment
@user3681409 Трябва да следвате ВСИЧКИ инструкциите в публикацията ми. Трябва също така да коригирате регистъра на името на пакета: package OS_Specific;. Ако бяхте направили това, използването на "$os_specific:os_name" нямаше да работи. Корпусът има значение. - person Miller; 30.05.2014