Simulieren von Aspekten der statischen Typisierung in einer duck-typed Sprache

8

In meinem aktuellen Job erstelle ich eine Reihe von Perl-Skripten, die stark von Objekten abhängen. (Verwenden Sie Perls bless() auf einem Hash, um so nahe wie möglich an OO heranzukommen)

Jetzt, aus Mangel an einer besseren Art, dies zu setzen, sind die meisten Programmierer in meiner Firma nicht sehr schlau. Schlimmer noch, sie mögen es nicht, Dokumentation zu lesen, und sie haben offenbar Probleme, den Code anderer Leute zu verstehen. Cowboy-Codierung ist das Spiel hier. Wann immer sie auf ein Problem stoßen und versuchen, es zu beheben, finden sie eine schreckliche Lösung, die tatsächlich nichts löst und es normalerweise noch schlimmer macht.

Das führt dazu, dass ich ihnen ehrlich gesagt nicht mit Code vertraue, der in der Sprache geschrieben ist, in der die Ente geschrieben ist. Als ein Beispiel sehe ich zu viele Probleme damit, dass sie keinen expliziten Fehler für den Missbrauch von Objekten bekommen. Zum Beispiel, wenn der Typ A Mitglied foo hat, und sie etwas wie instance->goo tun, werden sie das Problem nicht sofort sehen. Es wird einen Null- undefinierten Wert zurückgeben, und sie werden wahrscheinlich eine Stunde damit verschwenden, die Ursache zu finden. Dann am Ende etwas anderes ändern, weil sie das ursprüngliche Problem nicht richtig identifiziert haben.

Ich suche also nach einer Möglichkeit, meine Skriptsprache beizubehalten (die schnelle Entwicklung ist von Vorteil), gebe aber eine explizite Fehlermeldung aus, wenn ein Objekt nicht richtig verwendet wird. Da es keine Kompilierstufe oder statische Typisierung gibt, muss der Fehler zur Laufzeit auftreten. Mir geht es gut, solange der Benutzer eine sehr deutliche Nachricht erhält, dass "dieses Objekt kein X hat"

Als Teil meiner Lösung möchte ich nicht, dass sie überprüfen, ob eine Methode / Variable existiert, bevor Sie versuchen, sie zu verwenden.

Obwohl meine Arbeit in Perl ist, denke ich, dass dies sprachunabhängig sein kann.

    
Mike 29.05.2010, 01:50
quelle

3 Antworten

15

Wenn Sie Fotos davon haben, Module hinzuzufügen, versuchen Sie Elch . Es bietet so ziemlich alle Funktionen, die Sie in einer modernen Programmierumgebung wünschen, und mehr. Es gibt Typprüfung, ausgezeichnete Vererbung, hat Introspektionsfähigkeiten, und mit MooseX :: Declare , einer der nettesten Schnittstellen für Perl-Klassen da draußen. Schau es dir an:

%Vor%

Ich denke, es ist ziemlich cool, ich selbst. :) Es ist eine Ebene über dem Objektsystem von Perl, also funktioniert es mit Dingen, die du bereits hast (im Grunde.)

Mit Moose können Sie Subtypen sehr einfach erstellen, so dass Sie sicherstellen können, dass Ihre Eingabe gültig ist. Faule Programmierer sind sich einig: Mit so wenig, dass Subtypen in Moose funktionieren müssen, ist es einfacher, sie zu machen als nicht! (aus Kochbuch 4 )

%Vor%

Und Tada, der US-Bundesstaat ist jetzt ein Typ, den du benutzen kannst! Kein Aufwand, kein Muss und nur eine kleine Menge Code. Wenn es nicht stimmt, wird ein Fehler ausgegeben, und alle Benutzer Ihrer Klasse müssen einen Skalar mit dieser Zeichenfolge übergeben. Wenn es in Ordnung ist (was es sein sollte ... richtig? :)) Sie benutzen es wie normal, und Ihre Klasse ist vor Müll geschützt. Wie schön ist das!

Elch hat jede Menge toller Sachen wie diese.

Vertrau mir. Hör zu. :)

    
Robert P 29.05.2010, 03:09
quelle
4

In Perl

  • machen es erforderlich, dass use strict und use warnings in 100% des Codes aktiviert sind

  • Sie können versuchen, eine fast private Membervariable zu erstellen, indem Sie erstellen Schließungen . Ein sehr gutes Beispiel ist der Abschnitt "Private Member-Variablen, Sort of" in Ссылка . Sie sind nicht 100% privat, aber ziemlich unansehnlich, wie man Zugang erhält, wenn Sie nicht wirklich wissen, was Sie tun (und verlangen, dass sie Ihren Code lesen und recherchieren, um herauszufinden, wie).

  • Wenn Sie keine Closures verwenden möchten, funktioniert der folgende Ansatz gut:

    Machen Sie alle Ihre Objekt-Member-Variablen (auch Objekt-Hash-Schlüssel in Perl genannt) in Accessoren verpackt. Es gibt Möglichkeiten, dies effizient von Codierungsstandards POV zu tun. Eines der sichersten ist Class :: Accessor :: Fast. Ich bin sicher, Elch hat bessere Wege, aber ich kenne Elch nicht so gut.

    Stellen Sie sicher, dass Sie die tatsächlichen Membervariablen in Private-Convention-Namen, z. $object->{'__private__var1'} wäre die Membervariable und $object->var1() wäre ein Getter / Setter-Accessor.

    HINWEIS: Für die letzte Klasse :: Accessor :: Fast ist schlecht, da seine Mitgliedsvariablen Namen mit Accessoren teilen. Aber Sie können sehr einfache Builder verwenden, die genau wie Class :: Accessor :: Fast funktionieren und Schlüsselwerte wie $ obj- & gt; {'__ private__foo'} für "foo" erstellen.

    Das hindert sie nicht daran, sich in den Fuß zu schießen, aber WIRD es viel schwerer machen, das zu tun.

    Wenn sie in% $obj->goo oder $obj->goo() verwenden, würden sie zumindest in Perl einen Laufzeitfehler bekommen.

    Sie könnten natürlich alles Mögliche tun, um $obj->{'__private__goo'} zu machen, aber wenn sie den Gonzocowboy-Mist wegen reiner Faulheit machen, ist letzteres viel mehr Arbeit als das richtige $obj->foo() .

    Sie können auch einen Scan von code-base haben, der $object->{"_ type Strings erkennt, obwohl das aus Ihrer Beschreibung nicht so abschreckend wirkt.

DVK 29.05.2010 01:58
quelle
4

Sie können Class :: InsideOut oder Objekt :: InsideOut , das Ihnen wahren Datenschutz bietet. Anstatt Daten in einer gesegneten Hash-Referenz zu speichern, wird eine gesegnete Skalarreferenz als Schlüssel für lexikalische Datenhashes verwendet. Lange Rede, kurzer Sinn: Wenn Ihre Mitarbeiter $obj->{member} ausprobieren, erhalten sie einen Laufzeitfehler. Es gibt nichts in $obj für sie zu greifen und keine einfache Möglichkeit, an die Daten zu gelangen, außer durch Accessoren.

Hier ist eine Diskussion der Inside-Out-Technik und verschiedener Implementierungen .

    
Schwern 29.05.2010 21:57
quelle