kiyo_hikoのブログ

メモ+日記?

Perl: Net::FTP使ったコードをデバッグしたくて引数全部printするラッパ書いた

PerlのNet::FTPモジュールをラップして、メソッドを呼ぶごとに引数をプリントアウトするクラス書きました。

  • デバッグによいかも。
  • 別にFTPに限る必要はなくて、少し直せば他でもバンバン使えるはず。

あとAUTOLOADを少し勉強しました。

コード

{ package FtpDebug;
    use Net::FTP qw//;
    sub new {
        my $this = shift;
        bless { me => Net::FTP->new(@_) }, $this;
    }
    sub AUTOLOAD {
        my $this = shift;
        our $AUTOLOAD;
        my $method = (split /::/, $AUTOLOAD)[-1];
        # 次の行はお好みでファイルに出すとかカスタマイズ
        print "Calling method $method (", join(', ', @_) . ")\n";
        $this->{me}->$method(@_);
    }
    sub DESTROY {}
}

使い方

  1. クラスを読める位置にコピペするか、useできる場所にpm切ります。
  2. Net::FTPを使ったコードでnew Net::FTPまたはNet::FTP->newしているところをFtpDebug->newで置き換えます。
  3. 置き換えたコードでFTPのメソッドを呼ぶたびに引数がプリントアウトされます。

AUTOLOAD要点

  • Perlで未定義のメソッド呼ぶとこれが呼ばれるらしい?
  • sub AUTOLOADで書いて中にグローバル変数our $AUTOLOAD書くとFQNでメソッド名が得られる。
    • 上記コードでは、FQNそのまま呼ぶとDeep Recursionになってよくないのでsplitして最終要素取っている。
  • そのままではDESTROYというメソッドもこれに捕まってしまうので、空メソッドとして定義する必要がある。
    • なおDESTROYはPerlシステムの処理なので通常深入りしない
      • (参照カウンタが0になってオブジェクトが消滅するときに自動で呼ばれる処理)

なぜ作ったか、あるいはタダの愚痴

クソ長いメソッド書いたPerlで、$workFileだのftpDataDirだの妙に抽象的な変数名使ってるわ、 逆に処理手順はファイルをカウントアップとかやたら具体的で全体で何をするかという抽象が書かれてない。 そんなクソコードとの出会いがあり、怒りに震えてました。

  • 変数名は具体的に、処理は抽象的なのが俺が思うよいコードです。これでは俺の理想と真逆です。

で突然「あれ?コードがわかんなきゃとにかく全部プリントアウトすりゃいいんじゃね?」という発想が浮かんで作った。
クソコードとの出会いは案外多いから会っても泣かないために、これからもクソコードを力で殴るコード書きたいです。