La simulación de los aspectos de la electricidad estática a escribir en una lengua de pato-mecanografiado

StackOverflow https://stackoverflow.com/questions/2933438

Pregunta

En mi trabajo actual Estoy construyendo un conjunto de scripts de Perl que dependen en gran medida de los objetos. (Usando bless() de Perl en un hash de llegar lo más cerca posible OO)

Ahora, a falta de una mejor manera de expresar esto, la mayoría de los programadores en mi empresa no es muy inteligente. Peor aún, no lo hacen como la lectura de la documentación y parecen tener problemas para entender el código de otras personas. codificación vaquero es el juego aquí. Cada vez que se encuentran con un problema y tratar de solucionarlo, ellos vienen con una solución horrible que realmente no resuelve nada y por lo general lo hace peor.

Este resultado en mí, francamente, no confiar en ellos con el código escrito en el lenguaje de pato mecanografiadas. A modo de ejemplo, veo demasiados problemas con ellos no conseguir un error explícito para el mal uso de los objetos. Por ejemplo, si el tipo de A tiene foo miembro, y lo hacen algo parecido, instance->goo, ellos no van a ver el problema de inmediato. Se devolverá un valor nulo / sin definir, y que probablemente va a perder una hora de encontrar la causa. Luego terminar cambiando algo más porque no se identifican adecuadamente el problema original.

Así que estoy de intercambio de ideas de una forma de mantener mi lenguaje de script (su rápido desarrollo es una ventaja) sino dar un mensaje de error explícito cuando un objeto no se utiliza correctamente. Me doy cuenta de que, dado que no es una etapa de compilación o tipos estáticos, el error tiene que ser en tiempo de ejecución. Estoy bien con esto, siempre y cuando el usuario recibe un aviso muy explícito diciendo "este objeto no tiene X"

Como parte de mi solución, no quiero que sea necesario que compruebe si existe un método / variable antes de intentar utilizarlo.

A pesar de que mi trabajo es en Perl, creo que esto puede ser independiente del lenguaje.

¿Fue útil?

Solución

Si tiene cualquier tiro de añadir módulos para su uso, prueba a Moose . Proporciona más o menos todo las características que usted desea en un entorno de programación moderno, y más. Esto lo hace la comprobación de tipos, excelente herencia, tiene capacidades de introspección, y con MooseX :: Declare , una de las mejores interfaces para las clases de Perl que hay. Echar un vistazo:

use MooseX::Declare;

class BankAccount {
    has 'balance' => ( isa => 'Num', is => 'rw', default => 0 );

    method deposit (Num $amount) {
        $self->balance( $self->balance + $amount );
    }

    method withdraw (Num $amount) {
        my $current_balance = $self->balance();
        ( $current_balance >= $amount )
            || confess "Account overdrawn";
        $self->balance( $current_balance - $amount );
    }
}

class CheckingAccount extends BankAccount {
    has 'overdraft_account' => ( isa => 'BankAccount', is => 'rw' );

    before withdraw (Num $amount) {
        my $overdraft_amount = $amount - $self->balance();
        if ( $self->overdraft_account && $overdraft_amount > 0 ) {
            $self->overdraft_account->withdraw($overdraft_amount);
            $self->deposit($overdraft_amount);
        }
    }
}

creo que es muy bueno, a mí mismo. :) Es una capa sobre el sistema objeto de Perl, por lo que funciona con cosas que ya tiene (básicamente).

Con alces, puede crear subtipos con mucha facilidad, por lo que puede asegurarse de que su entrada es válida. Los programadores perezosos están de acuerdo: con tan poco que tiene que hacerse para que los subtipos de trabajo en Moose, es más fácil hacer ellos que no! (De Cookbook 4 )

subtype 'USState'
    => as Str
    => where {
           (    exists $STATES->{code2state}{ uc($_) }
             || exists $STATES->{state2code}{ uc($_) } );
       };

Y Tada, el estadoEEUU es ahora un tipo se puede usar! Sin ningún problema, sin despeinarse, y sólo una pequeña cantidad de código. Se va a lanzar un error si no es correcto, y todos los consumidores de la clase tienen que hacer es pasar un escalar con esa cadena en ella. Si está bien (que debe ser ... ¿verdad? :)) Lo usan como normal, y su clase están protegidos de la basura. ¿Cómo bueno es que!

Moose tiene un montón de cosas impresionantes como este.

confiar en mí. Echale un vistazo. :)

Otros consejos

En Perl,

  • que sea necesario que use strict y use warnings están en en el 100% del código

  • Usted puede tratar de hacer una variables miembro privadas mediante la creación de casi cierres . Un muy buen ejemplo es "variables miembro privadas, una especie de" sección en la http : //www.usenix.org/publications/login/1998-10/perl.html . Ellos no son 100% privada, pero bastante no-obvio cómo el acceso a menos que realmente sepa lo que está haciendo (y los necesita para leer el código y hacer la investigación para descubrir cómo).

  • Si no desea cierres de uso, el siguiente enfoque funciona algo así:

    Haga todas sus variables miembro del objeto (también conocido como llaves objeto hash en Perl) envueltos en descriptores de acceso. Hay maneras de hacer esto de manera eficiente de codificación de las normas POV. Uno de los menos segura es de clase :: :: De acceso rápido. Estoy seguro de Moose tiene mejores maneras pero no estoy tan familiarizado con los alces.

    Asegúrese de "ocultar" variables miembro reales en los nombres de convenciones-privada, por ejemplo, $object->{'__private__var1'} sería la variable miembro, y $object->var1() sería un descriptor de acceso getter / setter.

    NOTA: Para el último, Clase :: :: De acceso rápido es malo ya que sus variables que lo componen comparten nombres con descriptores de acceso. Pero usted puede tener constructores muy sencillos que funcionan igual que la clase :: :: De acceso rápido y crear valores clave como $ obj -.> { '__ private__foo'} para "foo"

    Esto no evitará que disparar en el pie, sino que hará que sea mucho más difícil hacerlo.

    En su caso, si utilizan o $obj->goo $obj->goo(), que obtendrían un error de ejecución, al menos en Perl.

    Ellos, por supuesto, podría salir de su manera de hacer $obj->{'__private__goo'}, pero si lo hacen la basura gonzo vaquero debido a la pereza, este último es mucho más trabajo que hacer el $obj->foo() correcta.

    También puede tener un escáner de código base que detecta Las cadenas de tipo $object->{"_, aunque desde su descripción que podría no funcionar como un elemento disuasorio tanto.

Se puede usar Clase :: InsideOut o objeto :: InsideOut que le dan cierto privacidad de los datos. En lugar de almacenar datos en una referencia de hash bendito, una referencia escalar bendito se utiliza como una clave para hashes de datos léxicos. Para acortar una larga historia, si sus compañeros de trabajo tratan $obj->{member} que obtendrá un error de tiempo de ejecución. No hay nada en $obj para ellos para agarrar al y no hay manera fácil de conseguir en los datos excepto a través de descriptores de acceso.

Aquí es una discusión de la técnica de dentro a fuera y varios implementaciones .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top