2010-08-11 9 views
6

primera publicación de un usuario novato. Cada pregunta que hago en Google parece traerme aquí y siempre obtengo una excelente respuesta a lo que estoy buscando; así que, naturalmente, esta fue mi primera parada cuando comencé a reflexionar sobre el uso de las bendiciones en Perl.¡Para bendecir o no bendecir, esa es mi pregunta!

Acabo de entrar en Perl's OOP y acabo de leer la publicación preguntando qué es lo que hace la bendición. Ahora entiendo que hace referencia a una matriz escalar/hash/a un objeto, 'adjuntándola', si se quiere.

En la mayoría de los ejemplos de clases que veo en Perl, que no parecen tener propiedades que estoy acostumbrado a ver en otros idiomas ...

{ package Person; 
    my $property = "This is what I'm talking about :)"; 

    sub new { ... } 
    ... 
} 

tanto, he creado una estúpida clase con una propiedad para ver qué pasaría. Le di a la propiedad el valor 'NIL' desde el principio y luego 'Not Nil!' en el constructor Usando un método LIST, pude imprimir la propiedad y, como esperaba, imprimí '¡Nada!'

Mi pregunta es, si las propiedades funcionan de la misma manera que esperaba que funcionen (declaradas en el cuerpo), entonces, ¿por qué usar bless en absoluto? ¿Cuál es el beneficio adicional de tener esa referencia cuando podría simplemente crear un escalar/hash/array como una propiedad, o crear las referencias que desee como propiedad?

espero que he explicado lo que estoy tratando de pedir lo suficientemente bien, muy verde con Perl :)

+0

Me pregunto cuándo van a obtener en torno a la implementación de "herir" ... –

+0

Wow, realmente no me di cuenta de que mi pregunta era estúpida ... ¿Cómo? .. me tomando su consejo ahora Hamish. – NiRC

+3

No estoy seguro de lo que dice @Hamish Grubijan, pero su pregunta no es estúpida. Supongo que está diciendo que Perl no es un lenguaje bien considerado en promedio en este sitio, pero las preguntas de Perl son bienvenidas :) – Jacob

Respuesta

8

lo que hizo con $ propiedad en este caso se declara una variable en su alcance la "Persona" del paquete. Cambia eso dentro (o afuera usando $ Person :: property) del paquete, y cualquier objeto que se refiera a él verá la variable actualizada, por lo que actúa mucho como un "atributo estático (Java)" sin ninguna real Alcance "privado". Por convención, las cosas ocultas en Perl ("privadas" o "protegidas") llevan como prefijo un guión bajo, pero, por supuesto, esto no se aplica.

En realidad, no hace una nueva clase, como señaló, con la palabra clave "paquete"; puede usar "paquete" sin OOP en absoluto. Eso simplemente crea un "espacio de nombre" separado.

La ventaja de "bendecir" una variable, casi siempre una referencia de hash por lo que he visto, es que puede tener métodos, al igual que cualquier otro lenguaje OOP. Solo recuerde bendecir lo que devuelva en la nueva {} subrutina ("nuevo" no es en realidad una palabra reservada, solo una convención). Cuando se llama a un método en el "objeto" (una estructura de datos bendecida como un hashref), el primer argumento del método es la propia estructura de datos. Entonces, si tienes un hashref llamado $ myobject, que está bendecido para AwesomeClass, y defines un método en AwesomeClass llamado doSomethingAwesome, que necesita aceptar una variable, tendrías que "cambiar" @_ (que es la lista de argumentos de la subrutina, o use $ _ [0]) para acceder al $ myobject hashref. Python hace algo similar, y todos los lenguajes pasan la referencia del objeto al método de alguna manera. ("this" palabra clave en muchos, consulte también "thiscall" convención de llamadas)

NB: He visto muchos ataques de Perl en mi tiempo, que solo han sido unos años como programador. Perl es un lenguaje impresionante que fue hecho por un lingüista muy inteligente (Larry Wall) y tiene seguidores fanáticos, más fanáticos a la vez que Ruby, quizás, pero no tanto como David Koresh. Perl hace las cosas de forma muy diferente que muchos idiomas, pero si observa las entradas de código de golf en este sitio y otras, puede ver claramente que se puede lograr mucho con muy poco Perl (no hay garantías sobre la legibilidad del código, ¡especialmente para los recién llegados!)

+0

¡Muchas gracias! Veo lo que estás diciendo ahora. Perl es de hecho muy diferente del C# al que estoy acostumbrado :) – NiRC

+3

¡Si David Koresh fuera algo así como Perl, habría más de una forma de salir del maldito compuesto! Y más de un módulo de supresión de incendios. – DVK

11

Bueno, esa no es la forma de crear clases en Perl.

Su variable $property se define en el alcance del paquete.Por lo tanto, solo habrá una copia por clase, en lugar de que cada objeto tenga su propia copia.

Se podría implementar una clase de tales objetos usando basado picadillo el camino largo y duro de la siguiente manera:

#!/usr/bin/perl 

package Person; 

use strict; use warnings; 

