Perl 有没有办法测试标量是否已字符串化?

Perl 有没有办法测试标量是否已字符串化?,perl,Perl,我正在编写一个东西,从perl结构输出类似于JSON的东西。我希望引用的行为如下: "string" outputs "string" "05" outputs "05" "5" outputs "5" 5 outputs 5 05 outputs 5, or 05 would be acceptable XS通过测试标量是否被“字符串化”来处理这个问题,我认为这很酷。但是,如果不编写XS,我无法找到自己进行此测试的方法,我宁愿避免使用XS。这可能吗?我在CPAN上的任何地方都找不到这一点,除

我正在编写一个东西,从perl结构输出类似于JSON的东西。我希望引用的行为如下:

"string" outputs "string"
"05" outputs "05"
"5" outputs "5"
5 outputs 5
05 outputs 5, or 05 would be acceptable
XS通过测试标量是否被“字符串化”来处理这个问题,我认为这很酷。但是,如果不编写XS,我无法找到自己进行此测试的方法,我宁愿避免使用XS。这可能吗?我在CPAN上的任何地方都找不到这一点,除非我发现Scalar::Util::looks_like_number等方面存在大量学究,这完全不是我想要的。我能找到的唯一权宜之计是Devel::Peek,它感觉很邪恶。而且,就像JSON::XS一样,我对这个secenario很满意:

my $a = 5;
print $a."\n";
# now $a outputs "5" instead of 5)

这可能不是最好的方法,但是如果
JSON
符合您的要求,为什么不使用它呢

sub is_stringy {
    encode_json([$_[0]]) =~ /["']/
}

is_stringy(5);      # undef
is_string("5");     # 1
检查以下各项的输出:

输出:

B::PV
B::IV
B::NV

或者,正如ikegami所建议的,如果您希望查找
pPOK
标志:

if (B::svref_2object( \$x )->FLAGS & B::SVp_POK) {
    print "I guess \$x is stringy\n";
}

您可以使用以下方法使数字不再显示为字符串化:

$x = 0+$x;
sub is_stringy {
   { no warnings 'void'; "".$_[0]; }
   return 1;
}
比如说,

$ perl -MJSON::XS -E'
   $_ = 4;
   say encode_json([$_]);  # [4]
   "".$_;
   say encode_json([$_]);  # ["4"]
   $_ = 0 + $_;
   say encode_json([$_]);  # [4]
'
由于JSON::XS正在研究Perl内部,因此检测某些内容是否已字符串化更为困难。可以使用以下方法:

$x = 0+$x;
sub is_stringy {
   { no warnings 'void'; "".$_[0]; }
   return 1;
}
但我认为这不是你想要的:)我不知道如何在不编写XS代码的情况下检测“腐败”。您想知道的是,
SvPOKp
对于标量是否为真(在对标量调用
SvGETMAGIC
之后)


无法调用
SvGETMAGIC
有缺点,但它几乎在所有时间都能工作。

如果找不到更好的答案,我最终可能会这么做。但这确实让人觉得浪费。我只保留JSON::XS的标量输出,但不幸的是,我输出的不是JSON,并且有不同的转义规则,等等。它与SV类型无关。它与pPOK标志有关。例如,查看
my$x=“”$x=5;我的$y=5;“.$y。两个都是PVIV,但只有一个是“stringy”。我也注意到了。如果B真的列出了它提供的东西,那就太好了!不幸的是,
SvGETMAGIC
似乎不可用。真的吗?对于
perl-MB-E'my$y=5,我得到
B::PV
;说ref B::svref\u 2对象(\(“”.$y))
。您是否正在传递对
svref\u 2object
的引用?呃,您不是在看$y<代码>perl-MB-E'my$x=“”$x=5;说ref B::svref_2对象(\$x);'
perl-MB-E'my$y=5;“.$y;说ref B::svref\u 2对象(\$y);'
use B qw( svref_2object SVp_POK );

sub is_stringy {
   my ($s) = @_;
   my $sv = svref_2object(\$s);
   #$sv->GETMAGIC();  # Not available
   return $sv->FLAGS & SVp_POK;
}