根據 perldoc,應該在當前范圍內執行 String Eval。但下面的簡單測驗似乎與此相矛盾。
我們需要以下兩個簡單的檔案來設定測驗。請把它們放在同一個檔案夾下。
test_eval_scope.pm
package test_eval_scope;
use strict;
use warnings;
my %h = (a=>'b');
sub f1 {
eval 'print %h, "\n"';
# print %h, "\n"; # this would work
# my $dummy = \%h; # adding this would also work
}
1
test_eval_scope.pl
#!/usr/bin/perl
use File::Basename;
use lib dirname (__FILE__);
use test_eval_scope;
test_eval_scope::f1();
當我運行程式時,出現以下錯誤
$ test_eval_scope.pl
Variable "%h" is not available at (eval 1) line 1.
我的問題是為什么變數 %h 超出了范圍。
我做了一些修改,發現以下內容:
- 如果我在沒有 eval() 的情況下運行,就像上面的評論一樣,它將起作用。這意味著 %h 應該在范圍內。
- 如果我只是在代碼中添加一個看似無用的提及,如上面的注釋, eval() 也將起作用。
- 如果我將 pl 和 pm 檔案合并為一個檔案,則 eval() 也將起作用。
- 如果我用 'our' 而不是 'my' 宣告 %h,eval() 也將起作用。
我在撰寫一個在運行時決議用戶提供的代碼的大程式時遇到了這個問題。我不需要解決方案,因為我上面有很多解決方法。但我無法解釋為什么上面的代碼不起作用。這影響了我的 perl 自豪感。
我的 perl 版本是 linux 上的 v5.26.1。
感謝您的幫助!
uj5u.com熱心網友回復:
Subs 只捕獲他們使用的變數。由于f1不使用%h,它不會捕獲它,并且當模塊完成執行時它超出范圍后變得不可訪問。
對 var 的任何參考,包括優化掉的參考,都會導致 sub 捕獲該變數。因此,以下確實有效:
sub f1 {
%h if 0;
eval 'print %h, "\n"';
}
演示:
$ perl -M5.010 -we'
{
my $x = "x";
sub f { eval q{$x} }
sub g { $x if 0; eval q{$x} }
}
say "f: ", f();
say "g: ", g();
'
Variable "$x" is not available at (eval 1) line 1.
Use of uninitialized value in say at -e line 8.
f:
g: x
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/316244.html
上一篇:迭代多級哈希
