【发布时间】:2021-12-16 05:13:27
【问题描述】:
考虑这个脚本(从我拥有的更大的脚本中总结出来):
#!/usr/bin/perl
use strict;
use warnings;
package help {
my %HELPTEXT;
$HELPTEXT{ "topic" } = "Some help\n";
sub get_help( $ ) {
print $HELPTEXT{ $_[0] };
}
}
package main {
sub main() {
help::get_help( "topic" );
}
}
main();
这有效,打印Some help。
现在,我想将初始化($HELPTEXT{ "topic" } = "Some help\n"; 和其他类似的)放在脚本的末尾 - 同时保留 package help 及其代码。
但是,这不起作用:
# ...
main();
package help {
$HELPTEXT{ "topic" } = "Some help";
}
错误信息:Global symbol "%HELPTEXT" requires explicit package name (did you forget to declare "my %HELPTEXT"?)
这也不起作用:
main();
$help::HELPTEXT{ "topic" } = "Some help\n";
错误信息:Name "help::HELPTEXT" only used once / Use of uninitialized value in print。
显然我缺乏对 Perl 包及其命名空间的理解。
我可以在中间文件包命名空间中有一个变量,并且仍然在文件末尾初始化它吗?
补充:我发现声明问题可以通过our解决:
# ...
main();
package help {
our %HELPTEXT;
$HELPTEXT{ "topic" } = "Some help\n";
}
来自 perldoc:
"our" 为当前包中同名的包(即全局)变量创建一个词法别名,以便在当前词法范围内使用。
但是,这仍然会出现错误:Use of uninitialized value in print。即使我将初始化包装在 INIT {} 块中。
我不仅想为此提供解决方案,而且了解为什么这不能按我预期的那样工作。通过猜测编码感觉很糟糕......
【问题讨论】:
-
my %HELPTEXT;去哪儿了? -
用
my声明的变量超出了它声明的块的范围。 -
@choroba 他正在使用两个
package help块......显然你可以这样做,根据 perldoc。这也让我很困惑。 -
@TLP,是的,使用同一个包的不同代码段没有问题。
package help { }之前和之后的代码将是另一个示例。 -
如果您将
main()函数调用放在最后一个包声明之后,它会按预期工作。它似乎按照它出现的顺序执行代码,如果你仔细想想,这并不奇怪。如果我写my $foo; print $foo; $foo = 'abc';,那么它不会打印abc,我们也不会期望它。
标签: perl package initialization