In moving from Perl 5.22.0 to 5.22.1 I noticed an anomaly using tobyink’s P5U module: p5u v <Module> still finds the module correctly, but in some (not all) cases the version number disappears. Under 5.22.0:
12:24 >p5u v Capture::Tiny Capture::Tiny C:\Perl\Strawberry\strawberry-perl-5.22.0.1-64bit-PDL\perl\ven +dor\lib\Capture\Tiny.pm: 0.30
But under 5.22.1:
12:27 >p5u v Capture::Tiny Capture::Tiny C:\Perl\Strawberry\strawberry-perl-5.22.1.1-64bit-PDL\perl\ven +dor\lib\Capture\Tiny.pm: undef 12:27 >
Some tortuous debugging1 eventually led to sub version in Module::Info as the source of the version number. Furthermore, the problem was introduced between version 0.35 (which happens to be the version of Module::Info on my 5.22.0 Perl installation) and version 0.37 (the version on my 5.22.1 installation). But sub version didn’t change between those versions, so what did?
1Cue The Long and Winding Road.
These lines appear near the head of the code for Module::Info 0.35:
use vars qw($VERSION @ISA $AUTOLOAD); # quotes 'version' for 5.004 $VERSION = eval 'use version; 1' ? 'version'->new('0.35') : '0.35'; $VERSION = eval $VERSION;
In 0.37 this has changed to:
our $AUTOLOAD; our $VERSION; $VERSION = eval 'use version; 1' ? 'version'->new('0.37') : '0.37'; $VERSION = eval $VERSION;
And, yes, it turns out that the difference in behaviour does result from changing the declaration of $VERSION from use vars to our. Specifically, it’s a problem of scope: use vars (if I understand it correctly) creates a dynamic scope within the current package, whereas our creates a lexical scope that crosses packages within the same file.
Anyway, I came up with a short script that reproduces the problem I’m seeing in Module::Info:
use strict; use warnings; package Package_One; use vars qw( $VERSION ); #our $VERSION; $VERSION = 'irrelevant'; # "our $VERSION" comes from the target module; without "our" there's n +o problem my $eval =<<'END_EVAL'; no strict; local $VERSION; $VERSION=undef; do { our $VERSION = 'desired_version'; }; $VERSION END_EVAL printf "Version: %s\n", Package_Two->_eval($eval); package Package_Two; sub _eval { eval $_[1]; }
This script works correctly: it prints Version: desired_version. But when I change the declarations:
#use vars qw( $VERSION ); our $VERSION;
the version comes back undefined. Note that this problem goes away if the our inside the do block is removed from $eval:
my $eval =<<'END_EVAL'; no strict; local $VERSION; $VERSION=undef; do { $VERSION = 'desired_version'; }; $VERSION END_EVAL
— which explains why some modules have the version problem and some don’t: the former have their own package variable $VERSION declared with our, the latter do not.
So, my questions:
I’m posting here before submitting a bug report because I would like to first understand exactly what is happening, and why. Any insight or advice will be appreciated — especially an explanation of how the do block interacts with the surrounding code when it’s evaled. A step-by-step description of which $VERSION is which inside sub _eval would be very helpful, too. :-)
Thanks,
| Athanasius <°(((>< contra mundum | Iustus alius egestas vitae, eros Piratica, |
In reply to Bug in Module::Info? our vs. use vars by Athanasius
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |