我有一段通過字串處理形成的代碼,我試圖運行一個eval來捕獲代碼的輸出到另一個字串。這段代碼本身是由一些步驟形成的,這意味著它不在Perl程式的主體中,而是在一塊。這就是為什么我使用eval.
。我試著使用Tiny::Capture,但沒有使用capture、capture_merged、capture_stdout,也沒有使用Safe與Safe-> new-> reval()。
use strict;
use warnings;
使用 Capture::Tiny 'capture'。
use Capture::Tiny 'capture_stdout';
使用 Capture::Tiny 'capture_merged'。
# $num_loops被定義在主代碼體中。
my $num_loops = 10;
#在現實中,新代碼是通過一系列的步驟形成的。
my $new_code = "foreach $idx (0..$num_loops-1) {print "I am at iteration number $idx
";}"。
my $out = capture_merged {eval $new_code;};
print $out;
我使用的是Perl 5.30.
。上面這段代碼并沒有列印出任何東西。它也沒有在日志中列印任何錯誤。我已經在原始代碼中給出了中間列印,以確保扔進 eval 的字串有真正的代碼,所以這不是一個問題。
上述代碼中的問題是什么呢?
uj5u.com熱心網友回復:
檔案的撰寫是有原因的,你不應該假設函式的回傳值 -- 檔案給出了什么是回傳值的細節。
在你的情況下如何使用eval的示例代碼。
use strict;
use warnings;
my $num_loops = 10;
my $new_code = '
我的$r;
$r .= "我在迭代數$_的地方
" for 0...$num_loops-1;
回傳 $r;
'。
my $out = eval $new_code;
print $out;
輸出
我在迭代數0。
我在迭代數1。
我在迭代次數2。
我在迭代數3。
我在迭代數4。
我在迭代數5。
我在迭代數6。
我在迭代數7。
我在迭代數8。
我在迭代數9。
uj5u.com熱心網友回復:
如果我理解正確的話,你想做的事情和
一樣$var = `... commands ...`。
$var = qx(. commands ...)。
但是commands是perl而不是shell代碼,并且沒有分叉一個單獨的行程。
你可以通過本地化STDOUT和重新打開本地檔案柄作為一個記憶體檔案來實作。
簡單的例子,沒有任何外部模塊:
use strict;
sub qp(&){
my $s;
open local *STDOUT, '> ', $s or die "open in-memory file: $!"。
&{$_[0]}。
die $@ if $@;
$s;
}
# Usage:
my $a = qp { eval 'print "in"'/span> };
print "<$a>
"。
print "out
"。
# 'in'將進入字串,'out'將進入實際的stdout。
# 與你的例子一起使用(固定使用'my $idx'):。
my $num_loops = 10;
my $new_code = "foreach my $idx (0..$num_loops-1) {print "I am at iteration number $idx
";}"。
my $out = qp { eval $new_code };
print $out;
這樣做的局限性在于
syswrite輸出 -- 這可以通過tie本地化的STDOUT和實作PRINT、PRINTF和WRITE追加到一個字串來輕松解決。
STDOUT到一個臨時檔案來解決(這就是Capture::Tiny的作用)。
為什么你的例子不起作用
在你的評估代碼中,你使用了foreach $idx (...)而沒有定義$idx,由于你在use strict的范圍內,這就出錯了,你的代碼沒有被運行。但是你沒有檢查$@的值,所以你無法看到這個錯誤。把它改為foreach my $idx (...),就像我上面做的那樣。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/311354.html
標籤:
