Frage

In meinem aktuellen Job, den ich baue eine Reihe von Perl-Skripten, die stark von Objekten abhängen. (Perl bless() auf einem Hash mit möglichst nahe an OO wie möglich zu erhalten)

Nun, aus Mangel an einem besseren Weg, dies zu setzen, die meisten Programmierer in meinem Unternehmen sind nicht sehr klug. Schlimmer noch, tun sie nicht wie Lesen der Dokumentation und Code ein Problem zu verstehen, andere Menschen zu haben scheinen. Cowboy-Codierung ist das Spiel hier. Jedes Mal, wenn sie auf ein Problem stoßen und versuchen, es zu beheben, kommen sie mit einer schrecklichen Lösung, die eigentlich nichts löst und in der Regel macht es noch schlimmer.

Diese Ergebnisse in mir, ehrlich gesagt, nicht mit dem Code zu vertrauen sie in Ente geschrieben typisierte Sprache. Als ein Beispiel, sehe ich zu viele Probleme mit ihnen keinen expliziten Fehler für missbräuchlich Objekte zu bekommen. wenn Typ A Mitglied foo Zum Beispiel hat, und sie tun so etwas wie, instance->goo, sie werden nicht das Problem sofort zu sehen. Es wird eine Null / undefined Wert zurück, und sie werden wahrscheinlich eine Stunde zu finden, um die Ursache verschwenden. am Ende dann etwas zu ändern sonst, weil sie nicht richtig, das ursprüngliche Problem identifizieren haben.

Also ich für eine Art und Weise bin Brainstorming meine Skriptsprache zu halten (seine schnelle Entwicklung ist ein Vorteil), aber eine explizite Fehlermeldung geben, wenn ein Objekt nicht ordnungsgemäß verwendet wird. Ich weiß, dass da keine Kompilierung Bühne oder statische Typisierung ist, wird der Fehler hat zur Laufzeit sein. Ich geht es gut mit diesem, solange der Benutzer einen sehr expliziten Hinweis bekommt sagen „dieses Objekt nicht X hat“

Als Teil meiner Lösung, ich will nicht, dass es erforderlich sein, dass sie prüfen, ob eine Methode / Variable, bevor Sie versuchen existiert, es zu benutzen.

Auch wenn meine Arbeit in Perl ist, ich denke, das sprachunabhängig sein kann.

War es hilfreich?

Lösung

Wenn Sie Schuss haben Module zu verwenden hinzufügen, versuchen Moose . Es bietet so ziemlich alle Funktionen, die Sie in einer modernen Programmierumgebung wollen würden, und vieles mehr. Es tut Typprüfung, hervorragende Erbe, hat Selbstbeobachtung Fähigkeiten und mit MooseX :: Declare , eine der schönsten Schnittstellen für Perl-Klassen gibt. Werfen Sie einen Blick:

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

Ich denke, es ist ziemlich cool, mich selbst. :) Es ist eine Schicht über die Perl-Objekt-System, so dass es mit Material arbeitet man bereits (im Wesentlichen).

Mit Moose können Sie Subtypen wirklich einfach erstellen, so dass Sie sicherstellen können Sie Ihre Eingabe gültig ist. Faule Programmierer einig: mit so wenig, dass zu machen Subtypen Arbeit in Moosen getan werden muss, ist es einfacher, sie als nicht zu tun! (Von Kochbuch 4 )

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

Und Tada, der US State ist nun ein Typ, den Sie verwenden können! Keine Hektik, kein Durcheinander, und nur eine kleine Menge an Code. Es wird einen Fehler aus, wenn es nicht richtig, und alle Verbraucher der Klasse tun müssen, ist in eine skalare mit dieser Zeichenfolge übergeben. Wenn es in Ordnung (das sollte es ... richtig? :)) Sie benutzen es wie normal, und Ihre Klasse ist von Müll geschützt. Wie schön ist das!

Moose haben Tonnen von awesome Sachen wie diese.

Trust me. Hör zu. :)

Andere Tipps

In Perl

  • macht es, dass use strict und use warnings erforderlich sind auf 100% des Codes

  • Sie können versuchen, eine fast privaten Membervariablen zu machen, indem Verschlüsse . Ein sehr gutes Beispiel ist „Private Membervariablen, Sort of“ im http : //www.usenix.org/publications/login/1998-10/perl.html . Sie sind nicht zu 100% privat, aber ziemlich un-klar, wie man Zugang, wenn Sie wirklich wissen, was Sie tun (und verlangen, daß sie den Code zu lesen und zu forschen, um herauszufinden, wie).

  • Wenn Sie nicht wollen, zu verwenden Schließungen, der folgenden Ansatz funktioniert etwas gut:

    Machen Sie alle Ihre Objektelementvariablen (auch bekannt als Objekt Hash-Schlüssel in Perl) in Accessoren gewickelt. Es gibt Möglichkeiten, diese von Coding-Standards POV effizient zu tun. Eines der am wenigsten sicher ist Class :: Accessor :: Schnell. Ich bin sicher, Moose bessere Möglichkeiten haben, aber ich bin nicht so vertraut mit Moosen.

    Achten Sie darauf, zu „verstecken“ tatsächliche Membervariablen in privaten Konvention Namen, z.B. $object->{'__private__var1'} wäre die Membervariable und $object->var1() wäre ein Getter / Setter Accessor sein.

    Hinweis: Für die letzte Klasse :: Accessor :: Schnell ist schlecht, da seine Mitgliedsvariablennamen mit Zugriffs teilen. Aber man kann sehr einfach Bauherren haben, dass die Arbeit wie Class :: Accessor :: Schnelle und Schlüsselwerte erstellen wie $ obj. -> { ‚__ private__foo‘} für „foo“

    Dies wird nicht verhindern, dass sie sich in den Fuß zu schießen, aber wird es sehr viel schwieriger machen, dies zu tun.

    In Ihrem Fall, wenn sie $obj->goo oder $obj->goo() verwenden, würden sie einen Laufzeitfehler erhalten, zumindest in Perl.

    Sie könnten natürlich von ihren Weg gehen $obj->{'__private__goo'} zu tun, aber wenn sie die gonzo Cowboy Mist tun durch schiere Faulheit ist die letztere viel mehr Arbeit als die richtige $obj->foo() tun.

    Sie können auch einen Scan-Code-Basis haben, die $object->{"_ Typ Strings erkennt, wenn auch aus Ihrer Beschreibung, die möglicherweise nicht als Abschreckung viel.

Sie können mit Class :: InsideOut oder Objekt :: InsideOut , die Sie wahre Datenschutz geben. Anstatt Daten in einem gesegneten Hashreferenz speichern, ein gesegneter skalare Sollwert wird als Schlüssel zum lexikalischen Daten Hashes verwendet. Lange Rede kurzer Sinn, wenn Ihre Mitarbeiter $obj->{member} versuchen werden sie einen Laufzeitfehler erhalten. Es gibt nichts in $obj für sie zu greifen an und keine einfache Möglichkeit, auf die Daten zu erhalten, außer durch Accessoren.

Hier ist eine Diskussion über die Inside-Out-Technik und verschiedenen Implementierungen .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top