区分perl中的字符串和数字参数

caj*_*ine 2 perl

如何解决以下问题?

use 5.014;
use warnings;
use Test::Simple tests => 4;

ok( doit(0123)   == 83, "arg as octal number" );
ok( doit(83)     == 83, "arg as decimal number" );
ok( doit('0123') == 83, "arg as string with leading zero" );
ok( doit('123')  == 83, "arg as string without leading zero" );

sub doit {
    my $x = shift;
    return $x;                                     # how to replace this line
    #return  got_the_arg_as_string ? oct($x) : $x; # with something like this
}
Run Code Online (Sandbox Code Playgroud)

例如,如果我向doit子传递任何字符串 - 均值引用值 - (有或没有前导零),它应该转换为八进制值.否则,它只是一个数字.

mob*_*mob 6

Perl的标量内部表示可以是整数或字符串,并且随时可以将该表示强制转换为任何其他标量类型.使用C/XS代码可以获得标量的内部类型.该JSON::XS模块是这种情况,例如,来决定的值是否应呈现为数字或字符串.

这是您的问题的概念证明:

use Inline 'C';
sub foo {
    my ($x) = @_;
    print $x, " => isString: ", isString($x), "\n";
}
foo(0123);
foo('0123');

__END__
int isString(SV* sv)
{
    return SvPOK(sv) ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)

节目输出:

83 => isString: 0
0123 => isString: 1
Run Code Online (Sandbox Code Playgroud)

相关文章:

$ var = 500和$ var ='500'之间的差异

Perl 5中字符串和数字之间的差异何时重要?

为什么JSON模块会引用一些数字而不引用其他数字?

更新一些此功能在核心B模块中公开,因此无需添加为XS依赖项:

use B;
sub isString {
    my $scalar = shift;
    return 0 != (B::svref_2object(\$scalar)->FLAGS & B::SVf_POK)
}
Run Code Online (Sandbox Code Playgroud)

  • `sub isNumber {no warnings"numeric"; 长度($ _ [0]&"")}` (2认同)