Perl eval函数

 eval EXPR
eval 表达式
       eval BLOCK

eval 代码块

       eval    In the first form, the return value of EXPR is parsed and exe-
               cuted as if it were a little Perl program.  The value of the
               expression (which is itself determined within scalar context)
               is first parsed, and if there weren’t any errors, executed in
               the lexical context of the current Perl program, so that any
               variable settings or subroutine and format definitions remain
               afterwards.  Note that the value is parsed every time the
               "eval" executes.  If EXPR is omitted, evaluates $_.  This form
               is typically used to delay parsing and subsequent execution of
               the text of EXPR until run time.

在第一种形式中,表达式的返回值是解析和执行就好像它是一个小的Perl程序。

表达式的值(这本身就是在标量上下文确定)
首先解析,如果这里没有错误,执行当前的PERL程序的文本,使任何变量设置或者子函数和格式定义保持向后

注意每次eval执行变量都会解析,如果表达式省略,执行$_.
这种形式通常用于延迟解析和随后的文本表达式的执行


执行动态代码:
use strict;
use warnings;

sub test {
    my $num1 = 2;
    my $num2 = 3;

    foreach my $op (qw!+ - * /!) {
        print "$num1 $op $num2 equals ";
        #print eval "$num1 $op $num2", "\n";
        print  "$num1 $op $num2", "\n";
    }
}

test()
[oracle@june3 dbi]$ perl 3.pl
2 + 3 equals 2 + 3
2 - 3 equals 2 - 3
2 * 3 equals 2 * 3
2 / 3 equals 2 / 3
#################################################
[oracle@june3 dbi]$ cat 3.pl 
use strict;
use warnings;

sub test {
    my $num1 = 2;
    my $num2 = 3;

    foreach my $op (qw!+ - * /!) {
        print "$num1 $op $num2 equals ";
        #print eval "$num1 $op $num2", "\n";
        print eval  "$num1 $op $num2", "\n";
    }
}

test()
[oracle@june3 dbi]$ perl 3.pl 
2 + 3 equals 5
2 - 3 equals -1
2 * 3 equals 6
2 / 3 equals 0.666666666666667



               In the second form, the code within the BLOCK is parsed only
               once--at the same time the code surrounding the "eval" itself
               was parsed--and executed within the context of the current Perl
               program.  This form is typically used to trap exceptions more
               efficiently than the first (see below), while also providing
               the benefit of checking the code within BLOCK at compile time.

第2种情况,块内的代码只解析一次,同时围绕着"eval"的代码本身被解析和执行

这种情况通常用于更高效的捕捉异常,也提供了检查代码块在编译事件的好处。



               The final semicolon, if any, may be omitted from the value of
               EXPR or within the BLOCK.


最后的分号,可以从表达式或者代码块省略

               In both forms, the value returned is the value of the last
               expression evaluated inside the mini-program; a return state-
               ment may be also used, just as with subroutines.  The expres-
               sion providing the return value is evaluated in void, scalar,
               or list context, depending on the context of the "eval" itself.
               See "wantarray" for more on how the evaluation context can be
               determined.

所有两种情况,返回值是程序里最后执行表达式返回的值;一个返回状态也被使用,就像子程序。

表达式提供的返回值是计算无效的,变量或者列表上下文。依赖于eval的上下文







               If there is a syntax error or runtime error, or a "die" state-
               ment is executed, an undefined value is returned by "eval", and
               $@ is set to the error message.  If there was no error, $@ is
               guaranteed to be a null string.  Beware that using "eval" nei-
               ther silences perl from printing warnings to STDERR, nor does
               it stuff the text of warning messages into $@.  To do either of
               those, you have to use the $SIG{__WARN__} facility, or turn off
               warnings inside the BLOCK or EXPR using "no warnings 'all'".
               See "warn", perlvar, warnings and perllexwarn.


如果这里有个符号错误或者是runtime错误,或者die语句被执行,一个没有定义的值通过eval返回

   $@ 存储了错误信息,如果没有错误 $@是强制为空字符窜。小心 使用eval 既不打印错误到STDERR 也不将错误写入到$@






               Note that, because "eval" traps otherwise-fatal errors, it is
               useful for determining whether a particular feature (such as
               "socket" or "symlink") is implemented.  It is also Perl’s
               exception trapping mechanism, where the die operator is used to
               raise exceptions.

         因为eval 捕捉另外一些致命的错误,对那些特定的功能包括( "socket" or "symlink")是有效的

