我遇到了一种情况(在记录各种数据变化时),我需要确定引用是否具有有效的字符串强制(例如,可以正确打印到日志中或存储在数据库中)。 Scalar::Util中没有任何内容可以执行此操作,因此我使用该库中的其他方法拼凑了一些内容:
use strict;
use warnings;
use Scalar::Util qw(reftype refaddr);
sub has_string_coercion
{
my $value = shift;
my $as_string = "$value";
my $ref = ref $value;
my $reftype = reftype $value;
my $refaddr = sprintf "0x%x", refaddr $value;
if ($ref eq $reftype)
{
# base-type references stringify as REF(0xADDR)
return $as_string !~ /^${ref}\(${refaddr}\)$/;
}
else
{
# blessed objects stringify as REF=REFTYPE(0xADDR)
return $as_string !~ /^${ref}=${reftype}\(${refaddr}\)$/;
}
}
# Example:
use DateTime;
my $ref1 = DateTime->now;
my $ref2 = \'foo';
print "DateTime has coercion: " . has_string_coercion($ref1) . "\n\n";
print "scalar ref has coercion: " . has_string_coercion($ref2) . "\n";
然而,我怀疑通过以某种方式检查变量的内容可能有更好的方法来确定这一点。如何做得更好?
答案 0 :(得分:6)
overload::StrVal(arg)
在没有stringify重载的情况下,给出
arg
的字符串值。
sub can_stringify {
my ($obj) = @_;
return "$obj" ne overload::StrVal($obj);
}
请注意overload::Method
不适合because:
- 醇>
'bool'
,'""'
,'0+'
,如果这些操作中的一个或两个没有过载,则可以使用其余的操作。
因此,仅检查'""'
是否过载会与您在问题中显示的方法相比返回误报。