最近の記事
- 9/1 - 将棋始めました
- 5/16 - サーバー引っ越し
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
Entering Passive Mode
では、シンボルテーブルからコードを検索してみよう。
例えば、Carp のシンボルテーブルを調べてみる。
use Carp;
まずはシンボルテーブルを取得する。
my $package = 'Carp';
no strict 'refs';
my $symbol_table = \%{"${package}::"};
use strict 'refs';
今後のために、シンボリックリファレンスを使って、
シンボルテーブルを取得してみた。
シンボルテーブルは連想配列であるので、
each を使えば中身を列挙できる。
while ( my ($key, $value) = each %$symbol_table) {
# シンボルごとの処理。
}
シンボルテーブルの中身は、原則として型グロブである。
関数のプロトタイプとの兼ね合いで、例外もありえるので、
型グロブであるかどうか調べる必要がある。
# 型グロブでない場合は抜ける。
next if ref \$value ne 'GLOB';
型グロブが見つかった場合、コード用のスロットを調べる。
メソッドや関数があれば、リファレンスが格納されている。
逆に定義されていなければ、undef となる。
# コードが格納されていなければ抜ける。
next if not defined *$value{'CODE'};
コードリファレンスが取れれば、メソッドが定義されている。
見つかったメソッドを画面に出力してみよう。
# 名前を出力。
print "\&$key\n";
では、上記をまとめてテストしてみよう。
========== dumpcode.pl ==========
use strict;
use warnings;
use Carp;
sub dump_code {
my $package = $_[0];
no strict 'refs';
my $symbol_table = \%{"${package}::"};
use strict 'refs';
while ( my ($key, $value) = each %$symbol_table) {
next if ref \$value ne 'GLOB';
next if not defined *$value{'CODE'};
print "\&$key\n";
}
}
dump_code('Carp');
========== end of dumpcode.pl ==========
$ perl ./dumpcode.pl
&export_fail
&shortmess
&longmess
&croak
&confess
&carp
&cluck
俺の環境ではこのようになった。
コメント (0 件)