也用于Perl捕获异常机制,




               If the code to be executed doesn’t vary, you may use the eval-
               BLOCK form to trap run-time errors without incurring the
               penalty of recompiling each time.  The error, if any, is still
               returned in $@.  Examples:


  如果执行代码没有变化,你可以使用eval块去捕捉运行时候的错误,而不需要每次重复的编译  错误存储到$@

                   # make divide-by-zero nonfatal
                   eval { $answer = $a / $b; }; warn $@ if $@;


                   # same thing, but less efficient
                   eval ’$answer = $a / $b’; warn $@ if $@;


                   # a compile-time error
                   eval { $answer = };                 # WRONG


                   # a run-time error
                   eval ’$answer =’;   # sets $@

               Using the "eval{}" form as an exception trap in libraries does
               have some issues.  Due to the current arguably broken state of
               "__DIE__" hooks, you may wish not to trigger any "__DIE__"
               hooks that user code may have installed.  You can use the
               "local $SIG{__DIE__}" construct for this purpose, as shown in
               this example:

                   # a very private exception trap for divide-by-zero
                   eval { local $SIG{’__DIE__’}; $answer = $a / $b; };
                   warn $@ if $@;

               This is especially significant, given that "__DIE__" hooks can
               call "die" again, which has the effect of changing their error
               messages:

                   # __DIE__ hooks may modify error messages
                   {
                      local $SIG{’__DIE__’} =
                             sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x };
                      eval { die "foo lives here" };
                      print $@ if $@;                # prints "bar lives here"
                   }

               Because this promotes action at a distance, this counterintu-
               itive behavior may be fixed in a future release.

               With an "eval", you should be especially careful to remember
               what’s being looked at when:

                   eval $x;            # CASE 1
                   eval "$x";          # CASE 2

                   eval ’$x’;          # CASE 3
                   eval { $x };        # CASE 4

                   eval "\$$x++";      # CASE 5
                   $$x++;              # CASE 6

               Cases 1 and 2 above behave identically: they run the code con-
               tained in the variable $x.  (Although case 2 has misleading
               double quotes making the reader wonder what else might be hap-
               pening (nothing is).)  Cases 3 and 4 likewise behave in the
               same way: they run the code '$x', which does nothing but return
               the value of $x.  (Case 4 is preferred for purely visual rea-
               sons, but it also has the advantage of compiling at compile-
               time instead of at run-time.)  Case 5 is a place where normally
               you would like to use double quotes, except that in this par-
               ticular situation, you can just use symbolic references
               instead, as in case 6.

               "eval BLOCK" does not count as a loop, so the loop control
               statements "next", "last", or "redo" cannot be used to leave or
               restart the block.

               Note that as a very special case, an "eval ''" executed within
               the "DB" package doesn’t see the usual surrounding lexical
               scope, but rather the scope of the first non-DB piece of code
               that called it. You don’t normally need to worry about this
               unless you are writing a Perl debugger.


1.
eval 这块代码真的诱发了常见错误,就会停止运行,但不至于使程序崩溃.

[oracle@dwh1 dbi]$ cat 1.pl 1.pl 
eval{$var = 2 / 0;
};
print "An error occurred: $@" if $@;
print "bbbb\n";
eval{$var = 2 / 0;
};
print "An error occurred: $@" if $@;
print "bbbb\n";
[oracle@dwh1 dbi]$ perl 1.pl
An error occurred: Illegal division by zero at 1.pl line 1.
bbbb


程序崩溃,下面的没在继续执行


[oracle@dwh1 dbi]$ cat 1.pl 
{$var = 2 / 0;
};
print "An error occurred: $@" if $@;
print "bbbb\n";


[oracle@dwh1 dbi]$ perl 1.pl 1.pl 
Illegal division by zero at 1.pl line 1.


2.

eval 同时也是一个块结构

