импортированные переменные perl импорт без значения - PullRequest
1 голос
/ 28 декабря 2011

решено: Как оказалось, моя проблема коренится в том, что я не поставил $ перед DEBUGVAR в назначении @EXPORT_OK и "use config_global" qw (config DEBUGVAR); " линия. Поскольку это не вызывает никаких ошибок, я не мог знать, что это была проблема. Итак, исправление заключается в том, чтобы поместить правильный синтаксис перед вашими переменными в этих точках.

Итак, я пытаюсь научиться писать и импортировать модули Perl. Я не знаю, почему это было так сложно сделать, но у меня много проблем с этой, казалось бы, тривиальной задачей. Вот содержимое моего модуля:

package global_config;
use strict;

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(DEBUGVAR);

our ($DEBUGVAR);

our $DEBUGVAR = "Hello, World!";

return 1;

Вот содержимое моего perl-скрипта, который импортирует модуль:

use strict;

use config_global qw(config, DEBUGVAR);
our %config;
our $DEBUGVAR;


print "variable imported with value: ".$DEBUGVAR;

Вывод: «переменная импортирована со значением:» и ничего больше. Кажется, моя переменная теряет свое значение. Что я делаю не так?

РЕДАКТИРОВАТЬ : Немного покопавшись и включив предупреждения, я выделил проблему в том, что $ DEBUGVAR фактически никогда не импортируется. Когда я использую его через $ config_global: DEBUGVAR, он работает как положено. Проблема в том, что он не импортируется в пространство имен. Что дает?

Ответы [ 4 ]

1 голос
/ 28 декабря 2011

Я вижу несколько вопросов:

  • Вы не должны использовать запятую в синтаксисе qw(). qw берет каждую фразу, разделенную пробелами, и помещает ее в элемент массива.

Эти два одинаковы:

my @bar = qw(foo bar barfu);          #No commas!
my @bar = ("foo", "bar", "barfu");    #Commas Required
  • Если вы экспортируете переменную, вам нужно поставить сигил перед ней.

У вас есть:

our @EXPORT_OK = qw(DEBUGVAR);

Должно быть:

our @EXPORT_OK = qw($DEBUGVAR);
  • Вы должны использовать более новый синтаксис Exporter:

Вот новый синтаксис Exporter:

package global_config;
use strict;
use warnings;

use Exporter 'import';   #Not "require". No need for "@ISA"

our @EXPORT_OK = qw(DEBUGVAR);

our $DEBUGVAR = "Hello, World";

1;    #Makes no real difference, but you shouldn't say "return 1". Just standard.
  • Наконец, что вы делаете, экспортируя переменные? Это просто плохая практика.
    • Экспорт чего-либо теперь ставится под сомнение - даже функции. Это загрязняет пространство имен пользователя. (По крайней мере, вы используете @EXPORT_OKAY). Посмотрите на File :: Spec . По умолчанию он использует полные имена пакетов для своих подпрограмм.
    • Переменная, о которой идет речь, доступна через полное имя пакета $global_config::DEBUGVAR, поэтому ее не нужно экспортировать.
    • Что, если все это сделали? Да, вы в последний раз слышали об этом оправдании в детском саду, но это применимо здесь. Представьте, если экспортировано несколько модулей $DEBUGVAR.

Есть несколько способов обойти это затруднительное положение, но лучше всего использовать объектно-ориентированный Perl, чтобы помочь установить эту переменную и даже позволить пользователям изменять ее.

package MyPackage;

use strict;
use warnings;
use feature qw(say);

sub new {
   my $class = shift;
   my $debug = shift;  #Optional Debug Value

   my $self = {};
   bless $self, $class;

   if (not defined $debug) {
      $debug = "Hello, world!";

   $self->Debug($debug);
   return $self;
}

sub Debug {
   my $self  = shift;
   my $debug = shift;

   if (defined $debug) {
      $self->{DEBUG} = $debug;
   }
   return $debug;
}

1;

Чтобы использовать этот модуль, я просто создаю новый объект, и для меня будет установлена ​​Debug:

use strict;
use warnings;
use MyPackage               #No exporting needed

#Create an object w/ Debug value;
my $obj = MyPackage->new;   #Debug is the default.
say $obj->Debug;            #Prints "Hello, world!"

# Change the value of Debug
$obj->Debug("Foo!");
say $obj->Debug;            #Now prints "Foo!"

#Create a new object with a different default debug
$obj2 = MyPackage->new("Bar!");
say $obj2->Debug;           #Print "Bar!";

Это решает несколько проблем:

  • Он допускает несколько значений отладки, поскольку каждый объект теперь имеет свои собственные значения
  • Нет проблем с загрязнением пространства имен или доступом к переменным пакета. Опять же, все, что вам нужно, содержится в самом объекте.
  • Отладка проблем проще, поскольку сложность скрыта внутри самих объектов.
  • Это новый предпочтительный метод, так что вы можете также использовать синтаксис и иметь возможность читать объектно-ориентированный код Perl. Вы будете видеть это все больше и больше.
1 голос
/ 28 декабря 2011

Хотя экспорт переменных из пакета не обязательно рекомендуется, для этого вам необходимо использовать фактическое имя экспортируемой переменной.В этом случае это $DEBUGVAR, а не DEBUGVAR, которое будет именем подпрограммы.

В сценарии, использующем модуль конфигурации, вам не нужно объявлять переменную $DEBUGVAR как our, поскольку импортируемые переменные освобождены от строгих переменных.

0 голосов
/ 28 декабря 2011

Вы перепутали имя, оно выглядит так:

use config_global ...

package global_config;

Хотя можно подумать, что это выдаст предупреждения.Если вы не используете предупреждения ...?

ETA:

our @EXPORT_OK = qw($DEBUGVAR);
                    ^  

Кроме того, у вас есть два объявления для этой переменной.Вы действительно должны использовать предупреждения при отладке, иначе вы никогда не получите ничего.

0 голосов
/ 28 декабря 2011

Вы уверены, что хотите запятую здесь:

use config_global qw(config, DEBUGVAR);

Кроме того, вы не экспортируете конфигурацию, поэтому она может работать лучше:

use config_global qw(DEBUGVAR);

Я бы также удалил последний our $DEBUGVAR;, поскольку он мог бы установить его на undef (или, по крайней мере, поставить его перед строкой "use") - хотя я не уверен в этом.

...