6

(さまざまなデータ変更をログに記録しているときに)参照に有効な文字列強制が含まれているかどうかを判断する必要がある状況に遭遇しました(たとえば、ログに適切に印刷したり、データベースに保存したりできます)。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";

ただし、変数の内臓を何らかの方法で検査することで、これを判断するためのより良い方法があるのではないかと思います。どうすればこれをより良くすることができますか?

4

1 に答える 1

6

perldocオーバーロードから:

overload::StrVal(arg)

arg stringifyのオーバーロードがない場合の文字列値をasに指定します。

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

overload::Methodここでは適切ではないことに注意してください。

  1. 'bool'、、、、'""'_ '0+'_

これらの操作の1つまたは2つが過負荷になっていない場合は、代わりに残りの操作を使用できます。

したがって、'""'がオーバーロードされているかどうかのみをチェックすると、質問で示した方法と比較してフォールスネガティブが返されます。

于 2010-04-08T18:09:41.823 に答える