Reputation: 3
I define a Perl module, like so:
#!/usr/bin/env perl
use strict;
use warnings;
package Sample;
use Data::Dumper;
our $VERSION = v1.10;
sub VERSION
{
my ($class, $version) = @_;
print ("version is $version\n");
print Dumper ($version);
}
The nature of the value passed in $version
changes depending on how the module is imported:
$ perl -e 'use Sample 1.0'
version is 1
$VAR1 = '1';
However, if the required module version is specified as a v-string:
$ perl -e 'use Sample v1.0'
version is
$VAR1 = v1.0;
What data type is being passed in $version
in the second case? It's apparently not a simple scalar, and it's not a reference.
Upvotes: 0
Views: 48
Reputation: 385789
Each dot-separated number is converted into a character with the ordinal value of the number.[1] In other words,
v1.0 ≡ "\x01\x00" ≡ chr(1).chr(0) ≡ pack('W*', 1, 0)
You can convert a v-string into something human readable using the %vd
format specifier of sprintf
.[2]
$ perl -e'CORE::say sprintf("%vd", v1.0)'
1.0
But it's better to use the version module.
$ perl -Mversion -e'CORE::say version->parse(v1.0)'
v1.0
It's better because the version module can handle version strings in general (not just v-strings).
$ perl -Mversion -e'
my $v1 = version->parse(1.0);
my $v2 = version->parse("1.0");
my $v3 = version->parse(v1.0);
my $v4 = version->parse("v1.0");
CORE::say "equal"
if $v1 == $v2
&& $v1 == $v3
&& $v1 == $v4
'
equal
One can use any numerical or string comparison operator[3] to compare version objects.
It's more than that, though. A scalar containing a v-string has magic (of type V
) applied, so it's possible to dectect that it's a v-string.
$ perl -MDevel::Peek -e'Dump("\x01\x00"); Dump(v1.0);'
SV = PV(0xbc9d70) at 0xbe7998
REFCNT = 1
FLAGS = (POK,IsCOW,READONLY,PROTECT,pPOK)
PV = 0xbf1ed0 "\1\0"\0
CUR = 2
LEN = 10
COW_REFCNT = 0
SV = PVMG(0xc20480) at 0xbe7938
REFCNT = 1
FLAGS = (RMG,POK,IsCOW,READONLY,PROTECT,pPOK)
IV = 0
NV = 0
PV = 0xbf0190 "\1\0"\0
CUR = 2
LEN = 10
COW_REFCNT = 0
MAGIC = 0xbf3a80
MG_VIRTUAL = 0
MG_TYPE = PERL_MAGIC_vstring(V)
MG_LEN = 4
MG_PTR = 0xbf1700 "v1.0"
This magic is even applied to any scalar to which the v-string is copied!
$ perl -MDevel::Peek -e'my $v1 = v1.0; my $v2 = $v1; Dump($v2)'
SV = PVMG(0x9dc500) at 0x9a3a00
REFCNT = 1
FLAGS = (RMG,POK,IsCOW,pPOK)
IV = 0
NV = 0
PV = 0x9ac1b0 "\1\0"\0
CUR = 2
LEN = 10
COW_REFCNT = 2
MAGIC = 0x9b8090
MG_VIRTUAL = 0
MG_TYPE = PERL_MAGIC_vstring(V)
MG_LEN = 4
MG_PTR = 0x9adef0 "v1.0"
I believe the version module takes advantage of this information.
This format specifier works on any string, so it's convenient for checking for hidden or special characters when debugging.
$ perl -e'CORE::say sprintf "%v02X", "abc\r\n"'
61.62.63.0D.0A
==
, <
, >
, <=
, >=
, <=>
, eq
, lt
, gt
, le
, ge
and cmp
.
Upvotes: 1
Reputation: 4013
A v string is a string. Each number is assumed to be a Unicode code point and is converted to that character so what you are actually printing out is chr(1) . chr(0). You can prove this with the following script
my $vstring = v80.101.114.108
print $vstring, "\n";
This will print Perl
Upvotes: 2