« Markapl - Mark up as Perl. | Home | Binding.pm implemented »

December 29, 2008

實做 Binding.pm

下午連續喝了三杯之前在菡萏買的 Espresso 綜合豆,雖然有點小過期,帶點雜味,但是仍然是酸勁十足。

結論:動態語言果然好玩。

之前在寫 Markapl 的時候,曾經需要解這這個問題:

執行以下這段程式時:

eval 'my @attr = ($x, $y)';

如何使其中 $x$y 的的值,參照到 caller 之中的同名變數。

換同話說,如何實做出以下這段程式中的 caller_eval 函式:

sub x_add_one {
    caller_eval '$x + 1';
}

sub ans {
    my $x = 41;
    x_add_one;
}

print ans; #42

實際上在 Markapl 中碰到的狀況比較廣泛一些,但是只要寫出這裡的 caller_eval 函式,就可以一併解決。今天則是把這個做法整理成一個單 獨的模組,也就是 Binding.pm。

在其他動態語言中,能同樣解決這個問題的,有 Tcl 的 uplevel 函式,以及Ruby 中的 Binding.of_caller 方法。

我實際上實做的用法是參照 Ruby 的 Binding 類別,提供了 Binding.pm 模組,用法如下:

my $binding = Binding->of_caller;
$binding->eval('$x + 1');

這些例子都算是比較特例,因為傳給 eval 的程式碼中實際寫了會用到的變 數 $x,在 Markap 的例子裡,變數名稱也是個變數,因此才會需要通用 的解法。

實際的做法是利用 PadWalker 的 peek_my 加上 Data::Dump 的 pp 函式將 上層的變數值複製一份下來。不算是個很漂亮的解法,但總算是個方法。

目前還沒實作完成,但可以嘗試看看的目標還有:

  • Binding->of_package
  • Binding->of_sub
  • Binding->local

可以想見的是,這些都有些難度,也不見得會很有用。完全是屬於實驗或研 究性質的作品。不過接著便可以在 Rubyish 中直接使用 Binding.pm 了。

這個作品的初版已經上傳到 CPAN: http://search.cpan.org/dist/Binding/ , 版本控制則是放在 github 上: http://github.com/gugod/binding/tree/master , 敬請賜教。

1 TrackBack

TrackBack URL: http://chupei.pm.org/mt/mt-tb.cgi/522

下午連續喝了三杯之前在菡萏買的 Espresso 綜合豆,雖然有點小過期,帶點雜味,但是仍然是酸勁十足。 結論:動態語言果然好玩。 之前在寫 Markapl 的時候,曾經需要解這這個問題: 執行以下這段程式時: eval 'my @attr = ($x, $y)'; 如何使其中 $x 與 $y 的的值,參照到 caller 之中的同名變數。 閱讀全文 (link to chupei.pm.org)... Read More

Leave a comment

Pages

OpenID accepted here Learn more about OpenID

About this Entry

This page contains a single entry by gugod published on December 29, 2008 3:42 AM.

Markapl - Mark up as Perl. was the previous entry in this blog.

Binding.pm implemented is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.