【问题标题】:Perl: Variable value is 'glob', but should be 'scalar'Perl:变量值是“glob”,但应该是“标量”
【发布时间】:2020-06-12 01:23:39
【问题描述】:

我确实有以下简单代码:

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

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

这个应用程序服务器有时会变得“脏”,上面的代码会打印以下错误:

DateTime::TimeZone::new 的“名称”参数(“Europe/Berlin”)是 一个“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. 有没有办法“监控” 多变的?基本上,如果变量发生变化,就会得到一个堆栈跟踪

【问题讨论】:

  • ref(\$var) 将返回 GLOB 以获得全局。例如,perl -e'$x = *STDOUT; CORE::say ref(\$x)'
  • 谢谢。您知道星号 (*) 是否始终是创建 GLOB 的方式吗?
  • * 是 glob 的标志。 *foo 表示“当前包中名为 foo 的 glob”,就像 $x 指的是名为 x 的标量一样。

标签: perl variables glob


【解决方案1】:

如何创建“glob”变量?

Glob,“typeglob”的缩写,是一种结构(在 C 意义上),它包含一个字段,用于表示可以在符号表中找到的每种类型的变量(标量、数组、散列、代码、glob、等等)。它们构成了符号表。

只需提及一个包变量即可创建 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 引用的 glob 的引用填充 $fh

$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.

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

ref(\$var) 将返回 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

需要做更多的工作来检测散列或数组是否发生变化,但以上可用于监控散列和数组的元素。

【讨论】:

  • 这很有帮助!谢谢。
  • 也许您能帮我进一步解释一下?我得到了一个对象...但是 Perl 突然将属性转换为 typeglobs(见屏幕截图)。你碰巧知道关于 Perl 对象处理的更多细节吗?截图:server.xsigndll.com/typeglob-issue.png
  • @xsigndll:问一个新问题问一个新问题。 Perl 通常不会这样做:包含所有细节(是否包含任何 OO 框架?),最好的方法是发布SSCCE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多