如何在Perl中的变量中“存储”运算符?

时间:2010-03-21 09:44:06

标签: perl

我正在寻找一种在Perl中执行此操作的方法:

$a = "60"; $b = "< 80";

if ( $a $b ) {  then .... }

在这里,$b“拥有”一名运营商......我可以这样做吗?也许还有其他方式?

6 个答案:

答案 0 :(得分:18)

很高兴看到人们如何发现函数式编程。 : - )

幸运的是,Perl具有即时创建和存储功能的能力。例如,您问题中的示例将如下所示:

$a = "60"; $b = sub { $_[0] < 80 };

if ( $b->($a) ) { .... }

在此示例中,对匿名子例程的引用存储在$b中,该子句具有与通常的参数传递相同的语法。然后使用->来引用调用(与可能用于引用数组和哈希的语法相同)。

但是,当然,如果您只想从任意字符串构造Perl表达式,您可能希望使用eval

$a = "60"; $b = " < 80";

if ( eval ("$a $b") ) { .... }

但是,如果您正在评估的字符串包含作为用户输入的部分,则通过eval执行此操作并不安全。 Sinan Ünür explained it perfectly in his answer-comment

答案 1 :(得分:8)

如何定义包含所需条件的函数:

my $cond = sub { $_[0] < 80 };

if ( $cond->( $a ) ) { 
     ...
}

答案 2 :(得分:8)

这应该是一个评论,但评论过于局促这样的事情所以我正在做CW。

对于您显示将要传递给string eval的变量内容的情况,接受的解决方案是正确的。

但是,如果$a$b的内容来自用户输入,请查看以下脚本:

#!/usr/bin/perl

use strict; use warnings;

my $x = '80';
my $y = '; warn "evil laugh!\n"; exit';

if ( eval ($x . $y) ) {
    print "it worked!!!\n";
}

如果用户输入了字符串,则无法阻止用户将字符串';system "rm -rf /bin"'传递给您的程序。

因此,正确解决您的问题需要编写或使用表达式解析器。

顺便说一句,你不应该使用$a$b作为变量名称作为sort使用的神奇包本地变量,因此它们不受strict的限制 - 并且必须始终在您的计划中使用strictwarnings

答案 3 :(得分:6)

$a = "60"; $b = "< 80";
if( eval($a. $b)){
  print "ok";
}

请参阅perldoc eval了解更多

答案 4 :(得分:1)

我想知道Number::Compare是否对此感兴趣。从示例:

 Number::Compare->new(">1Ki")->test(1025); # is 1025 > 1024

 my $c = Number::Compare->new(">1M");
 $c->(1_200_000);                          # slightly terser invocation

答案 5 :(得分:0)

如果您信任(或可以充分验证)$ op并且不信任输入的安全性,则更安全的表格:

git checkout release
git checkout master -- website1/
git checkout master -- website2/