• Publicidad

Interfaces, en Perl

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Interfaces, en Perl

Notapor gaston » 2010-01-18 20:46 @907

¡ Hola Perleros !

Hace ya un tiempo que estoy metido en Perl, y ahora, armando un proyecto GPL, me doy cuenta que según la arquitectura que estoy planteando necesito que varias clases implementen una "interfaz" (por ahora estoy planteando una arquitectura genérica, pues no sé si existe esto en perl) como tienen otros lenguajes OOP.

La idea es, por ejemplo, poder decir: "MiClase implements MiInterface".

¿Se puede hacer esto en Perl? Estoy usando el polimorfismo y no quiero que ninguna clase nueva que se agregue deje de tener los métodos que yo les impongo en la Interfaz.

Si no existe... ¿hay manera de emularlo?

Gracias amigos, espero puedan darme una mano.
Saludos

Gastón.
gaston
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2008-01-28 22:16 @969

Publicidad

Re: Interfaces, en Perl

Notapor danimera » 2010-01-18 23:46 @032

Eso lo puedes lograr aprendiendo a crear tus propios módulos de Perl y a usarlos, hay varios hilos que hablan sobre eso en el foro.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Interfaces, en Perl

Notapor Perl user » 2010-01-19 02:59 @166

Échale un vistazo a Moose, en especial a Moose::Role. Antes de Moose, una de las ténicas utilizadas, puesto que Perl soporta "multiple herencia" por medio de @ISA, era declarar "clases abstractas" cuya la implementación de los métodos virtuales o abstractos consiste en simplemente invocar a Carp::croak, con esto indicándole al cliente que debe implementarlos en su clase especializada, de esa manera se definen clases Base.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package Base;
  2. use Carp qw(croak);
  3.  
  4. sub foo {
  5.     croak ("Necesitas implementar este método");
  6. }
  7.  
  8. package MiClase;
  9. use base 'Base';
  10.  
  11. sub new { }
  12.  
  13. sub foo {
  14.    # aquí implementación de foo
  15. }
  16.  
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Cómo podrás observar, Perl jamás forzará la verificación de dichos métodos "abstratos" o "virtuales" que defines en tu clase base, sino, lo único que haces es diseñar tu API y permitir que el que implemente la especialización se encargue de dichos métodos. En este caso la recomendación es comentar si es necesario siempre implementarlos todos, o solo algunos. De la misma manera, como tu clase base no cuenta con un constructor, no podrá ser instanciada, pero si alguien invoca uno de los métodos abstractos y no está implementado, por polimorfismo, dicho método será invocado el cual abortará con una llamada a croak.

En el caso de usar Moose:Role (o el uso de traits), es que Moose te proveerá de mecanismos de verificación de tipos y otras monerías en las que recomiendo checar el manual y el cookbook.
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

Re: Interfaces, en Perl

Notapor explorer » 2010-01-19 06:12 @300

gaston escribiste:¿Se puede hacer esto en Perl?

Depende de la forma de programar que estés usando. En perldoc tienes unos cuantos tutoriales que dan pautas de la programación básica orientada a objetos en Perl.

En módulos, hay unos cuantos, como el Class::Interface, tanto para definir clases abstractas como de interfaz.

La solución más moderna pasa por programar en Moose (o Mouse). Los interfaces se llaman roles (en Moose::Manual::Concepts). Lo tienes más descrito en Moose::Cookbook en la sección Moose Roles.

P.D. (este mensaje tenía que haber salido antes que el de Perl User. Lo siento.)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Interfaces, en Perl

Notapor gaston » 2010-01-19 22:32 @980

Amigos:
Ante todo, gracias por tomarse un tiempito.

Me han abierto una puerta enorme, ya que desconocía estos módulos.

En estos días probaré las opciones que me recomendaron, y seguramente con esto tengo de sobra para solucionar el inconveniente.

Gracias nuevamente.
¡ Saludos !

Gastón.
gaston
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2008-01-28 22:16 @969

Re: Interfaces, en Perl

Notapor gaston » 2010-02-04 15:52 @702

¡Hola, gente!

Bueno, lamento retomar el tema, pero tengo unas dudillas.

Estuve tratando de implementar Class::Interface porque me parece más sencillo y no da tantas vueltas como Moose (de todas formas esto lo voy a usar más adelante).

La cuestión es que no he podido usar esa clase porque no me funciona.

Puntualmente me da este error: "tries to implement non existing interface".

Estuve viendo el código y usando tan cual muestran los ejemplos, y nada. Probé varias formas de llamadas (intercambiando las llamadas de lugar solamente) y nada.

El ejemplo que usé es el mismo que trae en su PM y tampoco me funciona.

¿Les ha pasado esto alguna vez a ustedes? Si es así y pudieran darme una mano, se los agradecería.

