如何区分Perl中的数字标量和字符串标量?

Ste*_*sky 19 string perl types integer

Perl通常透明地将数字转换为字符串值,反之亦然.然而,必须有一些东西允许例如Data::Dumper区分两者,如下例所示:

use Data::Dumper;
print Dumper('1', 1);

# output:
$VAR1 = '1';
$VAR2 = 1;
Run Code Online (Sandbox Code Playgroud)

是否有Perl函数允许我以类似的方式区分标量的值是存储为数字还是字符串?

ike*_*ami 17

标量有许多不同的领域.使用Perl 5.8或更高版本时,Data :: Dumper会检查IV(整数值)字段中是否有任何内容.具体来说,它使用类似于以下内容:

use B qw( svref_2object SVf_IOK );

sub create_data_dumper_literal {
    my ($x) = @_;  # This copying is important as it "resolves" magic.
    return "undef" if !defined($x);

    my $sv = svref_2object(\$x);
    my $iok = $sv->FLAGS & SVf_IOK;
    return "$x" if $iok;

    $x =~ s/(['\\])/\\$1/g;
    return "'$x'";
}
Run Code Online (Sandbox Code Playgroud)

你可以使用类似的技巧.但请记住,

  • 在不丢失的情况下将浮点数字串化是非常困难的.(浮动指针编号使用$sv->FLAGS & SVf_NOK.)

  • 您需要在字符串文字中正确转义某些字节(例如NUL).

  • 标量可以存储多个值.例如,!!0包含一个字符串(空字符串),一个浮点数(0)和一个有符号整数(0).如您所见,不同的值甚至不等同.有关更具戏剧性的示例,请查看以下内容:

    $ perl -E'open($fh, "non-existent"); say 0+$!; say "".$!;'
    2
    No such file or directory
    
    Run Code Online (Sandbox Code Playgroud)


cho*_*oba 15

它更复杂.Perl根据变量的使用上下文更改变量的内部表示:

perl -MDevel::Peek -e '
    $x = 1;    print Dump $x;
    $x eq "a"; print Dump $x;
    $x .= q(); print Dump $x;
'
SV = IV(0x794c68) at 0x794c78
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 1
SV = PVIV(0x7800b8) at 0x794c78
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 1
  PV = 0x785320 "1"\0
  CUR = 1
  LEN = 16
SV = PVIV(0x7800b8) at 0x794c78
  REFCNT = 1
  FLAGS = (POK,pPOK)
  IV = 1
  PV = 0x785320 "1"\0
  CUR = 1
  LEN = 16
Run Code Online (Sandbox Code Playgroud)


Boh*_*dan 10

使用纯perl无法找到它.Data :: Dumper使用C库来实现它.如果强制使用Perl,如果字符串看起来像十进制数字,则不会将字符串与数字区分开来.

use Data::Dumper;
$Data::Dumper::Useperl = 1;
print Dumper(['1',1])."\n";

#output
$VAR1 = [
          1,
          1
        ];
Run Code Online (Sandbox Code Playgroud)

  • 实际上,无需编写C代码或安装任何模块即可实现.看我的回答. (2认同)

TLP*_*TLP 6

根据您的评论,这是为了确定SQL语句是否需要引用,我会说正确的解决方案是使用占位符,这在DBI文档中有描述.

通常,您不应直接在查询字符串中插入变量.