Question

Dans mon emploi actuel je construis un ensemble de scripts Perl qui dépendent fortement des objets. (En utilisant la bless() de Perl sur un Hash pour obtenir le plus près possible OO)

Maintenant, faute d'une meilleure façon de mettre cela, la plupart des programmeurs de mon entreprise ne sont pas très intelligents. Pire encore, ils ne le font pas comme la lecture de la documentation et semblent avoir du mal à comprendre le code des autres. codage Cowboy est le jeu ici. Chaque fois qu'ils rencontrent un problème et essayer de le réparer, ils viennent avec une solution horrible qui permet de résoudre en fait rien et fait souvent qu'empirer les choses.

Il en résulte en moi, franchement, ne pas leur faire confiance avec le code écrit dans la langue de canard typé. À titre d'exemple, je vois trop de problèmes avec eux de ne pas obtenir une erreur explicite pour les objets abusant. Par exemple, si le type a A membre foo, et ils le font quelque chose comme, instance->goo, ils ne vont pas voir le problème immédiatement. Il retourne une valeur nulle / valeur non définie, et ils vont probablement perdre une heure à trouver la cause. Puis finir par changer autre chose parce qu'ils n'ont pas identifié le problème d'origine.

Je suis remue-méninges pour une façon de garder mon langage de script (son développement rapide est un avantage), mais un message d'erreur explicite lorsqu'un objet est pas utilisé correctement. Je me rends compte que depuis il n'y a pas une étape ou de la compilation typage statique, l'erreur devra être au moment de l'exécution. Je suis bien avec cela, tant que l'utilisateur obtient un avis très explicite en disant « cet objet n'a pas X »

Dans le cadre de ma solution, je ne veux pas qu'il soit nécessaire qu'ils vérifient si une méthode / variable existe avant d'essayer de l'utiliser.

Même si mon travail est en Perl, je pense que cela peut être agnostique de la langue.

Était-ce utile?

La solution

Si vous avez une prise de vue d'ajouter des modules à utiliser, essayez Moose . Il fournit à peu près toutes les fonctionnalités que vous voulez dans un environnement de programmation moderne, et plus encore. Il fait la vérification de type, un excellent héritage, a introspection des capacités, et MooseX :: Declare , l'une des interfaces les plus agréables pour les classes Perl là-bas. Jetez un coup d'oeil:

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);
        }
    }
}

Je pense assez cool il, moi-même. :) Il est une couche sur le système d'objet de Perl, il travaille avec des choses que vous avez déjà (essentiellement).

Avec Moose, vous pouvez créer des sous-types très facilement, de sorte que vous pouvez vous assurer que votre entrée est valide. programmeurs paresseux sont d'accord: avec si peu qui doit être fait pour que les sous-types de travail à Moose, il est plus facile de les faire que non! (À partir de livre de recettes 4)

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

Et Tada, le USState est maintenant un type que vous pouvez utiliser! Pas de chichi, pas muss, et juste une petite quantité de code. Il va lancer une erreur si ce qui ne va pas, et tous les consommateurs de votre classe ont à faire est de passer un scalaire avec cette chaîne en elle. Si elle est bien (ce qui devrait être ... non? :)) Ils l'utilisent comme d'habitude, et votre classe est protégé contre les déchets. Quel bel ça!

Moose a des tonnes de trucs super comme ça.

Faites-moi confiance. Vérifiez-le. :)

Autres conseils

En Perl,

  • faire nécessaire que use strict et use warnings sont dans 100% du code

  • Vous pouvez essayer de faire une des variables membres presque privé en créant fermetures . Un très bon exemple est « Variables membres privées, une sorte de » section http : //www.usenix.org/publications/login/1998-10/perl.html . Ils ne sont pas 100% privé, mais assez non évident de l'accès à moins que vous savez vraiment ce que vous faites (et les obliger à lire votre code et faire des recherches pour savoir comment).

  • Si vous ne voulez pas les fermetures d'utilisation, l'approche suivante fonctionne plutôt bien:

    Faire tous vos objets variables membres (alias clés de hachage objet en Perl) enveloppé dans accesseurs. Il y a plusieurs façons de le faire efficacement des normes de codage POV. L'un des moins sûr est classe :: :: accesseur rapide. Je suis sûr que Moose a de meilleures façons mais je ne suis pas familier avec Moose.

    Assurez-vous de « cacher » les variables membres réels dans les noms-convention privée, par exemple $object->{'__private__var1'} serait la variable membre et $object->var1() serait un accesseur getter / setter.

    NOTE: Pour la dernière, Class :: :: accesseur rapide est mauvais car ses variables membres partagent avec les noms accesseurs. Mais vous pouvez avoir des constructeurs très simples qui fonctionnent comme Class :: :: accesseur rapide et créer des valeurs clés telles que $ obj -.> { « __ private__foo »} pour « foo »

    Cela ne les se tirer une balle dans le pied de prévenir, mais fera beaucoup plus difficile de le faire.

    Dans votre cas, si elles utilisent $obj->goo ou $obj->goo(), ils obtiendraient une erreur d'exécution, au moins en Perl.

    Ils pourraient bien sûr sortir de leur façon de faire $obj->{'__private__goo'}, mais s'ils font les conneries de cow-boy gonzo en raison de la paresse pure, celle-ci est beaucoup plus de travail que de faire la $obj->foo() correcte.

    Vous pouvez également avoir une analyse de base de code qui détecte les chaînes de type $object->{"_, bien que de votre description qui pourrait ne pas fonctionner comme un moyen de dissuasion beaucoup.

Vous pouvez utiliser Class :: InsideOut ou objet :: InsideOut que vous donner la vraie confidentialité des données. Plutôt que de stocker des données dans une table de hachage béni, une référence scalaire béni est utilisé comme clé de hachages de données lexicales. Longue histoire courte, si vos collègues essaient $obj->{member} ils obtiennent une erreur de temps d'exécution. Il n'y a rien $obj pour eux de saisir à et pas facile d'obtenir les données que par accesseurs.

Voici une discussion de la technique inside-out et divers implémentations .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top