2009-08-27 9 views
6

He estado jugando con Moose, sintiéndolo. Me gustaría un ejemplo de funciones virtuales puras, como en C++ pero en el lenguaje de Moose (específicamente en un aspecto de C++). Sé que incluso con Moose imponiendo un modelo más estricto que Perl normal, todavía hay más de una forma de hacer lo que estoy pidiendo (a través de modificadores de método o llamadas SUPER::). Es por eso que estoy pidiendo específicamente una implementación que se asemeje a C++ tanto como sea posible. En cuanto al "¿por qué?" de esta restricción? Principalmente curiosidad, pero también planeaba portar algún código C++ a Perl con Moose de una manera en la que las personas centradas en C++ podrían identificarse con en su mayoría.C++ - como el uso de Moose con Perl para OOP

+0

Moví mi intento de la pregunta a la sección de respuestas. –

+1

Sí, esta pregunta ya es la tercera respuesta cuando se busca en Google para funciones virtuales puras en Perl con Moose. Para los interesados, la discusión de perlmonks semi relacionada con esto está aquí: http://www.perlmonks.org/?node_id=742013. Tampoco parecen tener una respuesta concreta allí. –

+0

Probablemente porque todos excepto los programadores de C++ los llaman "métodos". – jrockway

Respuesta

5

que puedo pensar de esta manera el uso de funciones en lugar de subclases:

{ 
    package AbstractRole; 
    use Moose::Role; 
    requires 'stuff'; 
} 

{ 
    package Real; 
    use Moose; 
    with 'AbstractRole'; 
} 

Esto le dará un error de compilación porque el Real no tiene cosas definido.

Adición método cosas al Real ahora hacer que funcione:

{ 
    package Real; 
    use Moose; 
    with 'AbstractRole'; 

    sub stuff { print "Using child function!\n" } 
} 
+0

Sí, así es como se haría si solo quisiera una interfaz. Estoy descubriendo a través de la investigación y la discusión aquí que quizás no pueda hacer _exactamente_ lo que espero hacer. –

+0

Creo que esto te lleva la mayor parte del camino. Chatee con Moose guys en #moose en irc.perl.org o en la lista de correo [email protected] si cree que hay un beneficio en extender esto más. – draegtun

+0

@draegtun Sí, creo que esta es la mejor aproximación que puedo esperar. ¡Gracias por tu ayuda! –

1

Aquí es fue mi intento (sin Papeles, para obtener información sobre Roles ver las otras respuestas):

package Abstract; 
use Moose; 

sub stuff; 

package Real; 
use Moose; 
extends 'Abstract'; 

override 'stuff' => sub { print "Using child function!\n"; } 
+0

No tengo idea de lo que estás hablando, pero parece que quieres 'Abstract' para ser una clase base abstracta y el método' stuff' (no función) para ser puramente virtual. Simplemente escribir 'sub stuff {}' inmediatamente viola eso. Entonces, el método de clase base probablemente debería ser 'sub stuff {croak}'. –

+0

@Sinan Iba por algo como C++: virtual void stuff() = 0; –

+0

@Sinan Tengo dos preocupaciones al agregar el croak a las cosas: 1) no compiló para mí y 2) se podría argumentar que croak es una forma de implementación, que (a menos que malinterprete la definición de funciones virtuales puras)) es exactamente lo contrario de lo que estoy buscando. Estoy editando sub cosas {; } ser sub cosas; –

2

Parece que no puedo hacer exactamente lo que quiero con alces, pero puede llegar muy cerca con Roles. Aquí está la información del manual de Moose entry para las funciones:

Roles Versus clases abstractas base

Si está familiarizado con el concepto de clases base abstractas en otros idiomas, puede tener la tentación para usar los roles de la misma manera.

Puede definir una función "solo de interfaz" , que solo contiene una lista de métodos necesarios.

Sin embargo, cualquier clase que consume este papel debe implementar todos los métodos necesarios , ya sea directa o través de la herencia de un padre. Usted no puede retrasar el requisito del método para que se puedan implementar en futuras subclases.

Dado que la función define los métodos requeridos directamente, al agregar una clase base a la mezcla no se lograría nada. Recomendamos que simplemente consuma la función de interfaz en cada clase que implementa esa interfaz.

+0

complemento! Tu respuesta apareció justo cuando estaba ordenando la mía ;-) – draegtun

+0

@draegtun ¡Qué divertido es eso! Su respuesta es realmente útil, especialmente para las personas que buscan implementar interfaces con Moose. Me acaba de ocurrir una pregunta extraña que estoy descubriendo a través de nuevas investigaciones que quizás no tengan una respuesta determinista. Todavía estoy tratando de decidir si esto es porque no entendí completamente el área antes de preguntar, o si a Moose le falta esta característica;) –

+2

Hmm. ¿Solo soy yo o esa ayuda realmente no es muy útil? Parece decir 'si quieres implementar una clase abstracta con un rol, no funciona porque no son la misma cosa; en cambio, * mira hacia allí, ¡un cerdo volador *! Todavía estaría interesado en (a) cómo hacer una jerarquía de clases abstractas (específicamente si MooseX :: ABC se considera bueno o no) o alternativamente (b) por qué el ABC es malo para los programas Moose. – ijw

5

También puede ser que desee echar un vistazo a Jesse Luehrs' MooseX::ABC. Parece muy similar a algunas de las implementaciones aquí. Desde la sinopsis:

package Shape; 
use Moose; 
use MooseX::ABC; 

requires 'draw'; 

package Circle; 
use Moose; 
extends 'Shape'; 

sub draw { 
    # stuff 
} 

my $shape = Shape->new; # dies 
my $circle = Circle->new; # succeeds 

package Square; 
use Moose; 
extends 'Shape'; # dies, since draw is unimplemented 

Sé que Jesse es un programador de C++ durante el día.

+0

Gracias por la sugerencia, definitivamente voy a comprobarlo. –

+0

Enlace actualizado de apuntar a la versión 0.20 a la versión actual. La versión 0.30 agregó clases base abstractas de subclases con otras clases abstractas. – spazm

Cuestiones relacionadas