определение константы perl в специальном пакете - PullRequest
0 голосов
/ 05 апреля 2011

Я хотел бы установить выделенный пакет для всех общих объявлений для основной программы perl и других пакетов, не повторяя эти объявления в каждом заголовке.Я точно ошибаюсь, но не могу понять, что за этим стоит:

Предположим:
- я настроил общие данные в пакете my_common_declarations.pm .
- Я хочу использовать эти данные в другом пакете, например, my_perl_utils.pm .

#!/usr/bin/perl -w
package my_perl_utils;
use parent qw(Exporter);
our @EXPORT_OK = qw(f1 f2);
use my_common_declarations qw(debugme);
my %setup = &debugme;
my $DEBUGME = $setup{setup}{debugme};

# This generates this error : "Use of uninitialized value"
use constant true => $setup{setup}{'true'};
print "=" x25, "\nDEBUG true :\nimport = " . $setup{setup}{'true'} . "\nconstant = " , true , "\n", "=" x25, "\n"; 

sub f1{
# some rationals using the true or false constants
}

sub f2{
}

1;  

Не удается получить объявленную истинную константу без ошибок.

Должен ли я импортировать пакет общих объявлений только один раз в основную программу и соответственно объявить константу там, или переопределить ее в каждом пакете, где мне нужна эта константа?

thx

1 Ответ

6 голосов
/ 05 апреля 2011

Проблема, с которой вы сталкиваетесь, - это взаимодействие между временем выполнения и временем компиляции в вашем скрипте. Любое объявление use имеет неявный блок BEGIN {...}, что означает, что оно происходит во время компиляции. Ваше присвоение %setup происходит во время выполнения, после того, как константа была объявлена. Исправление для этого состоит в том, чтобы объявить переменную, а затем выполнить присвоение ей в блоке BEGIN. Таким образом, переменная будет определена временем use constant ...:

use my_common_declarations 'debugme';

my (%setup, $DEBUGME);  # declare variables with file scope

BEGIN {
    %setup   = debugme;                # assign to variables at compile time
    $DEBUGME = $setup{setup}{debugme};
}

use constant true => $setup{setup}{true}; # %setup is defined now

В качестве альтернативы, поскольку вы экспортируете функцию, которая возвращает хеш, почему бы ей не вернуть ссылку на хеш, тогда вы можете написать свой код как:

use my_common_declarations 'debugme';

use constant true => debugme->{setup}{true};

В этом случае, поскольку debugme импортируется первым оператором use во время компиляции, он доступен в строке use constant ....

Но поскольку вы объявляете пакет для общих объявлений, почему бы просто не переместить определение ваших констант в этот пакет, а затем добавить такие вещи, как true, в список экспорта для этого пакета?

...