La prueba que hice fue:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package Bouncable;
  2.  
  3.   use Class::Interface;
  4.   &interface;   # this actually declares the interface
  5.  
  6.   sub bounce;
  7.   sub getBounceBack;
  8.  
  9.   1;
  10.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package Ball;
  2.  
  3.   use Class::Interface;
  4.   &implements( 'Bouncable' );
  5.  
  6.   sub bounce {
  7.     my $self = shift;
  8.     print "The ball is bouncing @ ".$self->getBounceBack." strength"
  9.   }
  10.  
  11.   sub getBounceBack {
  12.     return 10;
  13.   }
  14.  
  15.   1;
  16.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package AbstractInterestCalculator;
  2.  
  3.   use Class::Interface;
  4.   &abstract;   # this actually declares this class to be abstract;
  5.  
  6.   use Class::AccessorMaker {
  7.     interest => 5.1,
  8.     maxInterestValue => 0,
  9.   }
  10.  
  11.   # a hook for doing calculations
  12.   sub calculate {
  13.     my ( $self, $value ) = @_;
  14.  
  15.     $self->prepare();
  16.     $value += $self->getInterestValue( $value );
  17.  
  18.     return $value;
  19.   }
  20.  
  21.   sub prepare;          # prepare calculations
  22.   sub getInterstValue;  # get the interest value
  23.  
  24.   1;
  25.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package LowInterestCalculator;
  2.  
  3.   use Class::Interface;
  4.   &extends( 'AbstractInterestCalculator' );
  5.  
  6.   sub prepare {
  7.     my ( $self ) = @_;
  8.     $self->interest(1.3);
  9.  
  10.     # we don't give interest if the value of the account is or
  11.     # exceeds $10.000
  12.     $self->maxInterestValue(10000)
  13.   }
  14.  
  15.   sub getInterstValue {
  16.     my ( $self, $value ) = @_
  17.  
  18.     if ( $self->maxInterestValue &&
  19.          $value >= $self->maxInterestValue ) {
  20.       return 0;
  21.     }
  22.  
  23.     $value *= $self->interest;
  24.  
  25.     return $value;
  26.   }
  27.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Lo que pretendo en principio es que no me tire ningún error, luego me centraré en los detalles.

Cada archivo lo puse separado con el nombre de su Package con extensión pm.

¡ Gracias !

P.D.: El error que les marqué es uno de ellos, pero si puedo saber por qué me lo tira, resolveré el otro error que es similar.
gaston
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2008-01-28 22:16 @969

Re: Interfaces, en Perl

Notapor explorer » 2010-02-04 18:38 @818

No estoy seguro, pero juraría que

* en la línea 22 de AbstractInterestCalculator, y

* en la línea 15 de LowInterestCalculator,

les falta una letra 'e'. Es decir, en vez de getInterstValue(), debería ser getInterestValue().
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Interfaces, en Perl

Notapor gaston » 2010-02-07 15:14 @676

¡ Hola Explorer !
Bueno, ante todo, gracias por las molestias.

En efecto, ese es un error, pero no es el error por el cual no me está funcionando.

Aún no lo he podido resolver, pero sigo en carrera. Por ahora, estoy usando 'use base' con llamadas con Carp; mientras, voy a ver si lo resuelvo.

Solamente con el ejemplo de 'package Bouncable' con 'package Ball' (Ball implementa Bouncable) tira el error. Por ahora, el error está cuando está en la función '&interface' de 'Bouncable', y no Ball (cuando hace &implements).

Si logro resolverlo, por lo menos me doy una vuelta por el foro para dejar la solución, así alguien que tenga el mismo problema ya lo tiene resuelto.

Gracias por la ayuda.

¡ Saludos !
gaston
Perlero nuevo
Perlero nuevo
 
Mensajes: 7
Registrado: 2008-01-28 22:16 @969

Re: Interfaces, en Perl

Notapor explorer » 2010-02-07 18:38 @818

A ver... me he instalado la última versión de Class::Interface.

Luego, he escrito

Bouncable.pm:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package Bouncable;
  2.  
  3. use Class::Interface;
  4. interface;   # this actually declares the interface
  5.  
  6. sub bounce;
  7. sub getBounceBack;
  8.  
  9. 1;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Ball.pm:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. package Ball;
  2.  
  3. use Class::Interface;
  4. implements( 'Bouncable' );
  5.  
  6. sub new {
  7.   my $class = ref($_[0]) || $_[0]; shift;
  8.   return bless( {}, $class );
  9. }
  10.  
  11. sub bounce {
  12.     my $self = shift;
  13.     print "The ball is bouncing @ ".$self->getBounceBack." strength\n"
  14. }
  15.  
  16. sub getBounceBack {
  17.     return 10;
  18. }
  19.  
  20. sub otra {
  21.     my $self = shift;
  22.     print "Huy\n";
  23. }
  24.  
  25. 1;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Y finalmente, un programa que haga uso de Ball:
script.pl:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use Ball;
  4.  
  5. my $Ball = Ball->new;
  6.  
  7. $Ball->bounce();
  8. $Ball->otra();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si ejecuto script.pl, la salida es correcta:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
The ball is bouncing @ 10 strength
Huy
 
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Ahora bien, si en Bouncable.pm, agregamos
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub otrafuncion;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Ball fails to implement otrafuncion from Bouncable at Ball.pm line 4
Compilation failed in require at /home/explorer/Documents/Desarrollo/script.pl line 3.
BEGIN failed--compilation aborted at /home/explorer/Documents/Desarrollo/script.pl line 3.
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y nos avisa de que, efectivamente, nos falta por implementar otrafuncion() en Ball.pm.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 5 invitados

cron