"be consistent" | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
I've considered this before, but never bothered to implement it. tie your array. Here's the idea: You have an array that something strange is happening to and you can't find where/when/why. You want to inspect it without altering your code with a bunch of print statements. Sure, there's the Perl debugger, and that's probably where you ought to turn first (and the main reason I haven't gotten around to giving this a try before). But today I'm going to try something different. Tie an array to a class that provides debug info whenever the array is modified in some way. Often tied entities are discouraged as they create action at a distance; it's very difficult to look at the primary source code and see why some behavior is happening -- too easy to forget about the tied behavior. But in this case, that's exactly what we're after: Behavior that is mostly invisible to the primary script, but helpful to us in some way. Start by using Tie::Array, and subclassing Tie::StdArray since it provides us with all the methods that emulate a plain old array. Then just override the ones we care about. It turns out we care about a lot of the methods (any that alter the array). But the source for Tie::Array (under the Tie::StdArray section) is a good starting point for maintaining default Array behavior while providing hooks for additional functionality. Note that with the "use parent" pragma, we have to say '-norequire', since Tie::StdArray is part of Tie::Array, and has already been loaded. We could just manipulate @ISA directly but that's not very Modern Perlish. I used Carp because its cluck() function is perfectly verbose. And I created an object method called $self->debug() that is a setter and getter for debug status. With debug set to '1' (or any true value) we get a noisy tied array. Set to zero, the array becomes silent again. Here's one fun aspect of a tied entity; we get the side-effect behavior (the primary objective of the tie is to create side-effects in our variables), and we also get the ability to control our variable's behavior via object oriented interface. If our tied variable is @array, and our tie returns an object to $o, then $o->debug(1) will turn on debugging verbosity for @array. What's it all for? Tie @ARGV in the beginning of your script (be sure to save its content and restore it after the tie). Then watch what other parts of your script do to @ARGV. Put the tie in a BEGIN{} block, and put that block before any 'use Module;' statements that may involve tinkering with @ARGV. Here's some somewhat messy code that demonstrates what I'm talking about:
If you read the code you will also see that I'm creating a sort of inside-out object in tandom with the primary blessed array-ref. This is because Tie::Array and Tie::StdArray tie our array to an array-ref, which makes it simple to implement a tied array. But it doesn't help much if we need some name-space for additional storage per tied object. So by creating a hash called %STASH as a package global within the tie class module I create room for a namespace. I can create keys for the %STASH with names that are just the stringified version of the blessed object reference. And when the object is distroyed, I made sure to delete the key. There are probably better approaches nowadays, but it's been awhile since I played with such things, and that's how I remember doing it in the past. Your output should be:
Now that you've seen this atrocity, be glad that Perl has a debugger. ;) Dave In reply to Re: debugging during compile
by davido
|
|