这段 Perl 代码中的 '@(' 做什么?

发布于 2024-12-17 06:15:26 字数 497 浏览 1 评论 0原文

在此代码片段中:

    use strict;
    use warnings;
    use Data::Dumper;
    my $r = [qw(testing this thing)];

    print Dumper($r);
    foreach my $row (@({$r})
    {
        print "$row\n";
        $row .= 'mod';
    }
    print Dumper($r);
    print Dumper(@({$r});

我发现 foreach 中“@”后面的“(”导致其无法正确循环。我不知道为什么这段代码甚至可以工作,因为没有结束括号。它看起来是在动态创建一个新变量,但不应该触发“use strict”或其他什么

? '@(' 是正在做什么以及为什么它仍然在没有结束括号的情况下运行。

In this code snippet:

    use strict;
    use warnings;
    use Data::Dumper;
    my $r = [qw(testing this thing)];

    print Dumper($r);
    foreach my $row (@({$r})
    {
        print "$row\n";
        $row .= 'mod';
    }
    print Dumper($r);
    print Dumper(@({$r});

I figured out that the '(' after the '@' in the foreach is causing this not to loop correctly. I have no idea why this code even works as there is no ending parenthesis. What is this doing? It looks to be creating a new variable on the fly, but shouldn't 'use strict' have fired or something?

Please help explain what that '@(' is doing and why it still runs without an ending parenthesis.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

悲喜皆因你 2024-12-24 06:15:26

这是 %( 变量的哈希切片,它是 *( glob 的一部分,不受严格变量的限制。对于 Perl 预定义的变量来说也是如此,在这种情况下 $( 以及所有其他用于标点符号变量名称的 glob 槽。所有标点符号变量在所有包中都是全局的,并且它们的完全限定名称是缩写形式: $), @)%)&)... 由于 strict 'vars' 不适用于完全限定名称,这些名称都不是错误。

扩展一下:

@({$r};
@{(}{$r};
@{'main::('}{$r};  # needs strict refs to be off

这些行都是等价的。

使用 use warnings; perl 会让您知道最好用 $ 符号编写单个值的切片:

$({$r};
${(}{$r};
${'main::('}{$r};  # needs strict refs to be off

在尝试解决拼写错误时会产生这样的结果:为您指出了正确的位置。这就是为什么你应该始终使用警告和限制。

有关更多详细信息,perlvar 联机帮助页显示了至少带有一个或另一个印记的所有标点变量。如果您想要有关标点符号变量范围的参考,package 文档中有相关内容。


所有标点变量也不受仅使用一次警告的影响,这可能是一个错误......

That is a hash slice of the %( variable, which being part of the *( glob, is exempt from strict vars. This is true for variables that Perl has predefined, in this case $( and also for all of the other glob slots for the names of punctuation variables. All punctuation variables are global across all packages, and their fully qualified names are the short forms: $), @), %), &)... Since strict 'vars' does not apply to fully qualified names, none of these names are errors.

Expanding a bit:

@({$r};
@{(}{$r};
@{'main::('}{$r};  # needs strict refs to be off

Those lines are all equivalent.

With use warnings; perl will let you know that it would be better to write a slice of a single value with a $ sigil:

$({$r};
${(}{$r};
${'main::('}{$r};  # needs strict refs to be off

Which in trying to resolve a typo would have pointed you in the right spot. Which is why you should always use both warnings and strictures.

For more detail, the perlvar manpage shows all of the punctuation variables with at least one sigil or another. And if you wanted a reference about the scoping of punctuation variables, the package docs have that.


All the punctuation variables are also immune to used only once warnings, and that might be a bug...

一城柳絮吹成雪 2024-12-24 06:15:26

@({$r} 是一个哈希切片(记录在 perldata ) 的哈希 %(。Perl

%h = (a=>1, b=>2, c=>3);
say for @h{qw( a c )};  # 1 3

本身不使用 %(,所以它肯定是空的。

你肯定想使用 @{$r}< /code>,一种相当复杂的方式或写法@$r

@({$r} is a hash slice (documented in perldata) of the hash %(.

%h = (a=>1, b=>2, c=>3);
say for @h{qw( a c )};  # 1 3

Perl itself doesn't use %(, so it was surely empty.

You surely meant to use @{$r}, a rather complex way or writing @$r.

韵柒 2024-12-24 06:15:26

当我在其上运行 perl -cw 时,它显示:

Scalar value @({$r} better written as $({$r} at tmp.pl line 7.
Scalar value @({$r} better written as $({$r} at tmp.pl line 13.

$r 是对数组的引用。正如 Eric Strom 刚刚发布的那样,@({$r}%( 哈希变量的哈希切片。

您从未声明 %(,它不是 perldoc perlvar 中列出的预定义变量之一。那么为什么不 use strict; use warnings; 导致 Perl 抱怨它呢?任何名称为标点符号的变量都是预定义(比跟踪哪些变量真正是更简单,其中一些可能是 undef

请注意,$( 是一个有效的预定义变量(它是真正的组 -当前进程的 id),所以看起来像不匹配的括号的东西不一定是一个错误,

它看起来只是一个拼写错误,出于某种不明原因,Perl 没有抱怨

更改 。 @({$r}@{$r} 去做你(大概)真正想做的事情。

When I run perl -cw on it, it says:

Scalar value @({$r} better written as $({$r} at tmp.pl line 7.
Scalar value @({$r} better written as $({$r} at tmp.pl line 13.

$r is a reference to an array. As Eric Strom just posted, @({$r} is a hash slice of the %( hash variable.

You never declared %(, and it's not one of the predefined variables listed in perldoc perlvar. So why doesn't use strict; use warnings; cause Perl to complain about it? It probably just assumes that any variable whose name is a punctuation character is predefined (simpler than keeping track of which ones really are, some of which might be undef anyway).

Note that $( is a valid predefined variable (it's the real group-id of the current process), so something that looks like a mismatched parenthesis isn't necessarily an error.

It looks like it's simply a typo that, for obscure reasons, Perl didn't complain about.

Change @({$r} to @{$r} to do what you (presumably) actually meant to do.

分分钟 2024-12-24 06:15:26

它没有让我点击,这是一个哈希切片,直到我通过 B::Concise

$ perl -MO=Concise junk 
    Scalar value @({$r} better written as $({$r} at junk line 7.
    Scalar value @({$r} better written as $({$r} at junk line 13.
    junk syntax OK
    1l <@> leave[1 ref] vKP/REFC ->(end)
    1     <0> enter ->2
    ...
    ...
    1h             <@> hslice lKM ->1i
    1d                <0> pushmark s ->1e
    1e                <0> padsv[$r:335,339] l ->1f
    1g                <1> rv2hv[t17] sKR/3 ->1h
    1f                   <#> gv[*(] s ->1g
    -              <1> ex-rv2cv sK/2 ->-
    1i                <#> gv[*Dumper] s ->1j

hslice 意味着哈希切片 :) 运行它,了解你的 B:: 树,它真的很有帮助

It didn't click for me, that this is a hash slice, until I ran it through B::Concise

$ perl -MO=Concise junk 
    Scalar value @({$r} better written as $({$r} at junk line 7.
    Scalar value @({$r} better written as $({$r} at junk line 13.
    junk syntax OK
    1l <@> leave[1 ref] vKP/REFC ->(end)
    1     <0> enter ->2
    ...
    ...
    1h             <@> hslice lKM ->1i
    1d                <0> pushmark s ->1e
    1e                <0> padsv[$r:335,339] l ->1f
    1g                <1> rv2hv[t17] sKR/3 ->1h
    1f                   <#> gv[*(] s ->1g
    -              <1> ex-rv2cv sK/2 ->-
    1i                <#> gv[*Dumper] s ->1j

hslice means hash slice :) get to know your B:: tree, its really helpfull

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文