perl eval

eval  表達式:

eval 塊:

eval

在第一種形式,一般稱爲一個字符串eval 

EXPR 返回值是被解析的和被執行的做爲一個小小的Perl程序。

表達式的值(是它自己決定的在標量上下文環境)是有限被解析,

若是這裏沒有錯誤,做爲一個block執行在當前Perl程序的詞法上下文。


這意味着,特別狀況下, 任何外部的詞法變量時可見的,任何包變量設置或者子函數和

格式定義 以後仍舊存在

注意 eval執行值是每次都被解析的, 若是EXPR 被省略, 評估$_.


這種形式是典型的用於延遲解析。

若是unicode_eval 功能是被啓用( 默認是在5.16或者更多的版本)

EXPR 或者$_ 是做爲一個字符串,所以 use utf8 聲明沒有影響,

源過濾器是被禁止的。

在沒有unicode_eval的功能下,

字符串有時候回對待爲 字符和做爲字節,

取決於內部編碼,源過濾器激活eval 展示不穩定,


若是字符串擴展一個標量包含一個浮點數.

標量可能擴展爲字母,好比  "NaN" or "Infinity"


在一個use locale的範圍內.

第2中形式中, BLOCK裏的代碼只被解析一次,在同一時間圍繞代碼

eval自己是被解析-- 被執行在當前的Perl程序的上下文。

這種形式一般用來捕獲異常。

最後的分號,若是有的話,能夠從EXPR的值或者BLOCK裏省略


在這兩種形式中, 返回值是最後一個表達式計算的值,

一個return語句也可使用,就像在子函數裏。

表達式提供的返回值是計算爲空白的,標量,或列表上下文,

依賴eval 自己的列表上下文。



若是有一個語法錯誤或者運行時錯誤,或者一個"die" 語句被執行,

"eval" 返回undef 在標量上下文環境或者一個空的列表在列表環境,

$@是存放錯誤信息的。(在5.16以前,一個bug 致使"undef" 被返回在列表上下文對於符號錯誤,

可是不是運行錯誤)
.

若是沒有錯誤, $@是空的字符串。 一個控制流操做像 "last" 或者"goto" 

能夠繞過$@設置。


要注意的是,使用"eval" 不會沉默perl輸出警告道STDERR,

也不會把警告信息塞到$@.


須要注意的是,由於"eval" 捕獲其餘致命的錯誤, 它是有用的對於肯定某個特性(好比 做爲socket或者symlink)

是被實現。



若是你想要捕獲錯誤 當加載一個XS模塊, 一些2進制接口的問題(好比Perl 版本傾斜)

多是致命的  甚至是"eval" 除非$ENV{PERL_DL_NONLAZY} 被設置




若是要執行的代碼並無不一樣, 你可能使用eval-BLOCK 從一個捕獲運行錯誤的而不招致

每次從新編譯的處罰  錯誤,若是有的話,仍舊返回在$@


 # 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 $@

[root@wx03 test]# cat a1.pl
   eval { $answer = $a / $b; }; warn $@ if $@;

[root@wx03 test]# perl a1.pl 
Illegal division by zero at a1.pl line 1.



使用 "eval{}"的形式做爲一個異常捕獲器在libararies 有一些問題。

因爲當前的說的破碎的狀態(__DIE__)  

你可能但願不要觸發 any "__DIE__" hooks


#一個私有的理財捕獲 對於除以0

[root@wx03 test]# cat a2.pl 
    eval { local $SIG{'__DIE__'}; $answer = $a / $b; };
                warn $@ if $@;
[root@wx03 test]# perl a2.pl 
Illegal division by zero at a2.pl line 1.


這是很是重要的,給定的 "__DIE__" hooks 也被稱爲die, 這有可能改變它們的錯誤消息

[root@wx03 test]# cat a3.pl 
  # __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"
                }
[root@wx03 test]# perl a3.pl 
bar lives here at a3.pl line 5.






相關文章
相關標籤/搜索