Hack 84. Double Your Data with Dualvars


Store twice the information in a single scalar.

Some languages are really picky about the contents of a variable. If the variable is a string, it's always a string. If the variable is a number, it's always a numberespecially of a certain type and size.

Perl's not that picky; it happily converts back and forth depending on what you do with the variable. Consequently, one variable may hold several different pices of data. You can even peek inside Perl's storage and do different things depending on how you treat your variablereturning entirely different values whether you treat it as a number or a string.

The Hack

Consider a program that has a lot of constantssay, a graphical program [Hack #16] with screen size, color depth, difficulty level, and so on. If you're debugging such a problem, it can be difficult to track variables when you're passing around magic variables. It gets worse when you have to deal with flags that you AND and OR together. How do you know when a number is really an important number or just the coincidental result of a calculation that merely looks like an important number?

Instead of having to look up the symbolic names (easy for programmers to remember) for values (easy for a computer to handle) every time you debug something, consider using dualvars:

use Scalar::Util 'dualvar'; my $width   = dualvar( 800, 'Screen width'       ); my $height  = dualvar( 600, 'Screen height'      ); my $colors  = dualvar(  16, 'Screen color depth' ); # some code sub debug_variable {     my $constant = shift;     printf STDERR "%s is %d\\n", $constant, $constant; }

Now whenever you encounter a variable you want to inspect for debugging, pass it to debug_variable( ), which will helpfully print something like:

Screen width is 800 Screen height is 600 Screen color depth is 16

Running the Hack

Every Perl scalar has several slots for several different types of data. The dualvar( ) function from the ever-useful Scalar::Util package takes two: a numeric and a string value. It stores the numeric value in the numeric (NV) slot of the scalar and sets a flag that it's okay to look in that slot in numeric contexts. It does the same for the string value (PV slot, string contexts).

Whenever you access a scalar in a certain type of context, Perl first checks the appropriate flag for that context. If it's okay to use the value in the appropriate slot, Perl does so. Otherwise, it converts an existing value from another slot to the appropriate type, puts the calculated value in the appropriate slot, and sets the flag it checked.

The dualvar nature affects the value stored in the variable, not the variable itself, so it's safe to pass back and forth in and out of functions.

Hacking the Hack

You can also use this trick with the constant pragma if you prefer that for your constants:

use constant AUTHOR => dualvar( 006, 'chromatic the superspy author' );

If that's not paranoid enough for you, the Readonly module also works with this technique:

use Readonly; Readonly::Scalar my $colors => dualvar(  16, 'Screen color depth' );



Perl Hacks
Perl Hacks: Tips & Tools for Programming, Debugging, and Surviving
ISBN: 0596526741
EAN: 2147483647
Year: 2004
Pages: 141

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net