2010-04-08 15 views
6

Ho incontrato una situazione (durante la registrazione di varie modifiche di dati) in cui ho bisogno di determinare se un riferimento ha una coercizione di stringa valida (ad es. Può essere correttamente stampato in un registro o memorizzato in un database). Non c'è nulla in Scalar::Util per fare questo, così ho messo insieme qualcosa usando altri metodi in quella libreria:Come posso determinare se un oggetto o un riferimento ha una coercizione di stringa valida?

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"; 

Tuttavia, io ci sospetto potrebbe essere un modo migliore per determinare questo controllando il coraggio della variabile in qualche modo. Come può essere fatto meglio?

risposta

6

Da perldoc overload:

overload::StrVal(arg)

esprime il valore di stringa di arg come in assenza di sovraccarico in stringa.

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

noti che overload::Method non è appropriato qui because:

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

Se uno o due di queste operazioni non sono sovraccarichi, la quelli rimanenti possono invece essere usati.

Pertanto, il controllo solo se '""' è sovraccarico restituirebbe falsi negativi rispetto al metodo visualizzato nella domanda.

+0

Mi è piaciuta la versione precedente, che mostrava come trovare il metodo di stringificazione - ad es. 'perl -MDateTime -Moverload -wle'my $ dt = DateTime-> ora; my $ method = overload :: Method ($ dt, q {""}); print $ method -> ($ dt) '':) – Ether

+0

@Ether Il problema è che' bool' potrebbe essere stato sovraccaricato fornendo una stringa senza ''" "" "sovraccaricato. –

Problemi correlati