【问题标题】:How can I determine if an object or reference has a valid string coercion?如何确定对象或引用是否具有有效的字符串强制转换?
【发布时间】:2010-04-08 18:02:50
【问题描述】:

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

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

【问题讨论】:

    标签: perl reference coercion


    【解决方案1】:

    来自perldoc overload

    overload::StrVal(arg)

    在没有字符串化重载的情况下,给出arg 的字符串值。

    sub can_stringify {
        my ($obj) = @_;
        return "$obj" ne overload::StrVal($obj);
    }
    

    注意overload::Method在这里不合适because

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

    如果这些操作中的一个或两个没有重载,则可以使用其余的代替。

    因此,与您在问题中显示的方法相比,仅检查 '""' 是否重载会返回假阴性。

    【讨论】:

    • 我更喜欢你的早期版本,它展示了如何找到字符串化方法——例如perl -MDateTime -Moverload -wle'my $dt = DateTime->now; my $method = overload::Method($dt, q{""}); print $method->($dt)' :)
    • @Ether 问题是bool 可能已经重载,提供了字符串化而'""' 没有重载。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 2012-11-27
    • 2011-09-09
    相关资源
    最近更新 更多