在perl中使用标量作为条件

在perl中使用标量作为条件,perl,if-statement,conditional-statements,scalar,Perl,If Statement,Conditional Statements,Scalar,第一次…所以在提出问题时,如果有什么我没有注意到的,请告诉我 问题是如何使用标量作为条件,因为下面的代码不起作用 my @parameter=('hub'); my %condition; $condition{'hub'}{'1'}='$degree>=5'; foreach (@parameter) { if ($condition{$_}{'1'}) {..} } if ("$condition{$parameter}{'1'}") { ..} 我认为这是因为条

第一次…所以在提出问题时,如果有什么我没有注意到的,请告诉我

问题是如何使用标量作为条件,因为下面的代码不起作用

my @parameter=('hub');

my %condition;
$condition{'hub'}{'1'}='$degree>=5';

foreach (@parameter) {
       if ($condition{$_}{'1'}) {..}
}
if ("$condition{$parameter}{'1'}") { ..}
我认为这是因为条件没有被正确解释,所以我也尝试了下面的方法,这也不起作用

my @parameter=('hub');

my %condition;
$condition{'hub'}{'1'}='$degree>=5';

foreach (@parameter) {
       if ($condition{$_}{'1'}) {..}
}
if ("$condition{$parameter}{'1'}") { ..}

非常感谢您的帮助。:)

你在期待什么?字符串值为非空时,将被解释为
true

themel@kallisti: ~ $ perl -e 'print "oops\n" if "false" ; '
oops
themel@kallisti: ~ $ perl -e 'print "oops\n" if "" ; '
themel@kallisti: ~ $ perl -e 'print "oops\n" if "\$degree < 5" ;'
oops
印刷品

$foo>42 itself was true
$foo>23 itself was true
$foo>23 evaluated to true

要么需要stringeval,它将字符串作为Perl代码进行计算

if (eval $condition{$_}{'1'}) { ...
或者更安全的方法是使用


在第二个示例中,将一段代码附加到变量。
$var->()
语法执行代码并计算代码的返回值。

您试图做的是将“$degree>=5”计算为实际代码。与其尝试将字符串作为代码进行求值(这是可以完成的),相反,传递代码引用通常更安全、更健壮。您可以使用生成器子例程按需生成条件子例程,如下所示:

sub generate_condition {
    my ( $test, $bound ) = @_;
    return sub { return $test >= $bound; };
}

my %condition;
$condition{'hub'}{'1'} = generate_condition( $degree, 5 );

if( $condition{$parameter}{1}->() ) { ... }
sub generate_condition {
    my ( $relation, $bound ) = @_;
    die "Bad relationship\n" 
        if ! $relation =~ m/^(?:<=?|>=?|==|l[te]|g[te]|cmp)$/;
    state $relationships = {
        '<'     => sub { return $_[0]  <   $bound },
        # ......
my $condition = generate_condition( '<', 5 );
if( $condition->(2) ) {
    print "Yes, 2 is less than 5\n";
}
如果您希望动态创建
=
(即关系本身),那么它会变得有点棘手。然后你有两个选择。其中一个将带您回到stringy eval,并考虑其所有风险(特别是当您开始让用户指定字符串时)。另一个是
generate_condition()
sub中的查找表

generate_condition()
返回一个子例程引用,调用该引用时,将计算创建时绑定的条件

这里是一个通用的解决方案,它将接受Perl的任何条件,并将它们与正在测试的参数一起包装到一个子例程中。然后可以调用subref来计算条件:

use strict;
use warnings;
use feature qw/state/;

sub generate_condition {
    my ( $test, $relation, $bound ) = @_;
    die "Bad relationship\n" 
        if ! $relation =~ m/^(?:<=?|>=?|==|l[te]|g[te]|cmp)$/;
    state $relationships = {
        '<'     => sub { return $test <   $bound },
        '<='    => sub { return $test <=  $bound },
        '=='    => sub { return $test ==  $bound },
        '>='    => sub { return $test >=  $bound },
        '>'     => sub { return $test >   $bound },
        '<=>'   => sub { return $test <=> $bound },
        'lt'    => sub { return $test lt  $bound },
        'le'    => sub { return $test le  $bound },
        'eq'    => sub { return $test eq  $bound },
        'ge'    => sub { return $test ge  $bound },
        'gt'    => sub { return $test gt  $bound },
        'cmp'   => sub { return $test cmp $bound },
    };
    return $relationships->{$relation};
}


my $true_condition  = generate_condition( 10, '>', 5 );
my $false_condition = generate_condition( 'flower', 'eq', 'stamp' );

print '10 is greater than 5: ', 
      $true_condition->()  ? "true\n" : "false\n";
print '"flower" is equal to "stamp": ', 
      $false_condition->() ? "true\n" : "false\n";
然后像这样调用它:

sub generate_condition {
    my ( $test, $bound ) = @_;
    return sub { return $test >= $bound; };
}

my %condition;
$condition{'hub'}{'1'} = generate_condition( $degree, 5 );

if( $condition{$parameter}{1}->() ) { ... }
sub generate_condition {
    my ( $relation, $bound ) = @_;
    die "Bad relationship\n" 
        if ! $relation =~ m/^(?:<=?|>=?|==|l[te]|g[te]|cmp)$/;
    state $relationships = {
        '<'     => sub { return $_[0]  <   $bound },
        # ......
my $condition = generate_condition( '<', 5 );
if( $condition->(2) ) {
    print "Yes, 2 is less than 5\n";
}

my$condition=generate_condition('你是说$condition{'hub'}{'1'}='$degree=>5';?eval有效。$condition{'hub'}{'1'}=sub{return$degree>=5};对我不起作用,因为必须定义变量才能起作用-我的变量在代码后面定义。谢谢:)您的第一个代码块有问题:-应该使用\$degree/$$test。您只是用错了。潜艇制造完成后,不应该再看$degree。它用于在生成条件子项时锁定$degree和$test。如果你想更新$degree,你需要生成一个新的sub(绑定了新的值),或者使用第二个代码段,让试用值在匿名sub被调用之前保持空闲。嗯,好的,但这似乎有点毫无意义-为什么每次返回值为常量时都要计算条件?原始帖子没有指定值应该绑定在什么点。第二个代码段显示了如何保留一个参数。如果OP希望两个参数都可以自由进行后期绑定,那么这是一个简单的修改,我也可以添加一个作为更新。谢谢你的建议……好的,更新补充:现在OP可以选择绑定“左,关系,右”,或者让“左”自由,只绑定“关系,右”,甚至让“左”和“右”自由,只绑定关系。如果他需要更大的灵活性,不妨完全取消子生成器,并保留所有三个参数。虽然需要注意
eval
,但这并不总是“错误的方式”。有时候,最快、最简单的方法也不错。并不是每一个Perl脚本都将在空间站上处理生命支持或指导机器人外科医生的手术刀。