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 - без этого это можно сделать с помощью требования. Это не работает с 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 неофициально резервирует имена модулей в нижнем регистре для «прагматических» модулей, таких как 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. Однако ни один из них не использует экспортер qw(import); ни использовать Экспортер; наш @ISA = qw/Exporter/; устраняет необходимость использования префикса os_specific:: при каждом использовании. Нет ли способа заставить экспортер поместить имя в пространство имен вызывающего абонента? - person mathog; 29.05.2014
comment
@user3681409 user3681409 Вы должны следовать ВСЕМ инструкциям в моем сообщении. Вам также необходимо исправить регистр имени пакета: package OS_Specific;. Если бы вы это сделали, то использование "$os_specific:os_name" не сработало бы. Корпус имеет значение. - person Miller; 30.05.2014