如何确定对象或引用是否具有有效的字符串强制?

Eth*_*her 6 perl reference coercion

我遇到了一种情况(记录各种数据变化时),我需要确定引用是否具有有效的字符串强制(例如,可以正确打印到日志中或存储在数据库中).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";
Run Code Online (Sandbox Code Playgroud)

但是,我怀疑通过以某种方式检查变量的内容可能有更好的方法来确定这一点.怎么能做得更好?

Sin*_*nür 6

perldoc过载:

overload::StrVal(arg)

给出字符串值,arg 因为没有stringify重载.

sub can_stringify {
    my ($obj) = @_;
    return "$obj" ne overload::StrVal($obj);
}
Run Code Online (Sandbox Code Playgroud)

请注意,overload::Method此处不合适,因为:

  1. 'bool','""','0+',

如果这些操作中的一个或两个没有过载,则可以使用其余的操作.

因此,'""'与您在问题中显示的方法相比,仅检查是否过载将返回错误否定.