foreach my $person (qw/fred wilma betty barney dino pebbles/) {
eval {
 open FILE ,"<$person" or die "Can't open file '$person':$!";

my($total,$count);


while (<FILE>) {
$total += $_;
$count++;
}

my $average = $total/$count;
print "Average for file $person was $average\n";

&do_something($person,$average);
print "2-------over\n";
};
if ($@) {
print "An error occurred($@),continuing\n";
 }
print "3-------over\n";
}


如果错误在处理某个文件的时候发生,我们会获得错误信息,不过程序会跳过剩下的步骤,接着处理下一个文件。



[oracle@dwh1 dbi]$ cat 3.pl 
eval{$var = 2 / 1;
    print "\$war is $var\n";
   open FILE ,"aa" or die "Can't open file '$person':$!";
  print "1------test\n";

};
print "An error occurred: $@" if $@;
print "bbbb\n";
[oracle@dwh1 dbi]$ perl 3.pl 
$war is 2
An error occurred: Can't open file '':No such file or directory at 3.pl line 3.
bbbb


eval 程序哪里发生错误,就在哪里停止
























  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Perl语言入门(第五版),本书是为中文版本,英文原版下载地址:http://download.csdn.net/source/2801846。 原书名: Learning Perl, 5th Edition;原出版社: O'Reilly Media, Inc. ;作者: Randal L.Schwartz Tom Phoenix brian d foy;译者: 盛春 蒋永清 王晖;出版社:东南大学出版社 内容简介 《perl语言入门》也就是大家所称道的“小骆驼书”,是perl程序设计人员最为仰赖的启蒙读物之一。自1993年以来,这本书就成为热卖的perl语言教学材料,而此次新版又涵盖了perl 5.10的最新变化。本书的诸位作者自1991年起就开始在stonehenge consulting从事perl教学工作,多年的课堂教学实践和积累下来的点滴经验,形成了本书特有的教学节奏,以及务实的知识点取舍。随文而至的习题,可以让你及时巩固各种概念,强化理解和吸收。本书内容涵盖:. ·perl的变量类型 ·子程序 ·文件的操作 ·正则表达式 ·字符串的操作.. ·列表与排序 ·进程的管理 ·智能匹配 ·第三方模块的使用 有些人只是想要完成任务,perl语言为此而生。perl的最初目标只是为了协助unix系统管理员完成日常繁琐的文本数据处理工作。时至今日,perl已发展成为一套功能齐备的程序语言,几乎可以在任何操作系统上完成各种任务——从简单的命令行工具到web应用开发,及至生物信息学、金融数据分析等等不一而足。其他书籍可能会着重于教会你使用perl语言来编程,可本书不同,我们是想要你成为一名真正的perl程序员。... 目录 前言. 第1章简介 问题与答案 “perl”这个词是什么意思? 如何取得perl? 我该怎么编写perl程序? 走马观花 习题 第二章标量数据 数字 字符串 perl内建警告信息 标量变量 用print输出结果 if控制结构 获取用户输入 chomp操作符 while控制结构 习题 第三章列表与数组 .访问数组中的元素 特殊的数组索引值 列表直接量 列表的赋值 字符串中的数组内插 foreach控制结构 标量上下文与列表上下文 列表上下文中的(stdin) 习题 第四章子程序 定义子程序 调用子程序 返回值 参数 子程序中的私有变量 长度可变的参数列表 关于词法(my)变量 use strict编译命令 return操作符 非标量返回值 持久性私有变量 习题 第五章输入与输出 读取标准输入 钻石操作符输入 调用参数 输出到标准输出 使用printf格式化输出 文件句柄 打开文件句柄 用die处理严重错误 使用文件句柄 复用标准文件句柄 使用say来输出 习题 第六章哈希 什么是哈希? 访问哈希元素 哈希函数 哈希的典型应用 %env哈希 习题 第七章漫游正则表达式王国 什么是正则表达式? 使用简易模式 字符集 习题 第八章以正则表达式进行匹配 以m//进行匹配 可选修饰符 锚位 绑定操作符=~ 模式串中的内插.. 捕获变量 通用量词 优先级 模式测试程序 习题 第九章用正则表达式处理文本 用s///替换 可选修饰符 split操作符 join函数 列表上下文中的m// 更强大的正则表达式 习题 第十章其他控制结构 unless控制结构 until控制结构 条件修饰词 裸块控制结构 elsif子句 自增和自减 for控制结构 循环控制 三目操作符?: 逻辑操作符 习题 第十一章perl模块 寻找模块 安装模块 使用简单模块 习题 第十二章文件测试 文件测试操作符 localtime函数 按位运算操作符 习题 第十三章目标操作 在目录树中移动 文件名通配 文件名通配的另一种语法 目录句柄 递归的目录列表 操作文件与目录 删除文件 重命名文件 链接与文件 建立及移除目录 修改权限 更改隶属关系 修改时间戳 习题 第十四章字符串与排序 在字符串内用index搜索 用substr处理子串 高级排序 习题 第十五章智能匹配与given-when结构 智能匹配操作符 智能匹配操作的优先级 given语句 多个项目的when匹配 习题 第十六章进程管理 system函数 exec函数 环境变量 用反引号捕获输出结果 将进程视为文件句柄 用fork开展地下工作 发送及接收信号 习题 第十七章高级perl技巧 用eval捕获错误 用grep来筛选列表 用map对列表进行转换 不带引号的哈希键 切片 习题 附录a习题解答 附录b超越小骆驼...
