szabgab has asked for the wisdom of the Perl Monks concerning the following question:

I've been playing with some of the Devel::* modules lately. I came arross Devel::Carnivore. Here is a small example I put together:
use strict; use warnings; use Devel::Carnivore; my $h; { my %h : Watch('%h'); $h{fname} = "Foo"; $h = \%h; } $h->{lname} = 'Bar'; unwatch $h; $h->{email} = 'foo@bar.com';
and the output:
$perl carnivore.pl # variable is now under observation > %h: "fname" changed from "" to "Foo" at carnivore.pl line 10 > %h: "lname" changed from "" to "Bar" at carnivore.pl line 13 # mission completed
I have several comments: - When we start and stop watching I would like to see the name we assigned to the variable, better yet I'd like to see the real variable name. I would like to be able to control the watching from the outside world. e.g. in .carnivore I would like to say something like script.pl:37:watch %h; so I can run perl -d:Carnivore script.pl and %h will be watched from line 37 of the script.pl file Any idea if I can do this with another module? Maybe with the debugger?

Replies are listed 'Best First'.
Re: debugging: tracing changes to hashes
by shmem (Chancellor) on Nov 20, 2006 at 09:32 UTC
    So you want to tell Carnivore beforehand which variable is watched, and from which line onwards?

    I guess that would not need another module, but the introduction of major changes to Canivore, e.g. one or more of the following

    • store variable / line-number pairs passed as arguments to Devel::Carnivore::import() in a package hash for lookup
    • use source filtering to insert watch hooks at those lines (before or after that line?) without adding new lines to the file
    • check for the line number in STORE whether the line number caller() reports is in the desired range

    The above are just some rough ideas I would try to implement, maybe there are other (and better) ways. Have a look at Filter::Util::Call for source filtering and e.g. Spiffy for a usage example.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Automating the debugger with Devel::Carnivore
by pemungkah (Priest) on Nov 20, 2006 at 21:30 UTC
    You can stack the necessary commands in the .perldb file to automate the turning on/turning off of Devel::Carnivore. Here's the program stripped down:
    use strict; use warnings; my $h; { my %h; # watch from here ... $h{fname} = "Foo"; $holder = \%h; } $holder->{lname} = 'Bar'; $holder->{email} = 'foo@bar.com'; # ... to before here
    And here's .perldb to watch %h as noted:
    push @DB::typeahead, (split /\n/, <<EOS); # Load Carnivore use Devel::Carnivore # Line to start watching on c 7 watch(\\%h) # run to point where we want to switch off c 13 # do so unwatch \$h # run to end of program c # quit debugger q EOS
    Run this as perl -d <your program>. The output:
    01:26 PM $ perl5.8.5 -d z.pl Loading DB routines from perl5db.pl version 1.27 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(z.pl:4): my $h; main::(z.pl:5): { auto(-12) DB<1> use Devel::Carnivore auto(-11) DB<2> # Line to start watching on auto(-10) DB<3> c 7 main::(z.pl:7): $h{fname} = "Foo"; auto(-9) DB<4> watch(\%h) # variable is now under observation auto(-8) DB<5> # run to point where we want to switch off auto(-7) DB<6> c 13 > "fname" changed from "" to "Foo" at z.pl line 7 > "lname" changed from "" to "Bar" at z.pl line 11 main::(z.pl:13): $h->{email} = 'foo@bar.com'; # ... to before her +e auto(-6) DB<7> # do so auto(-5) DB<8> unwatch $h # mission completed auto(-4) DB<9> # run to end of program auto(-3) DB<10> c Debugged program terminated. Use q to quit or R to restart, use O inhibit_exit to avoid stopping after program termination, h q, h R or h O to get additional info. auto(-2) DB<10> # quit debugger auto(-1) DB<11> q 01:26 PM $
    The problem, of course, is that you're dependent on line numbers, but there's an example of how to automate the debugger. Removing the comments will of course give you nicer output as well.