在模块版本检查期间将参数传递给Perl VERSION子例程

时间:2018-09-27 11:35:50

标签: perl

我定义了一个Perl模块,如下所示:

SELECT count(n_group) AS CountOfLeaders
FROM [tableA] as a
INNER JOIN tableB b ON a.n_group = b.g_name
WHERE b.id = 1

#!/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); } 中传递的值的性质根据模块的导入方式而变化:

$version

但是,如果将所需的模块版本指定为v字符串:

$ perl -e 'use Sample 1.0'
version is 1
$VAR1 = '1';

第二种情况是在$ perl -e 'use Sample v1.0' version is $VAR1 = v1.0; 中传递什么数据类型?显然这不是简单的标量,也不是参考。

2 个答案:

答案 0 :(得分:2)

v字符串是字符串。每个数字都假定为Unicode代码点,并转换为该字符,因此您实际打印的是chr(1)。 chr(0)。您可以使用以下脚本证明这一点

#content

这将打印my $vstring = v80.101.114.108 print $vstring, "\n";

答案 1 :(得分:1)

每个点分隔的数字都将转换为具有该数字序号的字符。 [1] 换句话说,

v1.0   ≡   "\x01\x00"   ≡   chr(1).chr(0)   ≡   pack('W*', 1, 0)

您可以使用%vd的{​​{1}}格式说明符将v字符串转换为人类可读的内容。 [2]

sprintf

但是最好使用version模块。

$ perl -e'CORE::say sprintf("%vd", v1.0)'
1.0

最好是这样,因为版本模块可以处理一般的版本字符串(而不仅仅是v字符串)。

$ perl -Mversion -e'CORE::say version->parse(v1.0)'
v1.0

一个人可以使用任何数字或字符串比较运算符 [3] 来比较版本对象。


  1. 但是,不仅如此。包含v字符串的标量已应用了魔法(类型为$ 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 ),因此可以判断它是v字符串。

    V

    这种魔力甚至适用于将v字符串复制到的任何标量!

    $ 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"
    

    我相信版本模块会利用此信息。

  2. 此格式说明符可用于任何字符串,因此在调试时检查隐藏字符或特殊字符非常方便。

    $ 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"
    
  3. $ perl -e'CORE::say sprintf "%v02X", "abc\r\n"' 61.62.63.0D.0A ==<><=>=<=>,{{ 1}},eqltgtle