How can I determine if an object or reference has a valid string coercion?
I've run into a situation (while logging various data changes) where I need to determine if a reference has a valid string coercion (e.g. can properly be printed into a log or stored in a database). There isn't anything in Scalar::Util to do this, so I have cobbled together something using other methods in that library:
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开发者_C百科 $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";
However, I suspect there might be a better way of determining this by inspecting the guts of the variable in some way. How can this be done better?
From perldoc overload:
overload::StrVal(arg)
Gives string value of
arg
as in absence of stringify overloading.
sub can_stringify {
my ($obj) = @_;
return "$obj" ne overload::StrVal($obj);
}
Note that overload::Method
is not appropriate here because:
'bool'
,'""'
,'0+'
,If one or two of these operations are not overloaded, the remaining ones can be used instead.
Therefore, checking only if '""'
is overloaded would return false negatives compared to the method you show in your question.
精彩评论