Perl 星号符号有啥作用
Posted
技术标签:
【中文标题】Perl 星号符号有啥作用【英文标题】:What does the Perl asterisk sigil doPerl 星号符号有什么作用 【发布时间】:2016-06-17 06:23:00 【问题描述】:我正在更新一些非常旧的 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 可以采用不同的数据类型来匹配传递给子的任何参数。
【问题讨论】:
确定不是&DoEvent(\$abc, "DoXyz", @args)
和&DoEvent(\@xyz, "DoXyz", @args)
?您发布的内容没有多大意义。
【参考方案1】:
语法错误与 glob(带有星号符号的符号)无关。语法错误是由于在 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 主要在内部使用,尽管一些文件句柄主要通过命名的 glob(*STDIN
、*STDOUT
和 *STDERR
)访问,并且它们用于创建别名 (*foo = \&bar;
)。
【讨论】:
perl -i~ -pe's/do (\$?\w+)(?=\()/$1->/g' *.pl
或类似的东西应该可以解决所有问题。【参考方案2】:
它是包含所有其他类型的命名空间符号 sigil。在较旧的 Perl 代码中,它通常用于处理文件句柄。现代 Perl 应该使用简单的标量 - 即$
。
【讨论】:
【参考方案3】:是glob
,直接访问符号表。例如,通过这种方式,您可以在不引用类型(或具有该名称的任何类型)的情况下访问变量。现在几乎没有理由必须在 Perl 中使用它。
这里有一些参考资料on symbol table、an interesting use of it 和一些overview。书籍“Programming Perl”和“Mastering Perl”有权威性的报道。
【讨论】:
【参考方案4】:在过去,您必须使用 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 );
【讨论】:
目前,我们仍然使用 typeglobs 来传递文件句柄。我们只是将它们的引用存储在标量中。print("$event_fh\n");
.
不过,我们不需要。我们可以将文件句柄直接放入标量中。 perl -e'my $fh = \*STDOUT; print($fh "$fh\n"); $fh = *$fhIO; print($fh "$fh\n");'
以上是关于Perl 星号符号有啥作用的主要内容,如果未能解决你的问题,请参考以下文章