Acme::Don't 2.0 Bモジュールで覗くPerlの深淵 Goro Fuji gfx at Hatena GFUJI at CPAN http://d.hatena.ne.jp/gfx/20080929/1222669383より use Acme::Don't 2.0; #!perl -w use Acme::Don't 2.0; use feature 'say'; don't { say "don't"; don't { say "done!"; }; say "don't"; }; # => done! use B; B - The Perl Compiler Bモジュールの機能 SV構造体にアクセス Sub::Identify OP構文木にアクセス B::Deparse SV構造体 = Perlデータオブジェクト Perlのデータは全てSVとして表現される $foo #SV # # # #}; = 10; = { refcount => 1, flags => IOK, # Integer OK int_value => 10, SV構造体のプロパティ スカラー IV(整数) PV(文字列) などなど $foo = Scalar::Util::dualvar(42, "foo") #SV = { # refcount => 1, # flags => (IOK | POK), # int_value => 42, # ptr_value => "foo", #}; CV = Code ValueもSVの一種 コードリファレンスが参照しているもの Perlレベルからはアクセスできない 参照できるプロパティはそのアドレスだけ しかし,有用なプロパティも沢山ある CvGV - 型グロブ(たとえば*main::f) そこでBモジュールですよ! Bモジュールの使用例 Sub::Identify package Sub::Identify; # 単純化してあるものの,大体こんな感じ # GV->STASH は GVの所属するSymbol Table Hash # (*glob{PACKAGE}のようなもの) # GV->NAME は *glob{NAME}と同じ sub get_code_info{ my $code_ref = shift; my $cv = B::svref_2object(\&{$code_ref}); my $gv = $cv->GV; return ($gv->STASH->NAME, $gv->NAME); } OP構文木 = OP構造体のツリー Perlの構文木にアクセスする機能を提供する B - Perl Compiler Backend B::*モジュール群が代表的 B::Deparse B::Concise B::Lint Acme::Don't 2.0もこの機能を使っている Acme::Don't 2.0のメカニズム don't{ ... } = &don::t(sub{ ... }) この呼び出しに相当する構文木を単純化すると: entersub (上の娘たちを引数に末娘を呼び出す) ├refgen (娘SVのリファレンスを生成) │ └anoncode (無名サブルーチンの実体を参照) └gv[*don::t] (*dont::tを参照) (実行順:anoncode -> refgen -> gv -> entersub) そこで,まずrefgenを探し,妹がgv[*don::t]だったら refgenの娘のanoncodeを実行する まとめ Bモジュールは二つの機能がある SV構造体へのアクセス OP構文木へのアクセス 構文木へアクセスすると サブルーチンを実行せずに中身を調べられる 特定のシンボルを探したり 特定の制御構造を探したり サブルーチンの「大きさ」を調べたり cf. PPI ご清聴ありがとうございました お招きいただいたTAKESAKOさんに感謝し ます。 Acme::Don'tを書くきっかけになったもの Shibuya.pm #9 tokuhirom氏のLT (autobox, Perl VM Golf) stanaka氏のLT (GDB for Perl)
© Copyright 2024 ExpyDoc