togatttiのエンジニアメモ

過度な期待はしないでください.

Perlでデバッグ時に変数名と値を同時に出力する

変数をデバッグする時に、複数の値を一度に確認したい。

そういうときに、変数名と値がセットになっている分かりやすい。

いい方法を探していたら、Data::Dumper::Namesというモジュールがあったので、メモしておく。

Data::Dumper::Names - search.cpan.org

準備

標準のperlモジュールではないので、cpanmで入手する。

$ cpanm Data::Dumper::Names
使い方

モジュールをuseして、Dumperするだけでいい。

use Data::Dumper::Names;

my $hoge = 'hoge';
my @fuga = qw/fuga1 fuga2/;
my %foo = qw/status 1/;
print "[DEBUG]:" . Dumper $hoge;
print "[DEBUG]:" . Dumper \@fuga;
print "[DEBUG]:" . Dumper \%foo;

出力はこんな感じになる。

[DEBUG]:$hoge = 'hoge';
[DEBUG]:@fuga = (
          'fuga1',
          'fuga2'
        );
[DEBUG]:%foo = (
         'status' => '1'
       );

サブルーチン内で、呼び出すときは、$Data::Dumper::Names::UpLevelをlocalで指定する必要がある。

何も指定しない場合、$Data::Dumper::Names::UpLevelは1となる。

例えば、デバッグ用関数を作るときは、こんな感じに書く。

sub _dump {                                                                     
    local $Data::Dumper::Names::UpLevel = 2;
    print "[DEBUG]:\n" . Dumper(@_);
}

my $hoge = 'hoge';
my @fuga = qw/fuga1 fuga2/;
my %foo = qw/status 1/;

_dump($hoge,\@fuga,\%foo);

出力すると、

[DEBUG]:
$hoge = 'hoge';
@fuga = (
          'fuga1',
          'fuga2'
        );
%foo = (
         'status' => '1'
       );

$Data::Dumper::Names::UpLevelはネスト度合いに応じて、 調整する必要があるので、思ったような結果が得られないときは、うまく指定する。

例えば、次の例では_dumpに_dump2で渡された変数を@_に格納して、又渡ししている。

この場合、先ほどと同じ設定では、期待した出力がでない。

use Data::Dumper::Names;

sub _dump {
    local $Data::Dumper::Names::UpLevel = 2;
    print "[DEBUG]:\n" . Dumper(@_);
}

sub _dump2 {
    _dump(@_);
}

my $hoge = 'hoge';
my @fuga = qw/fuga1 fuga2/;
my %foo = qw/status 1/;
_dump2($hoge,\@fuga,\%foo);

出力すると、$VAR1,$VAR2,$VAR3となる。

[DEBUG]:
$VAR1 = 'hoge';
$VAR2 = [
          'fuga1',
          'fuga2'
        ];
$VAR3 = {
          'status' => '1'
        };

このときは$Data::Dumper::Names::UpLevelを一つ増やすとうまくいく。

# local $Data::Dumper::Names::UpLevel = 2;
local $Data::Dumper::Names::UpLevel = 3; 
まとめ

Data::Dumper::Namesを使う際には、変数名が分かる形でDumperに渡されているかどうかが鍵となる。

また、うまくいかないときは$Data::Dumper::Names::UpLevelを指定することで、よしなに出力できる ようになることも覚えておく。

参考:

[Perl] 引数の名前を知る方法 Data::Dumper::Names - harupiyoの日記

Data::Dumper::Names - search.cpan.org