2011-10-12 10 views
12

Ok, la sobrecarga de chequeo de cordura no parece funcionar para mí. No sé si es la versión de perl que tengo, o la versión de overload.pm, o algo mal con la forma en que lo he implementado, pero este código no funciona para mí.¿Por qué la "sobrecarga de uso" no funciona con "use namespace: autoclean"?

versión de Perl

This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi 

versión sobrecarga

perl -Moverload -e 'print "$overload::VERSION\n";' 
1.07 

Token.pm

package Token; 
use namespace::autoclean; 
use Data::Dumper; 


use Moose; 
use Moose::Util::TypeConstraints; 

use overload '+' => \&_overload_add, fallback => 1; 

    has 'secretvalue' => (is => 'rw', isa => 'Int'); 

    sub _overload_add{ 
    my ($one, $two) = @_; 
    my $value = $one->secretvalue() + $two->secretvalue(); 
    return ($value); 
    } 

principal

use strict; 
use warnings; 
use Token; 
my $t = Token->new(secretvalue => 17, key => 'x'); 
my $t2 = Token->new(secretvalue => 12, key => 'y'); 

my $x = $t + $t2; 

print $x; 

impresiones

$VAR1 = 12900840; 

Lo peor es que ahora no recibo ningún tipo de advertencia o errores en el registro.

ACTUALIZACIÓN

Gracias a Freido para encontrar el problema. He actualizado la pregunta por si acaso alguien más tropieza con esto.

¿La comunidad de Perl/Moose generalmente no usa sobrecarga?

Respuesta

16

namespace::autoclean es asombroso con la magia que overload agrega para manejar su operador. Los siguientes trabajos como es de esperar:

package Token; 

use Moose; 
use Moose::Util::TypeConstraints; 

use overload '+' => '_overload_add'; 

has 'secretvalue' => (is => 'rw', isa => 'Int'); 

sub _overload_add{ 
    my ($one, $two) = @_; 
    my $value = $one->secretvalue() + $two->secretvalue(); 
    return ($value); 
} 

1; 

Una mirada casual no revela nada en los documentos namespace::autoclean que aborda esto, así que supongo que es una característica inesperada. Algunas búsquedas revelan que se ha informado un bug.

Supongo que se trata de los símbolos especiales que overload agrega a su paquete. La sobrecarga + agrega las entradas de la tabla de símbolos (), (+ y OVERLOAD. Supongo que algunos o todos estos son aspirados por namespace::autoclean, por lo que se deshace la sobrecarga.

Si te sientes aventurero, here's a patch para namespace::autoclean que filtra los símbolos de sobrecarga.

+1

+1 para encontrar una solución después de golpear mi cabeza en el escritorio durante una hora o dos tratando de encontrar el problema con mi código. tontos errores de la biblioteca! – qodeninja

+1

estado allí, hecho eso. :) Estuve bastante desconcertado por tu problema también hasta que recordé que 'sobrecarga 'funcionaba insertando símbolos mágicos, y me pregunté si' autoclean' estaba jugando con ellos. – friedo

+3

@nodebunny, ¿por qué reclamar el código de otras personas cuando puedes escribir el tuyo? :) Esta pregunta me inspiró a escribir [namespace :: sweep] (http://search.cpan.org/~friedo/namespace-sweep/lib/namespace/sweep.pm) que no pisoteará tus sobrecargas. Más información [aquí] (http://blogs.perl.org/users/mike_friedman/2011/10/announcing-namespacesweep.html). – friedo

10

So friedo es absolutamente correcto; el problema radica en la clase heurística :: MOP utiliza para determinar qué es y qué no es un "método". Generalmente, cualquier cosa importada de otro paquete no es un método, y las sobrecargas técnicamente califican como eso. Dado que namespace :: autoclean le pregunta a Class :: MOP qué métodos existen para el paquete y elimina el resto, autoclean ciegamente purga las sobrecargas junto con todo lo demás.

Lo cual es bastante sorprendente, creo.

MooseX::MarkAsMethods ayudará con esto para las clases de Moose; se ejecuta antes de que Autoclean lo haga y le dice a Moose que reconozca los símbolos de código de sobrecarga para ese paquete como métodos. Esto les ahorra el hacha de autoclean, y tiene la ventaja añadida de que ahora puede usar sobrecargas en los roles, consumirlos y hacer que "simplemente funcionen". (Divulgación completa: escribí MX :: MarkAsMethods después de que mi corrección de autoclean fuera rechazada hace 2 años.)

Sin embargo, esto no ayuda con las clases que no son Moose, es posible que desee utilizar la limpieza automática con ... La eliminación de sobrecargas por autoclean es, en el mejor de los casos, un error en la limpieza automática.

+5

'defecto' es ser muy amable,' namespace :: autoclean' está completamente roto por esto. Tu corrección fue perfecta. Por cierto, es una pena que el mantenedor sea terco al respecto. –

0

He tenido el mismo problema (tratando de sobrecargar "" en mi caso), pero aún no tengo MooseX :: MarkAsMethods para trabajar. No se investigó por qué todavía, pero una solución alternativa que hizo fue utilizar (y como ya estaba usando varias funciones, se ajustaba fácilmente).

package MyClass; 
use Moose; 
use namespace::autoclean; 
with 'MyRole'; 

package MyRole; 
use MooseX::Role::WithOverloading; 

use overload '""' => sub { ... }; 
Cuestiones relacionadas