Eric Wilhelm wrote:
Why is the underscore treated as a split character? This is actually
counter to how v-strings work.
$ perl -E 'say join(".", map({ord($_)} split(//, v2.3.4_5)))'
2.3.45
That is a bare v-string, so the tokenizer eats the underscore, just like
any bare number.
Although this also means that v-strings don't preserve the underscore.
This means the behavior of 5.8.8 changes depending on whether
version.pm was loaded (ever).
And the behavior in 5.10.x follows the first case below, even without
'use version'.
$ perl -e 'BEGIN {
package foo; our $VERSION = v2.3.4_5; $INC{"foo.pm"} = 1};
use version; use foo v2.3.5;'
foo version v2.3.5 required--this is only version v2.3.4_5 ...
$ perl -e 'BEGIN {
package foo; our $VERSION = v2.3.4_5; $INC{"foo.pm"} = 1};
use foo v2.3.5;'
# no error (45 > 5)
This is slightly harder to explain. For any Perl > 5.8.0, v-strings are
magical:
$ perl -MDevel::Peek -e '$VERSION = v2.3.4_5; Dump($VERSION)'
SV = PVMG(0x82e8f0c) at 0x82c4cb4
REFCNT = 1
FLAGS = (RMG,POK,pPOK)
IV = 0
NV = 0
PV = 0x82bb5cc "\2\3-"\0
CUR = 3
LEN = 4
MAGIC = 0x82bf614
MG_VIRTUAL = 0
MG_TYPE = PERL_MAGIC_vstring(V)
MG_LEN = 8
MG_PTR = 0x82bf094 "v2.3.4_5"
('-' is 0x45).
However, when that $VERSION is upgraded to a version object, I grab the
original string representation (MG_PTR) and use that for comparison. In
this case, that translates to a quoted v-string, and hence the
underscore is preserved.
In this case, however, the author who used a bare v-string as a $VERSION
initializer is the one who caused this confusion in the first place. If
you want to have what you type in the source file match reality, you
have to 'use version' because then you don't trip over Perl's bare
number handling.
So, the only dependable way to move past an alpha release is to bump the
next digit to the left of the dot before the underscore.
Yes, that is safer and of course recommended. I only implemented things
the way I did because it was the appropriate way to handle the
degenerate case.
John