2009-06-24 20 views
14

Escribo clases de Perl para eliminar redundancias de scripts y dado que Perl tiene muchas formas de hacer clases, sigo teniendo problemas para hacer las clases correctamente. Entonces, ¿alguien tiene un ejemplo de mejor práctica de una clase?¿Cómo creo una clase Perl?

La mayor pregunta que tengo es si no debería haber variables globales en un módulo ¿cómo se usan las variables en sub() en un módulo? Como Java self-> foo = 10;

Básicamente solo dame una clase escrita en Java o C# o incluso C++ y escribe lo mismo en Perl. También puntos extra para mostrar cómo hacer las variables privadas, protegidas y de clase pública correctamente. La herencia y las interfaces serían útiles, supongo.

+1

Las características OO de Perl son un poco deficientes en el mejor de los casos ...: PI iría a un módulo .pm simple y vería cómo se implementan –

Respuesta

24

una forma típica de la creación de objetos de Perl es 'bendecir' un hashref. La instancia del objeto puede almacenar datos contra su propio conjunto de claves hash.

package SampleObject; 

use strict; 
use warnings; 

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

sub sample_method { 
    my ($self) = @_; 
    print $self->{sample_data}; 
} 

y uso:

my $obj = SampleObject->new(sample_data => 'hello world', 
          more_data => 'blah blah blah'); 
$obj->sample_method(); 

Como alternativa, los métodos de acceso/mutantes se pueden añadir (véase Clase :: Accessor, Clase :: :: Accessor encadenada, etc. para facilitar la puesta en marcha de estos) - esto hace que sea más fácil validar los datos y agregar encapsulamiento (no se aplica en Perl, debe asegurarse de que su código no vaya alrededor de un acceso/mutador apropiado y acceder a los datos en el hashref bendito directamente).

+0

Parece el más elegante de las dos respuestas. – kthakore

16

Consulte Moose, que es una extensión del sistema de objetos Perl 5.

Lo siguiente le ayudará en el aprendizaje de los alces:

+0

Me doy cuenta de que esta es una respuesta popular, sin embargo, en realidad no me mostró cómo hacer mis propias clases similares a otros lenguajes OOP. – kthakore

+2

Sin embargo, la publicación lo señaló a usted. –

+2

Tienes razón, en cambio él te dio enlaces que te muestran cómo hacerlo. ¿Por qué perder bytes copiando/pegando desde otro lugar cuando un enlace es mucho mejor? – mpeters

23

Bueno, el Perl es fácil, pero estoy oxidado en los otros idiomas, así que los actualizaré un poco. Aquí está una clase normal de Perl:

#!/usr/bin/perl 

package Person; 

use strict; 
use warnings; 
use Carp; 

sub new { 
    my $class = shift; 
    my $self = { @_ }; 
    croak "bad arguments" unless defined $self->{firstname} and defined $self->{lastname}; 
    return bless $self, $class; #this is what makes a reference into an object 
} 

sub name { 
    my $self = shift; 
    return "$self->{firstname} $self->{lastname}"; 
} 

#and here is some code that uses it 
package main; 

my $person = Person->new(firstname => "Chas.", lastname => "Owens"); 
print $person->name, "\n"; 

aquí es la misma clase escrito usando los nuevos objetos de estilo de los alces:

#!/usr/bin/perl 

package Person; 

use Moose; #does use strict; use warnings; for you 

has firstname => (is => 'rw', isa => 'Str', required => 1); 
has lastname => (is => 'rw', isa => 'Str', required => 1); 

sub name { 
    my $self = shift; 
    return $self->firstname . " " . $self->lastname; 
} 

#and here is some code that uses it 
package main; 

my $person = Person->new(firstname => "Chas.", lastname => "Owens"); 
print $person->name, "\n"; 

Y MooseX :: Declare elimina la necesidad de aún más código y hace que las cosas se ven nice:

#!/usr/bin/perl 

use MooseX::Declare; 

class Person { 
    has firstname => (is => 'rw', isa => 'Str', required => 1); 
    has lastname => (is => 'rw', isa => 'Str', required => 1); 

    method name { 
      return $self->firstname . " " . $self->lastname; 
    } 
} 

#and here is some code that uses it 
package main; 

my $person = Person->new(firstname => "Chas.", lastname => "Owens"); 
print $person->name, "\n"; 

Una nota rápida, estas dos clases son las dos primeras clases de Moose que he escrito. Y aquí es un poco de código muy oxidada C++ (no cortarse con ella o se necesita una vacuna contra el tétanos):

#include <stdio.h> 
#include <string.h> 

class Person { 
    char* firstname; 
    char* lastname; 

    public: 
    Person(char* first, char* last) { 
     firstname = first; 
     lastname = last; 
    } 

    char* name(void) { 
     int len = strlen(firstname) + strlen(lastname) + 1; 
     char* name = new char[len]; 
     name[0] = '\0'; 
     strcat(name, firstname); 
     strcat(name, " "); 
     strcat(name, lastname); 
     return name; 
    } 
}; 

int main(void) { 
    Person* p = new Person("Chas.", "Owens"); 
    char* name = p->name(); 
    printf("%s\n", name); 
    delete name; 
    delete p; 
    return 0; 
} 
+0

Exactamente lo que quería. Usted gana 10 puntos de internet, señor. – kthakore

4

Además de alces, que la gente ya se han mencionado ...

Si está simplemente hablando de clases (por lo tanto, no de objetos), normalmente crea datos de clase con variables léxicas con un alcance en el archivo y usa una clase por archivo. Usted crea métodos de acceso para tratar con ellos. Hay varias formas de lidiar con eso.

Sin embargo, parece que necesita comenzar con algo como Intermediate Perl o Damian Conway's Object Oriented Perl.Hay mucho que explicar para que cualquiera se tome el tiempo de reproducir todo eso en una respuesta Stackoverflow.

+0

oooh buenos libros. Gracias. – kthakore

Cuestiones relacionadas