Perl 评估函数示例--正则表达式、错误处理、要求、超时、动态代码

举报
Tiamo_T 发表于 2022/02/14 16:05:51 2022/02/14
【摘要】 Perl 的 eval 内置函数非常强大。在本文中,让我们了解如何在 eval 中使用正则表达式,使用 eval 捕获错误,使用 eval 创建动态代码,使用 eval 从文件/子例程插入代码等。

Perl 的 eval 内置函数非常强大。在本文中,让我们了解如何在 eval 中使用正则表达式,使用 eval 捕获错误,使用 eval 创建动态代码,使用 eval 从文件/子例程插入代码等。

perl eval的一般形式需要一个表达式或一个代码块作为参数。

一、各种Perl Eval语句的区别

让我们考虑以下 perl 代码片段:

$expr = '$a + $b';
评估 $expr; # 1
评估“$expr”; # 2
评估 '$expr'; # 3
评估 { $expr }; #4

案例#1 和#2 相同,perl 将它们识别为有效的可执行语句并计算表达式。因此,它将产生结果为“30”。

在情况 #3 中,无法扩展表达式。因此,它给出了实际的表达式 ($a + $b) 作为结果。这不会被任何人普遍使用。

案例#4 与案例#3 相同,但在编译时验证块内的语句是否存在语法错误。


2. 用 Eval 处理正则表达式

通过使用 eval,当需要匹配多于多个正则表达式的行时,我们可以显着减少代码中的行数。

正则表达式列表可以放入一个容器(哈希/数组)中,在一个循环中,可以将正则表达式一个一个地取出并与输入行匹配,如下所示。

$line = <>;
%hash = (
number     => qr/^[0-9]+$/,
alphabets   => qr/^[a-zA-Z]+$/
);

while( my ($key,$value) = each(%hash) ) {
if(eval    "$line =~ /$value/") {
print "$key\n";
}
}

3. Perl Eval 错误处理——捕获错误

eval 用于捕获错误。在子程序执行期间,程序可能会因为错误或外部调用 die 函数而死掉。在此期间,如果 perl 代码块在 eval 内执行,则即使在 die 或 errors 之后程序仍继续运行,并且它还会捕获错误或 dieing 单词。

零除法误差:

eval  { $average =  $total / $count };
print “Error captured : $@\n”;

在上面,$count 包含的值为 0。当我们在没有 eval 块的情况下运行代码时,程序会退出。

死后跑

sub func
{
die “dieing in subroutine func\n”;
}
eval { func(); };
print “Error captured : $@\n”;

Perl eval 无法捕获以下错误:

  • 未捕获的信号
  • 内存不足
  • 语法错误

4. 使用 Eval 的动态 Perl 代码

Eval 可以在运行时从字符串编译和执行代码。因此,我们可以使用 eval 编写动态 perl 程序。

print “Enter number 1 : ”;
$data1 = ;
print “Enter number 2 : ”;
$data2 = ;
print “Enter operator : ”;
$operator = ;
$str = “$data1 $operator $data2”;
$result = eval “$data1 $operator $data2”;

我们可以在 eval 中执行任意数量的语句。eval 的结果是最后一个计算的表达式。

在字符串上使用 eval 时我们应该小心,因为它可能会执行来自字符串的不受信任的数据。如果赋值操作必须在字符串本身中完成,我们应该小心处理左值。

$str = “\$result = $data1 $operator $data2”;
eval { $str };

5. 在运行时从文件或子程序中插入 Perl 脚本

在 perl 中,我们可以在运行时动态加载模块。要动态加载模块,我们必须使用“require”(而不是“use”)。
当输入文件是压缩文件时加载模块的示例代码,

$filetype = `file $InputFile`;

if($filetype =~ /gzip compressed/) {
print  "compressed input file...\n";
eval { require PerlIO::gzip; };
}

程序中使用的公共子程序可以分成一个文件,该文件可以通过 eval 加载到 perl 程序中,如下所示。

File :  common_routines.pl
sub open_file
{
....
}
sub read_file
{
....
}
sub write_file
{
....
}
sub close_file
{
....
}
In the perl script,
sub load_file_subroutines
{
open CODE, 'common_routines.pl';
undef $\;
my $code = <code>;
close CODE;
eval $code;
die $@ if $@;
}</code>

6. 输入超时中的 Perl Eval

报警标准库函数用于在一定时间后产生 SIGALRM 信号。这主要有助于我们避免对用户输入的阻塞等待。这可以与 eval 一起使用,以在指定时间内获取用户输入,如下例所示。

$SIG{ALRM} = \&input_timed_out;
eval {
alarm (10);
$buf = <>;
alarm(0);           # Cancel the pending alarm if user responds.
};
if ($@ =~ /NO USER INPUT IN TIME/) {
print "Timed out.\n";
}
sub input_timed_out {
die "NO USER INPUT IN TIME";
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。