英文:
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->$n()
calls the method which name is $n
on object $self
):
[grep { my $n = $_->[0]; $self->$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 => (
['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";
答案1
得分: 2
只允许使用简单的标量,所以您要么使用一个小技巧
$self->${\( $_->[0] )}()
或者采用不同的方法
$self->can( $_->[0] )->( $self )
英文:
Only a simple scalar is allowed there, so you'd either have use a hack
$self->${\( $_->[0] )}()
or a different approach
$self->can( $_->[0] )->( $self )
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论