perl函数手册英文版 Perl提供了可以直接调用的、数目众多的函数。可以对以下对象进行操作: 数组:chomp, join, keys, map, pop, push, reverse, shift, sort, splice, split, unshift, values 数据库:dbmclose, dbmopen 目录:chdir, closedir, mkdir, opendir, readdir, rewinddir, rmdir, seekdir, telldir 文件:binmode, chdir, chmod, chown, chroot, close, eof, fnctl, fileno, flock, getc, glob, ioctl, link, lstat, open, print, printf, read, readdir, readlink, rename, rmdir, seek, select, stat, symlink, sysopen, sysread, syswrite, tell, truncate, umask, unlink, utime, write 组:endgrent, getgrent, getgrgid, getgrname, getpgrp, setgrent, setpgrp Hash: delete, each, exists, keys, values 主机:endhostent, gethostbyaddr, gethostbyname, sethostent 输入:getc, read, sysread 处理器间通讯:msgctl, msgget, msgrcv, msgsnd, pipe, semctl, semget, semop, shmctl, shmget, hmread, shmwrite 数学:abs, atan2, cos, exp, hex, int, log, oct, rand, sin, sqrt, srand 消息队列:msgctl, msgget, msgrcv, msgsnd 其他:bless, defined, do, eval, formline, import, ref, scalar, syscall, tie, tied, undef, untie, wantarray 网络:endnetent, getnetbyaddr, getnetbyname, getnetent, setnetent 输出:die, print, printf, syswrite, warn, write 口令:endpwent, getpwent, getpwname, getpwuid, setpwent 进程:alarm, die, dump, exec, exit, fork, getlogin, getpgrp, getppid, getpriority, kill, setpriority, sleep, system, times, umask, wait, waitpid 协议:endprotent, getprotobyname, getprotobynumber, getprotoent, getservbyname, getservbyport, getservent, setprotoent 正则表达式:grep, pos, quotemeta, reset, split, study 范围:caller, local, my 服务:endservent, getservbyname, getservbyport, getservent, setservent 套节字:accept, bind, connect, gethostbyaddr, gethostbyname, gethostent, getpeername, getservbyname, getservbyport, getservent, getsockname, getsockopt, listen, recv, select, send, setsockopt, shutdown, socket, socketpair 字符串:chop, chr, crypt, hex, index, join, lc, lcfirst, length, oct, Ord, pack, q, qq, quotemeta, qw, qx, reverse, rindex, split, sprintf, substr, uc, ucfirst, unpack, vec 时间:gmtime, localtime, time UNIX: chmod, chown, chroot, dump, endgrent, endhostent, endnetent, endprotent, endpwent, endservent, fnctl, fork, getgrent, getgrgid, getgrname, gethostent, getlogin, getnetent, getpgrp, getppid, getpriority, getprotobyname, getprotobynumber, getprotoent, getpwent, getpwname, getpwuid, getservbyname, getservbyport, getservent, ioctl, link, lstat, readlink, select, setgrent, sethostent, setnetent, setpgrp, setpriority, setprotoent, setpwent, setservent, sleep, syscall, times, umask, wait, waitpid

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scan724

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值