我正在更新一些非常旧的Perl代码(不是我的代码),我在子例程中遇到了以下内容:
sub DoEvent {
local(*eventWEH, $foreachFunc, @args) = @_;
$ret = do $foreachFunc(*eventWEH, @args);
}
这似乎在Perl 5.6.1中运行良好,但在Perl 5.22中不再有效,它在do $ foreachFun之后出现语法错误(
变量* eventWEH前面的星号的用途是什么?
如果这是“C”,我会建议某种指针。 有什么建议吗?
ETA:第一个参数调用了许多不同类型的子。例如:
&DoEvent($abc, "DoAbc", @args);
和
&DoEvent(@xyz, "DoXyz", @args);
因此,根据给出的答案,看起来* eventWEH可以采用不同的数据类型来匹配传递给子的任何参数。
答案 0 :(得分:13)
语法错误与globs(带星号sigil的符号)无关。语法错误是由于5.20中删除了do $func(LIST)
。取代
$ret = do $foreachFunc(*eventWEH, @args);
与
$ret = $foreachFunc->(*eventWEH, @args);
至于你的文字问题,*foo
是一个typeglob,或简称为glob。 glob是以下C结构的实例的代理:
struct gp {
SV * gp_sv; /* scalar value */
struct io * gp_io; /* filehandle value */
CV * gp_cv; /* subroutine value */
U32 gp_cvgen; /* generational validity of cached gp_cv */
U32 gp_refcnt; /* how many globs point to this? */
HV * gp_hv; /* hash value */
AV * gp_av; /* array value */
CV * gp_form; /* format value */
GV * gp_egv; /* effective gv, if *glob */
PERL_BITFIELD32 gp_line:31; /* line first declared at (for -w) */
PERL_BITFIELD32 gp_flags:1;
HEK * gp_file_hek; /* file first declared in (for -w) */
};
Glob主要在内部使用,但有些文件句柄主要通过命名的globs(*STDIN
,*STDOUT
和*STDERR
)访问,并且它们用于创建别名({{1 }})。
答案 1 :(得分:3)
包含所有其他类型的命名空间符号sigil。在旧的Perl代码中,它通常用于处理文件句柄。现代Perl应该使用简单的标量 - 即$
。
答案 2 :(得分:2)
它是glob
,它直接访问符号表。例如,这样您就可以在不引用类型(或具有该名称的任何类型)的情况下访问变量。现在很少有理由在Perl中使用它。
以下是一些参考on symbol table,an interesting use of it和一些overview。 “Perl编程”和“掌握Perl”这些书籍具有明确的覆盖范围。
答案 3 :(得分:1)
在过去,您必须使用typeglob来传递文件句柄,如下所示:
# eventWEH is a global filehandle
open( eventWEH, $filename ) or die "Couldn't open $filename: $!";
somefunc( *eventWEH );
但是现在你有适当的词法文件句柄,所以你可以做
my $event_fh;
open( $event_fh, '<', $filename ) or die "Couldn't open $filename: $!";
somefunc( $event_fh );