避免使用临时变量的正确语法

huangapple go评论74阅读模式
英文:

Correct syntax to avoid the temporary variable

问题

我有一个名为FLAGS的列表,其中每个元素都是一个数组引用,其中第一个元素是要设置的某个布尔标志的方法名称(组合的getter/setter)。
在准备将对象"JSON化"之前,我想要省略未设置的标志(getter方法将返回false)。

用于过滤标志名称的代码的一部分是($self->$n() 调用了名称为 $n 的方法,该方法存在于对象 $self 中):

[grep { my $n = $_->[0]; $self->$n() } FLAGS]

(很抱歉,原始代码非常复杂,所以无法提供完整的示例)

我尝试过,但无法找到避免临时变量 $n 的语法(错误消息类似于"无法通过包来定位对象方法 'ARRAY(0x1c47418)'")。

是否存在这样的语法,如果存在,它是什么样子的?

更新

虽然我认为可以提供现有信息的答案,但我创建了一个非常类似的最小工作示例:

#!/usr/bin/perl
use strict;
use warnings;

package MWE;

use constant FLAGS      => (
    ['is_authentic', 1],
    ['is_disabled', 2],
    ['is_fault', 3],
#...
);                                      # flag list

sub new($;$)
{
    my ($class, $flags) = @_;
    my $self = $flags;

    bless $self, $class;
    return $self;
}

# value of a bit
sub _bit_value($)
{
    use integer;
    return (1 << $_[0]);
}

# test a bit
sub _bit_test($$)
{
    my ($val, $bit) = @_;

    return $val & _bit_value($bit);
}

sub is_authentic($) { return _bit_test(${$_[0]}, 1) != 0 }
sub is_disabled($)  { return _bit_test(${$_[0]}, 2) != 0 }
sub is_fault($)  { return _bit_test(${$_[0]}, 3) != 0 }

sub flags($)
{
    my $self = $_[0];

    #return FLAGS;
    return grep { my $n = $_->[0]; $self->$n() } FLAGS;
}

1;

package main;
my $f = MWE->new(2);
print "flags: ", join('|', map { $_->[0] } $f->flags()), "\n";
英文:

Writing some code, I have a list named FLAGS where each element is an array reference where the first element is a method name for some Boolean flag to be set (combined getter/setter).
In preparation to "JSONize" the object I want to omit the flags that aren't set (getter method would return false then).

Part of the code to filter the flag names is ($self-&gt;$n() calls the method which name is $n on object $self):

[grep { my $n = $_-&gt;[0]; $self-&gt;$n() } FLAGS]

(Sorry the original code is highly complex, so I can't provide a complete example)

I tried, but couldn't find out the syntax to avoid the temporary variable $n (The error message was like "Can't locate object method "ARRAY(0x1c47418)" via package ...").

Does such syntax exist, and if so, how does it look like?

Update

While I think the answer could be provided with the information present, I made some very similar minimal working example:

#!/usr/bin/perl
use strict;
use warnings;

package MWE;

use constant FLAGS      =&gt; (
    [&#39;is_authentic&#39;, 1],
    [&#39;is_disabled&#39;, 2],
    [&#39;is_fault&#39;, 3],
#...
);                                      # flag list

sub new($;$)
{
    my ($class, $flags) = @_;
    my $self = $flags;

    bless $self, $class;
    return $self;
}

# value of a bit
sub _bit_value($)
{
    use integer;
    return (1 &lt;&lt; $_[0]);
}

# test a bit
sub _bit_test($$)
{
    my ($val, $bit) = @_;

    return $val &amp; _bit_value($bit);
}

sub is_authentic($) { return _bit_test(${$_[0]}, 1) != 0 }
sub is_disabled($)  { return _bit_test(${$_[0]}, 2) != 0 }
sub is_fault($)  { return _bit_test(${$_[0]}, 3) != 0 }

sub flags($)
{
    my $self = $_[0];

    #return FLAGS;
    return grep { my $n = $_-&gt;[0]; $self-&gt;$n() } FLAGS;
}

1;

package main;
my $f = MWE-&gt;new(2);
print &quot;flags: &quot;, join(&#39;|&#39;, map { $_-&gt;[0] } $f-&gt;flags()), &quot;\n&quot;;

答案1

得分: 2

只允许使用简单的标量,所以您要么使用一个小技巧

$self-&gt;${\( $_-&gt;[0] )}()

或者采用不同的方法

$self-&gt;can( $_-&gt;[0] )-&gt;( $self )
英文:

Only a simple scalar is allowed there, so you'd either have use a hack

$self-&gt;${\( $_-&gt;[0] )}()

or a different approach

$self-&gt;can( $_-&gt;[0] )-&gt;( $self )

huangapple
  • 本文由 发表于 2023年7月10日 18:35:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76652906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定