miau's blog?

Devel::Calltree つづき

関数一覧の出力にはあっさり成功したわけですが、いくつかつまづいてたのでメモがてら。


■出力フォーマットの変更

Devel/Calltree.pm を参考に、

sub Devel::Calltree::print_report {
:
(なんか色々処理)
:
}

1;


みたいなファイルを作っておいて、たとえば print_report.pl として保存。

で、calltree --reportfunc print_report.pl hoge.pl みたいな感じで呼び出し。


■対象ファイル名の取得

サクラエディタでタグジャンプが使えるように、

<ファイル名>(<行数>) <関数名>


みたいな形式で出力したかったんだけど、print_report() 内でファイル名を取得するのは無理っぽい。
ので暫定的に "$SCRIPT" とかいう文字を出力して、外部から置換することに。


■メソッドのクラス名取得

たとえば get() なんてメソッドを呼び出した場合、どのクラスに対するメソッドを呼び出したのかはわからないらしい。
B::Concise とか使って op-tree とか眺めてみたけど、簡単には解決できなっぽい。
# まぁ私がちょっと見ただけで解決できるようなら、作者の人がちゃんと対応してるでしょうね・・・

まぁこの問題は ToDo か何かに書いてあったので、次のバージョンに期待しよう。


でもとりあえず暫定措置として、ソースコードを適当に解析することに。

(1) メソッド名が new() の場合、その結果がどの変数に出力されたかを記憶
(2) $hoge->get() 等の処理を見つけたら、(1) で記憶した変数名からクラス名を解決

という流れで。

まぁ最終的にはある程度解決できたけど、$hoge->fuga->get() とかなってた場合に fuga() がどんな型を返すかわからないので、これはルールを記述することに。


■拡張正規表現

上のソースコード解析で、jcode("ほげ")->euc みたいのも解析できるようにしてたんですが。
jcode(hoge('aaa'))->euc みたいにネストされてると、一筋縄ではいかないわけで。

このへんが腕の見せ所だなー、ということで拡張正規表現とか使おうとしてたんですが、色々忘れてたのでメモ。

# ネストされた括弧にマッチする正規表現
no strict "vars";
my $paren =qr/
\(
(?:
(?> [^()]+ ) # 括弧以外。パフォーマンスの都合で強欲マッチ
|
(??{ $paren }) # 括弧部分。再起的に適用
)*
\)
/x;
use strict "vars";


この正規表現自体は perlre にも載ってるようなものなので置いといて。
use strict "vars" を一時的に解除する必要があるのを忘れてた。

あと、上のを使って

$source =~ m/$paren/;           # 関数の呼び出しのパラメータっぽいのにマッチ


とかだとちゃんと jcode(hoge('aaa')) の (hoge('aaa')) 部分にマッチするくせに

$source =~ s/$paren/()/;    # パラメータは邪魔なので削除


だと、なぜか jcode(hoge('aaa')) の ('aaa') 部分にマッチしてしまうらしい。
(結果的に jcode(hoge()) なんてのが得られる)
"(??{〜})" が展開された時点で置換の範囲って変わってしまうんだっけ?

とりあえず、

$source =~ s/([^(]*)$paren([^)]*)/$1()$2/;    # パラメータは邪魔なので削除


とやって回避。

たぶんこのへんの問題って詳説正規表現に載ってたんだろうけど・・・忘れてるなぁ。
posted at 20:13:09 on 2005-01-28 by miau - Category: Perl No Trackbacks - Permalink

TrackBack

このエントリにトラックバックはありません
現在トラックバックは受け付けていません。

Comments

No comments yet

Add Comments

現在コメントは受け付けていません。
お手数ですが、 こちら のコメント欄にでも記載していただければと思います。