最近perlのスタッシュと言う単語を覚えました。所謂パッケージスコープのシンボルテーブルで特定のパッケージ内に定義されている関数や変数の情報を得る事が出来ます。詳細は以下のページが解り易かったです。
さて問題は何かというと、上記ページにも書かれているように、my変数がスタッシュではなく、別のスクラッチパッドと呼ばれる領域に格納されるため、スタッシュからはアクセスできないという事です。
定義されているmy変数のリストも取得したいと思い調べてみると、PadWalkerというモジュールに行き着きました。このモジュールを使うと、なんとスクラッチパッドの読み書きが出来ます。例えば以下のようにして使用します。
#!/usr/bin/perl use strict; use warnings; use PadWalker qw(peek_my peek_our); use Data::Dumper; my $scalar = "hello"; my @list = (1,2,3); our %hash = (item1 => 'val1', item2 => 'val2'); print Dumper peek_my(0); # このスコープで定義されているmy変数のハッシュを見る print Dumper peek_our(0); # our変数を見る事も出来る # ハッシュ経由で変数を弄る事も出来る ${peek_my(0)->{'$scalar'}} .= " world"; print $scalar . "\n"; # hello world
上記プログラムのpeek_my(0)のダンプ結果は以下のようになります。ばっちり思った結果が得られていますね。
$VAR1 = {
'$scalar' => \'hello',
'@list' => [
1,
2,
3
]
};これでスタッシュ経由でグローバル変数、スクラッチパッド経由でmy変数を、それぞれハッシュで得られるようになりました。だから何だという話もありますが、僕はperlのビギナーなので、Cやjavaの感覚でperlのプログラムを書いて、挙動が思ったようにならない事がよくあります。そんな時にシンボルテーブルどうなってるの?と確認できるのは結構便利です。ここ数時間あれこれダンプしすぎて作業が進みませんが。。
さておまけですが、このPadWalkerを使うと別のスコープのmy変数にアクセスできます。
sub modify_var { my $var_name = shift; # peek_my(1)で一つ上のスコープのスクラッチパッドにアクセスできる。 ${peek_my(1)->{$var_name}} = "modified"; } my $data = 'new data'; modify_var('$data'); print $data . "\n"; # modified
こんな事されるとレキシカルスコープ危うしですね。使い道も今のところ思いつきません。

