2014-05-01 7 views
14

Ho realizzato (nel modo più duro) che l'operatore eq dia un errore irreversibile al runtime quando uno degli operandi è un oggetto con stringificazione sovraccaricata.Perché `eq` non funziona quando un argomento ha sovraccaricato la stringa?

Ecco un esempio minimo:

my $test = MyTest->new('test'); 
print 'yes' if $test eq 'test'; 

package MyTest; 

use overload '""' => sub { my $self = shift; return $self->{'str'} }; 

sub new { 
    my ($class, $str) = @_; 
    return bless { str => $str }, $class; 
} 

Il risultato dell'esecuzione di questo è:

Operation "eq": no method found, 
    left argument in overloaded package MyTest, 
    right argument has no overloaded magic at ./test.pl line 7. 

La mia aspettativa dalla lettura perlop sarebbe tale contesto stringa è costretto su entrambi gli operandi, sparando l'in stringa metodo in $test, quindi le stringhe risultanti vengono confrontate. Perché non funziona? Cos'è in realtà l'hapenning?

Il contesto in cui ho riscontrato questo problema era in uno script che utilizza sia autodie e Try::Tiny. Nel blocco try, I die con alcuni messaggi specifici da rilevare. Ma nel blocco catch, quando provo se $_ eq "my specific message\n", questo dà un runtime se $_ è un autodie::exception.

So che dovrò sostituire $_ eq "..." con !ref && $_ eq "...", ma mi piacerebbe sapere perché.

+1

try '" $ test "eq 'test'' –

+0

@HunterMcMillen, ha funzionato, grazie. Ma non vedo che differenza fa all'interprete! – scozy

+2

Il confronto 'eq' in realtà non obbliga' $ test' a essere univoco, usa solo la stringa compare sui suoi argomenti. –

risposta

20

La stringificazione è stata sovraccaricata, non il confronto tra stringhe. Il overload pragma sarà comunque utilizzare l'in stringa sovraccarico per il confronto stringa se si specifica il parametro fallback => 1:

my $test = MyTest->new('test'); 
print 'yes' if $test eq 'test'; 

package MyTest; 

use overload 
    fallback => 1, 
    '""' => sub { my $self = shift; return $self->{'str'} }; 

sub new { 
    my ($class, $str) = @_; 
    return bless { str => $str }, $class; 
} 

dettagli sul motivo per cui questo funziona:

Quando consegnato un oggetto sovraccarico, l'operatore eq proverà a richiamare il sovraccarico di eq. Non abbiamo fornito un sovraccarico e non abbiamo fornito un sovraccarico cmp da cui è possibile generare automaticamente eq. Pertanto, Perl emetterà tale errore.

Con fallback => 1 enabled, l'errore viene eliminato e Perl farà ciò che farebbe comunque: forzare gli argomenti alle stringhe (che invoca il sovraccarico di stringificazione o altra magia) e confrontarli.

Problemi correlati