デバッグの目的で、特定の属性セットを使用してさまざまなサブルーチンのレキシカル スコープにアクセスしたいと考えています。それはうまくいきます。最初の変数が文字列を格納すると問題が発生し、その後空の文字列が返されます。私はこのようなことをします:
$pad = $cv->PADLIST; # $cv is the coderef to the sub
@scatchpad = $pad->ARRAY; # getting the scratchpad
@varnames = $scratchpad[0]->ARRAY; # getting the variablenames
@varcontents = $scratchpad[1]->ARRAY; # getting the Content from the vars
for (0 .. $#varnames) {
eval {
my $name = $varnames[$_]->PV;
my $content;
# following line matches numbers, works so far
$content = $varcontent[$_]->IVX if (scalar($varcontent[$_]) =~ /PVIV=/);
# should match strings, but does give me undef
$content = B::perlstring($varcontent[$_]->PV) if (scalar($varcontent[$_]) =~ /PV=/);
print "DEBUGGER> Local variable: ", $name, " = ", $content, "\n";
}; # there are Special vars that throw a error, but i don't care about them
}
コメントで言ったように、eval はスクラッチパッドの B::Special オブジェクトからのエラーを防ぐことです。出力:
Local variable: $test = 42
Local variable: $text = 0
最初の出力は問題ありません。2 番目は 0 ではなく "TEXT" を出力する必要があります。
私は何を間違っていますか?
編集:少しのコーディングで、変数のすべての値を取得しましたが、@varnames と @varcontents の同じインデックスには保存されませんでした。では、値が @varcontents にどのように (どの順序で) 格納されるかが問題になります。
use strict;
use warnings;
use B;
sub testsub {
my $testvar1 = 42;
my $testvar2 = 21;
my $testvar3 = "testval3";
print "printtest1";
my $testvar4 = "testval4";
print "printtest2";
return "returnval";
}
no warnings "uninitialized";
my $coderef = \&testsub;
my $cv = B::svref_2object ( $coderef );
my $pad = $cv->PADLIST; # get scratchpad object
my @scratchpad = $pad->ARRAY;
my @varnames = $scratchpad[0]->ARRAY; # get varnames out of scratchpad
my @varcontents = $scratchpad[1]->ARRAY; # get content array out of scratchpad
my @vars; # array to store variable names adn "undef" for special objects (print-values, return-values, etc.)
for (0 .. $#varnames) {
eval { push @vars, $varnames[$_]->PV; };
if ($@) { push @vars, "undef"; }
}
my @cont; # array to store the content of the variables and special objects
for (0 .. $#varcontents) {
eval { push @cont, $varcontents[$_]->IV; };
eval { push @cont, $varcontents[$_]->PV; };
}
print $vars[$_], "\t\t\t", $cont[$_], "\n" for (0 .. $#cont);
EDIT2: 問題を示すために実行可能なスクリプトを追加しました: Variablenames と variablevalues は、2 つの配列 (@varnames と @varcontents) の同じインデックスに保存されません。