Perl:变量值为'glob',但应为'scalar'

问题描述 投票:2回答:1

我确实具有以下简单代码:

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

此代码在应用程序服务器中运行,该服务器基本上是一个长时间运行的Perl进程,它接受传入的网络连接。

此应用程序服务器有时会以某种方式变得“肮脏”,并且上面的代码显示以下错误:

DateTime :: TimeZone :: new的'name'参数(“欧洲/柏林”)原为“ 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. 如何创建“全局”变量?它的语法是什么?我是我很确定我庞大的代码库中有些意外,但是我不知道要搜索什么。
  3. 有没有一种方法可以“监视”变量?基本上,如果变量更改,则获取堆栈跟踪]
perl variables glob
1个回答
5
投票

如何创建“全局”变量?

Glob,“ typeglob”的缩写,是一种结构(用C语言表示),它包含可在符号表中找到的每种类型的变量(标量,数组,哈希,代码,glob等)的字段。 )。它们形成符号表。

仅通过提及包变量即可创建全局变量。

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

由于glob本身就是包变量,因此只需提及它就可以使glob存在。

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

请注意,文件句柄通常是通过glob访问的。例如,open(my $fh, '<', ...)使用对包含对IO对象($fh)的引用的glob(*$fh)的引用来填充*$fh{IO}

如果'glob'不是引用,如何正确调试变量?

[ref(\$var)将返回glob的GLOB

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

有没有办法'监视'变量?

是。您可以为其添加魔法。

$ 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

需要更多的工作来检测哈希或数组是否发生更改,但以上内容可用于监视哈希和数组的元素。

© www.soinside.com 2019 - 2024. All rights reserved.