Perl: значение переменной 'glob', но должно быть 'scalar' - PullRequest
2 голосов
/ 28 февраля 2020

У меня есть следующий простой код:

my $TimeZone = $hCache->{'TimeZone'}; # Cache gets filled earlier
my $DateTime = DateTime->now();
$DateTime->set_time_zone($TimeZone);

Этот код запускается на сервере приложений, который в основном представляет собой длительный процесс perl, который принимает входящие сетевые подключения.

От время от времени этот сервер приложений становится «грязным», и приведенный выше код выводит следующую ошибку:

Параметр 'name' ("Europe / Berlin") для DateTime :: TimeZone :: new был 'glob', который не является одним из разрешенных типов: скаляр в /srv/epages/eproot/Perl/lib/site_perl/linux/DateTime.pm строка 1960.

Когда я пытаюсь для отладки переменной "$ TimeZone" я не получаю никаких дополнительных подробностей.

Например,

print ref($TimeZone); # prints nothing (scalar?)
print $TimeZone; # prints "Europe/Berlin"

Код работает, если я снова заставляю часовой пояс быть строкой, вот так :

my $TimeZone = $hCache->{'TimeZone'}; # Cache gets filled earlier
my $DateTime = DateTime->now();
$DateTime->set_time_zone($TimeZone."");

Мои вопросы:

  1. Если 'glob' не является ссылкой, как я могу правильно отладить переменную?
  2. Как создать переменная 'glob'? Какой синтаксис к нему? Я совершенно уверен, что в моей огромной кодовой базе есть некоторые случайности, но я не знаю, что искать.
  3. Есть ли способ «контролировать» переменную? По сути, получение трассировки стека при изменении переменной

1 Ответ

5 голосов
/ 28 февраля 2020

Как создать переменную 'glob'?

Глоб, сокращение от «typeglob» - это структура (в смысле слова C), которая содержит поле для каждого типа переменной, которое можно найти в таблице символов (скаляр, массив, ha sh, код, glob, et c). Они образуют таблицу символов.

Глобусы создаются простым упоминанием переменной пакета.

@a = 4..6;      # Creates glob *main::a containing a reference to the new array.

Поскольку глобусы сами являются переменными пакетов, вы можете создать глобус, просто упомянув его.

my $x = *glob;  # The glob *main::glob is created by this line at compile-time.

Обратите внимание, что файловые дескрипторы часто доступны через глобусы. Например, open(my $fh, '<', ...) заполняет $fh ссылкой на глоб, который содержит ссылку на IO.

$fh        # Reference to glob that contains a reference to an IO.
*$fh       # Glob that contains a reference to an IO.
*$fh{IO}   # Reference to an IO.

Если «глоб» не является ссылкой, как я могу отладить переменная правильно?

ref(\$var) вернет GLOB для глобуса.

$ perl -e'$x = *STDOUT; CORE::say ref(\$x)'
GLOB

Есть ли способ «контролировать» переменную?

Да. Вы можете добавить к нему magi c.

$ perl -e'
   use feature qw( say );

   use Carp            qw( cluck );
   use Variable::Magic qw( wizard cast );

   my $wiz = wizard(
      data => sub { $_[1] },
      set  => sub { cluck("Variable $_[1] modified"); },
   );

   my $x;
   cast($x, $wiz, q{$x});
   $x = 123;                     # Line 14
'
Variable $x modified at -e line 9.
        main::__ANON__(SCALAR(0x50bcee23c0), "\$x") called at -e line 14
        eval {...} called at -e line 14

Требуется дополнительная работа, чтобы определить, изменяется ли ha sh или массив, но вышеизложенное можно использовать для мониторинга элементов хэшей и массивов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...