sub new { 
    my $class = shift; 
    my $self = {}; 
    bless $self => $class; 

    my ($arg) = @_; 
    for my $property (qw(message)) { 
     if (exists $arg->{$property}) { 
      $self->$property($arg->{$property}); 
     } 
    } 
    return $self; 
} 

sub message { 
    my $self = shift; 
    return $self->{message} unless @_; 
    my ($msg) = @_; 
    $self->{message} = $msg; 
} 

package main; 

my $person = Person->new({ 
    message => "This is what I'm talking about :)" 
}); 

print $person->message, "\n"; 

Ahora bien, esto se vuelve tedioso rápido. Por lo tanto, hay módulos que lo ayudan a lidiar con esto y le ayudan a definir sus clases de forma segura para la herencia.

Class::Accessor es uno de esos módulos de utilidad.

Para programas donde el tiempo de inicio no es un problema, debe considerar Moose. Con alces, puede escribir lo anterior como:

#!/usr/bin/perl 

package Person; 

use Moose; 

has 'message' => (is => 'rw', isa => 'Str'); 

__PACKAGE__->meta->make_immutable; 
no Moose; 

package main; 

my $person = Person->new({ 
    message => "This is what I'm talking about :)" 
}); 

print $person->message, "\n"; 

Debe leer y perldoc perltootMoose::Manual::Unsweetened de la forma habitual de hacer las cosas.

+1

Gracias a TON por esta publicación, enlaces muy útiles. Había estado usando perldoc un poco, pero mucha de la documentación es muy ... intimidatoria por decir lo menos :) – NiRC

+0

@NiRC - Recomiendo encarecer un par de libros (hay una pregunta de StackOverflow sobre los libros de Perl) ya no me molestaré en recomendar, aparte de los Sospechosos Usuales - Serie O'Reilly Perl). La documentación de Perl no es necesariamente un gran material de aprendizaje, me temo (a diferencia de ser un gran material de referencia una vez que pasas la curva de aprendizaje inicial) – DVK

+0

@Sinan = +1 para Moose. Y un probational -1 para escribir getter y setter separados en lugar de un método unificado "if no arguments, i a getter", los resultados de ala de Class :: Accessor :: Fast :) – DVK

4

Uf ... La respuesta de Sinan se aprendió totalmente demasiado para mi gusto, al menos 12 a.m. pasado :)

Tan aquel que da una más corta y algo menos Perly uno, sólo por el bien de la variedad.

Su pregunta es no es realmente sobre Perl por lo que yo puedo decir, y puede ser sólo Ased tan fácilmente en otra forma: "¿Por qué molestarse usando C++ y programación orientada a objetos en ella cuando C ya tiene estructuras"

En otras palabras, parece que se pregunta cuál es el punto de utilizar el paradigma de OOP.

La respuesta es, por supuesto, que ayuda a resolver ciertos problemas de ingeniería de software más fácil que la pura programación de procedimientos. Énfasis en cierto - OOP no es una panacea para cada problema, más que CUALQUIER técnica/enfoque/paradigma.

El uso de OOP (en forma de paquetes como clases y hash bendecidos como objetos en Perl) le permite disfrutar de los beneficios de la herencia, el polimorfismo y otros juegos de OOPyish con los que probablemente ya esté familiarizado. Perl OOP experience.

¿Puedes hacer el 100% de lo que hubieras hecho con un objeto bendecido con una estructura de datos pura? Absolutamente. ¿Sería el 100% de un código tan fácil/corto/legible/mantenible como puede lograr utilizando objetos? Lo más probable es que no, aunque depende de qué tan bien su código OOP aprovecha los beneficios que ofrece OOP (BTW, I tiene encontrado supuestamente código OOP (Perl y no) que no estaba tomando ninguna ventaja del paradigma OOP y podría tener se hizo más fácil de leer y entender si se hubiera despojado de su OOP Chrome).

+1

¡Todavía eres muy culto! :) El IME, la herencia y el polimorfismo son buenos toques, pero la recompensa real con OOP es que proporciona una manera limpia y fácil de asociar los comportamientos con los datos. Algunos de mis proyectos OOP usan polimorfismo y herencia. Pero todos ellos aprovechan la clara asociación de datos y acciones. En lugar de mirar una estructura compleja de múltiples capas y 27 funciones asociadas, puedo tener objetos Foo y Bar que están contenidos en un bonito objeto Baz, dividiendo los 27 métodos entre las clases según corresponda. – daotoad

5

El valor de bless 'un objeto es llegar a utilizar los métodos de un paquete en particular.

package MyClass; 
sub answer { my ($self)[email protected]_; return $self->{foo} * 42; } 

package main; 
my $object1 = { foo => 1, bar => "\t" }; 
my $object2 = bless { foo => 2, bar => "\t" }, "MyClass"; 

$ref1 = ref $object1;  # 'HASH' 
$ref2 = ref $object2;  # 'MyClass' 

$answer1 = $object1->answer;  # run time error 
$answer2 = $object2->answer;  # calls MyClass::answer, returns 2 * 42 = 84 
Cuestiones relacionadas