Welchen Nutzen hat Smalltalks "werden:"?


12

Die become:Nachricht in Smalltalk bewirkt, dass ein Objekt in ein anderes geändert wird, was sich auf alle Verweise darauf auswirkt.

Welche Verwendung hat diese Sprachfunktion? Wird es in echtem Code verwendet? Ist es nur eine Neugier? Wird es als gute / schlechte Praxis angesehen, es anzuwenden?

Antworten:


11

Gilad Bracha spricht become:ausführlich über:

Eine der einzigartigsten und leistungsstärksten Funktionen von Smalltalk ist auch eine der am wenigsten bekannten außerhalb der Smalltalk-Community. Es ist eine kleine Methode namens geworden:.

Was wird: Tauscht die Identitäten seines Empfängers und seines Arguments. Das heißt, nachher

a wird: b

Alle Verweise auf das mit a bezeichnete Objekt vor dem Aufrufpunkt beziehen sich auf das mit b bezeichnete Objekt und umgekehrt.

Nehmen Sie sich eine Minute Zeit, um dies zu verinnerlichen. Sie könnten es als etwas Triviales missverstehen. Es geht nicht darum, zwei Variablen zu tauschen - es geht buchstäblich darum, dass ein Objekt zu einem anderen wird. Mir ist keine andere Sprache mit dieser Funktion bekannt. Es ist ein Merkmal von enormer Kraft - und Gefahr.

Betrachten Sie die Aufgabe, Ihre Sprache zu erweitern, um persistente Objekte zu unterstützen. Angenommen, Sie möchten ein Objekt von der Festplatte laden, möchten jedoch nicht alle Objekte laden, auf die es transitiv verweist (andernfalls handelt es sich nur um eine einfache Objektdeserialisierung). Sie laden also das Objekt selbst, aber anstatt die direkten Referenzen zu laden, ersetzen Sie sie durch Hülsenobjekte.

Die Hülsen stehen für die realen Daten im Sekundärspeicher. Diese Daten werden träge geladen. Wenn Sie tatsächlich eine Methode für einen Husk aufrufen müssen, lädt die Methode doesNotUnderstand: das entsprechende Datenobjekt von der Festplatte (aber auch hier nicht transitiv).

Dann wird es zu:, ersetzt alle Verweise auf die Hülle durch Verweise auf das neu geladene Objekt und wiederholt den Aufruf.

Einige Persistenz-Engines haben jahrzehntelang so etwas gemacht - aber sie verließen sich normalerweise auf einen niedrigen Zugriff auf die Repräsentation. Become: Hiermit können Sie dies auf Quellcodeebene tun.

Jetzt mach das in Java. Oder sogar in einer anderen dynamischen Sprache. Sie werden erkennen, dass Sie auf diese Weise eine allgemeine Form der Zukunft und damit der Faulheit erreichen können. Alles ohne privilegierten Zugriff auf die Funktionsweise der Implementierung. Dies ist auch für die Schemaentwicklung nützlich, wenn Sie beispielsweise einer Klasse eine Instanzvariable hinzufügen. Sie können alle Instanzen nach Bedarf umformen.

Natürlich sollten Sie nicht verwenden werden: beiläufig. Dies ist mit Kosten verbunden, die bei vielen Implementierungen möglicherweise untragbar sind. In frühen Smalltalks wurde: billig, weil alle Objekte indirekt über eine Objekttabelle referenziert wurden. Wenn keine Objekttabelle vorhanden ist, wird Folgendes ausgeführt: Durchläuft den Heap auf ähnliche Weise wie ein Garbage Collector. Je mehr Speicher Sie haben, desto teurer wird:.

Eine Objekttabelle belegt Speicherplatz und verlangsamt den Zugriff. Aber es gibt Ihnen viel Flexibilität. Hardware-Support kann die Leistung beeinträchtigen. Der Vorteil ist, dass viele schwierige Probleme schnell behoben werden können, wenn Sie bereit sind, die Kosten für die Indirektion über eine Objekttabelle im Voraus zu bezahlen. Denken Sie daran: Jedes Problem in der Informatik kann mit zusätzlichen Indirektionsebenen gelöst werden. Alex Warth hat einige sehr interessante Arbeiten, die zum Beispiel in diese Kategorie passen.

Werden: hat mehrere Variationen - Ein Weg wird: Ändert die Identität eines Objekts A zu der eines anderen Objekts B, so dass Verweise auf A jetzt auf B zeigen; Verweise auf B bleiben unverändert. Oft ist es sinnvoll, Folgendes zu tun: Massenumwandlung der Identitäten aller Objekte in einem Array (entweder unidirektional oder bidirektional). Eine Gruppe wird: Was es atomar mag, ist großartig, um zum Beispiel reflektierende Updates für ein System zu implementieren. Sie können eine ganze Reihe von Klassen und deren Instanzen auf einmal ändern.

Sie können sich sogar vorstellen, typsicher zu werden:. Zweiwege werden: Ist nur typsicher, wenn der Typ von A mit dem von B identisch ist. Einweg wird: Erfordert nur, dass das neue Objekt ein Subtyp des alten Objekts ist.

Es kann an der Zeit sein, zu überdenken, ob eine Objekttabelle tatsächlich eine gute Sache ist.

Tatsächlich erhalten Sie eine Form des verzögerten Ladens über eine Art Metaprogrammierung. Wie Bracha betont, kann dies sehr nützlich, aber auch gefährlich sein, da es schwerwiegende Auswirkungen auf die Leistung haben kann.


Ich wäre mehr besorgt über becomedie Auswirkungen auf meine geistige Gesundheit als über die Leistung meines Programms ...
Benjamin Hodgson

Hardware support could ease the performance penalty.Von allen Orten, die ich gehört habe, war die Smalltalk-Community die prominenteste. Warum sollten wir Hardware-Verbesserungen "ausgeben", um idealistische Programmierparadigmen zu ermöglichen, wenn dies stattdessen zu einer Leistungssteigerung, einer Verringerung des Stromverbrauchs oder einer Leistungssteigerung führen könnte?
Alexander - Reinstate Monica

2

Es wird nicht viel benutzt. In dem von mir geöffneten Pharo 5-Image gibt es 9 Absender von #become :, von denen 7 in Komponententests sind. Es wird im Compiler bei der Codegenerierung und in der Fuel-Serialisierungsbibliothek verwendet, um Proxys durch ihren Inhalt zu ersetzen.


Interessant. Wofür verwenden die Unit-Tests es?
dpk

um zu sehen, ob es funktioniert ...
Stephan Eggermont
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.