You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Perl代码中省略临时变量$n优化FLAGS过滤逻辑?

Perl中省略grep临时变量调用对象方法的可行语法

你可以通过两种方式省略临时变量$n,直接在grep块里用$_->[0]作为方法名调用:

方法1:使用${\(...)}强制插值

Perl里如果要把表达式直接作为方法名调用,需要用${\(表达式)}明确告诉解释器先计算表达式的值,再作为方法名使用。写法如下:

[grep { $self->${\($_->[0])}() } FLAGS]

这里${\($_->[0])}会先取出数组引用的首个元素(方法名),再让$self调用该方法。

方法2:利用can方法获取代码引用

can是Perl对象的内置方法,会返回对应方法的代码引用(若方法存在),之后直接调用这个代码引用并传入$self作为第一个参数(对象方法调用的本质就是把对象作为第一个参数传给子例程):

[grep { $self->can($_->[0])->($self) } FLAGS]

这种写法更健壮:如果FLAGS里存在不存在的方法名,can会返回undef,调用undef会返回false,直接被grep过滤掉,不会触发方法不存在的报错。

为什么直接写会报错?

你尝试的无临时变量写法$self->$_->[0](),会被Perl解析成先调用$self->$_(把当前数组引用$_当作方法名,逻辑完全错误),再尝试取返回值的[0]元素并调用,自然会触发报错。

最小可运行示例

use strict;
use warnings;

package MyObj;

sub new {
    my ($class, %args) = @_;
    bless \%args, $class;
}

sub is_active   { shift->{active} // 0 }
sub is_visible  { shift->{visible} // 0 }
sub is_enabled  { shift->{enabled} // 0 }

use constant FLAGS => (
    ['is_active'],
    ['is_visible'],
    ['is_enabled'],
);

sub get_set_flags {
    my $self = shift;
    # 任选一种写法即可
    return [map { $_->[0] } grep { $self->${\($_->[0])}() } FLAGS];
    # return [map { $_->[0] } grep { $self->can($_->[0])->($self) } FLAGS];
}

package main;

my $obj = MyObj->new(active => 1, enabled => 0);
my $set_flags = $obj->get_set_flags();

print "已设置的标志:" . join(', ', @$set_flags) . "\n";
# 输出:已设置的标志:is_active

内容的提问来源于stack exchange,提问作者U. Windl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 23:13:22