NAME
Devel::WatchVars - trace access to scalar variables
SYNOPSIS
use Devel::WatchVars;
my $some_var;
watch $some_var, '$some_var';
...
unwatch $some_var;
DESCRIPTION
The Devel::WatchVars
module provides simple tracing of scalars. The watch
function takes the scalar you want traced followed by the descriptive string to use as its name in traces.
Here's a simple illustration using a short program, here named examples/simple:
1 #!/usr/bin/env perl
2 use v5.10;
3 use strict;
4 use warnings;
5
6 use Devel::WatchVars;
7 sub twice { return 2 * shift }
8
9 my $x = 10;
10 watch($x, '$x');
11 say "starting watched value is $x";
12 $x = 5 + twice(++$x);
13 say "ending watched value is $x";
14 unwatch $x;
When run, that produces the following output:
WATCH $x = 10 at examples/simple line 10.
FETCH $x --> 10 at examples/simple line 11.
starting watched value is 10
FETCH $x --> 10 at examples/simple line 12.
STORE $x <-- 11 at examples/simple line 12.
FETCH $x --> 11 at examples/simple line 7.
STORE $x <-- 27 at examples/simple line 12.
FETCH $x --> 27 at examples/simple line 13.
ending watched value is 27
UNWATCH $x = 27 at examples/simple line 14.
The trace appears on standard error, one line per access consisting of the following elements:
A word in all capital letters for the type of access, one of
WATCH
,FETCH
,STORE
,UNWATCH
, orDESTROY
.Whatever string you passed in the second argument. passed the initial call to
watch
.A bit of intervening text (
=
or-->
or<--
).The scalar value.
The origin by file and line.
The first argument to watch
must be a scalar variable, or a single scalar element from an array or a hash. In other words, that argument needs to begin with a literal dollar sign.
The second argument to watch
is an arbitrary string. Normally its the name of that watched scalar, however you choose to represent that. This can be useful if you just want to watch one element from some larger data structure. For example,
watch $nums[2], "element[2] of array";
watch $color{blue}, "the blue color element";
The argument to unwatch
must match one that you have previously called watch
with and which you have not yet called unwatch
with.
The tracing lasts until you call the unwatch
function on the watched variable to discontinue that tracing, or when that scalar is destroyed through garbage collection. If it is destroyed while the program is running, it will say something like:
DESTROY $x = 9 at examples/destroyed line 15.
but if is destroyed during global destruction, it indicates this like so:
DESTROY (during global destruction) $x = 9 at examples/global-destruction line 0.
The watch
function is implemented using an internal tie
, and the unwatch
function is implemented using an internal untie
.
EXAMPLES
See the example scripts in the examples subdirectory of this module's source distribution.
ENVIRONMENT
- DEVEL_WATCHVARS_VERBOSE
-
Normally, the traces include only a shortmess at the end, no matter what you've may have set the value of
$Carp::Verbose
to. But if the environment variableDEVEL_WATCHVARS_VERBOSE
has a true value, a full longmess will be used instead.
DIAGNOSTICS
- "Can't unwatch something that isn't tied"
-
Runtime error because the scalar you passed is not being watched right now.
- "Can't unwatch something that isn't watched"
-
Runtime error because the scalar you passed is tied to some other class.
- "Can't watch a readonly scalar"
-
The scalar variable you want to watch contains a readonly value.
- "Type of arg 1 to Devel::WatchVars::unwatch must be scalar (not %s)"
-
Attempting to pass something to
unwatch
that does not begin with a literal dollar sign will produce a compilation error in your code like this:Type of arg 1 to Devel::WatchVars::unwatch must be scalar (not hash dereference) at -e line 1
- "Type of arg 1 to Devel::WatchVars::watch must be scalar (not %s)"
-
Attempting to pass something to
watch
that does not begin with a literal dollar sign will produce a compilation error in your code like these:Type of arg 1 to Devel::WatchVars::watch must be scalar (not constant item) at -e line 1 Type of arg 1 to Devel::WatchVars::watch must be scalar (not array dereference) at -e line 1
- "You didn't pass a scalar (by reference)";
- "You didn't pass a SCALAR (by reference), you passed a %s (by reference)"
-
These are both runtime errors, and usually possible only if you're cheating by calling the functions without prototypes being checked.
TODO
Devise a curried subclassing mechanism.
Add watching entire aggregate arrays and hashes en masse.
SEE ALSO
- Tie::Watch
-
Place watchpoints on Perl variables using PerlTK.
- Devel::TraceVars
-
Mode of the perl debugger to print each line of code with variables evaluated.
AUTHOR
Tom Christiansen <tchrist53147@gmail.com>
.
LICENCE AND COPYRIGHT
Copyright (c) 2020 by Tom Christiansen.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.