zoukankan      html  css  js  c++  java
  • 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", "
    ";
            print  "$num1 $op $num2", "
    ";
        }
    }
    
    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", "
    ";
            print eval  "$num1 $op $num2", "
    ";
        }
    }
    
    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
    ";
    eval{$var = 2 / 0;
    };
    print "An error occurred: $@" if $@;
    print "bbbb
    ";
    [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
    ";
    
    
    [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
    ";
    
    &do_something($person,$average);
    print "2-------over
    ";
    };
    if ($@) {
    print "An error occurred($@),continuing
    ";
     }
    print "3-------over
    ";
    }
    
    
    如果错误在处理某个文件的时候发生,我们会获得错误信息,不过程序会跳过剩下的步骤,接着处理下一个文件。
    
    
    
    [oracle@dwh1 dbi]$ cat 3.pl 
    eval{$var = 2 / 1;
        print "$war is $var
    ";
       open FILE ,"aa" or die "Can't open file '$person':$!";
      print "1------test
    ";
    
    };
    print "An error occurred: $@" if $@;
    print "bbbb
    ";
    [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 程序哪里发生错误,就在哪里停止
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

  • 相关阅读:
    FPGA开发全攻略——FPGA选型
    FPGA开发全攻略——FPGA开发基本流程
    希尔伯特变换的物理意义
    无线通信方式
    FPGA DDR3调试
    FPGA调试光纤模块
    FPGA FIFO深度计算
    Xilinx FPGA LVDS应用
    电源设计注意事项
    波特图与零极点
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13351877.html
Copyright © 2011-2022 走看看