这个 Perl 表达式有什么问题?

发布于 2024-12-20 06:51:50 字数 152 浏览 0 评论 0原文

下面有什么问题。我收到 $attribute not Defined 错误。

if (my $attribute = $Data->{'is_new'} and $attribute eq 'Y') {
}

What's the problem with following. I am getting $attribute not defined error.

if (my $attribute = $Data->{'is_new'} and $attribute eq 'Y') {
}

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

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

发布评论

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

评论(4

难如初 2024-12-27 06:51:50

你太聪明了。只需这样做:

my $attribute = $Data->{'is_new'};

if (defined $attribute && $attribute eq 'Y') { ... }

问题是双重的:

  • 在表达式上下文中的if my 中,您有一个额外的 )
  • 绑定非常紧密; $attribute 直到包含它的条件语句主体才处于词法范围内,因此 and 的另一个分支无法访问它。您需要将其提升到包含上下文,如我的示例所示。

You're being too clever. Just do this:

my $attribute = $Data->{'is_new'};

if (defined $attribute && $attribute eq 'Y') { ... }

The problems are twofold:

  • You have an extra ) in your if
  • my in expression context binds very tightly; $attribute is not in lexical scope until the body of the conditional statement that contains it, so the other branch of the and cannot access it. You need to lift it to the containing context, as in my example.
冷弦 2024-12-27 06:51:50

use strict; 就会发现问题。

$ perl -e'use strict; my $attribute = "..." and $attribute eq "Y";'
Global symbol "$attribute" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

my 声明仅对后续语句产生影响,而不会影响该声明所在的语句。 (ourlocal 声明也是如此。)这意味着您使用 my 创建的 $attribute 和您指定的变量与您与 Y 进行比较的 $attribute 不同。现在

my $attribute = $Data->{'is_new'};
if ($attribute eq 'Y') { ... }

,如果 $Data->{is_new} 不存在或未定义,则 $attribute 将未定义,并将其与 Y< /code> 将发出警告。您可以按如下方式避免此警告:

my $attribute = $Data->{'is_new'};
if (defined($attribute) && $attribute eq 'Y') { ... }

或者:(5.10+)

my $attribute = $Data->{'is_new'};
if (($attribute // '') eq 'Y') { ... }

use strict; would have found the problem.

$ perl -e'use strict; my $attribute = "..." and $attribute eq "Y";'
Global symbol "$attribute" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.

A my declaration only has an effect on subsequent statements, not the the statement in which the declaration is is located. (Same goes for the our and local declarations.) That means the $attribute that you create with my and to which you assign is a different variable than the $attribute you compare to Y. You want

my $attribute = $Data->{'is_new'};
if ($attribute eq 'Y') { ... }

Now, if $Data->{is_new} doesn't exist or is undefined, $attribute will be undefined, and comparing it to Y will issue a warning. You can avoid this warning as follows:

my $attribute = $Data->{'is_new'};
if (defined($attribute) && $attribute eq 'Y') { ... }

Alternatively: (5.10+)

my $attribute = $Data->{'is_new'};
if (($attribute // '') eq 'Y') { ... }
2024-12-27 06:51:50

其他答案都很好。我只是想补充一点,如果您想避免使用 $attribute 变量混淆周围的范围,您可以这样做:

if (($Data->{'is_new'} || '') eq 'Y') {
    # do stuff
}

这也适用于 strictwarnings.

The other answers are good. I just want to add that if you want to avoid cluttering the surrounding scope with the $attribute variable you could do:

if (($Data->{'is_new'} || '') eq 'Y') {
    # do stuff
}

This also works with strict and warnings.

Saygoodbye 2024-12-27 06:51:50

正如已经提到的,您不能在声明变量的同时使用它。事情就是这样;您需要先完成声明语句,然后才能使用新变量。

不过,坦率地说,我有点迷失,为什么还没有提到这一点,你本来可以做的是:

if (my $attribute = $Data->{'is_new'} and $Data->{'is_new'} eq 'Y') 

$attribute尚未声明,但是$Data->{'is_new'}

需要明确的是:这个 if 语句的要点是三件事:

  • 初始化并为 $attribute 分配一个值
  • 检查该值是否为未定义/空字符串/零
  • 检查该值是否为 < code>'Y'

$attribute 的词法范围是 if 语句后续块的内部,不多也不少。

Like has already been mentioned, you cannot declare a variable and use it at the same time. That's just the way it is; You need to finish the declaration statement before you can use the new variable.

What you could have done though, and I am frankly somewhat lost as to why this has not been mentioned yet, is this:

if (my $attribute = $Data->{'is_new'} and $Data->{'is_new'} eq 'Y') 

$attribute is not yet declared, but $Data->{'is_new'} is.

Just to be clear: The point of this if statement would then be three things:

  • Initialize and assign a value to $attribute
  • Check that this value is not undefined/empty string/zero
  • Check if this value is 'Y'

The lexical scope of $attribute is the inside of the if-statements subsequent block, no more, no less.

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