Ich finde es zutiefst seltsam, dass dies in Ruby möglich ist (ich werde nicht gleich sagen, wie):
obj = #code redacted
print obj.state # Some value.
LValue = obj
print obj.state # Different value!
Ihre Herausforderung besteht darin, Code ungefähr in dieser Form zu erstellen. Erstellen Sie ein Objekt und weisen Sie es einer Variablen zu. Es sollte ein definiertes Attribut (oder eine deterministische, idempotente Methode) wie state
oben haben, das sich ändert, nachdem das Objekt einem neuen Bezeichner ( LValue
oben) zugewiesen wurde , auch wenn Sie den alten Bezeichner ( obj
oben) weiterhin verwenden, um darauf zu verweisen.
Zur Hervorhebung bearbeiten : state
oder das Äquivalent muss idempotent sein. Die Erstellung eines Accessors, der den Wert ändert oder aus einem anderen Grund unterschiedliche Ergebnisse liefert, wenn er mehrmals hintereinander aufgerufen wird, ist keine gültige Lösung. Oder einfacher gesagt, es muss die Zuweisung sein, die den Zustand ändert.
Jede Sprache mit Zuweisung ist förderfähig, obwohl es wahrscheinlich einige gibt, für die es keine völlig legitime Lösung gibt. Ich werde meine Ruby-Antwort veröffentlichen, wenn sie nach ein paar Tagen niemand anderes erhält, und die Antworten mit den höchsten Stimmen fortlaufend annehmen.
quelle
LValue = obj
Leitung benötigt werden, umstate
sich tatsächlich zu ändern? (Ich könnte einfach eine Eigenschaft in C # erstellen, die jedes Mal erhöht wird, wenn Sie sie erhalten.)(setq a (list "val")) (setq b (nconc a "val2"))
zum Beispiel.a
endet("val" . "val2")
zu diesem Zeitpunkt zu bewerten .Antworten:
C ++
Dies ist mit den richtigen Werkzeugen trivial.
Ausgabe:
quelle
PHP (Debugbuild,> = 5.4)
Wir verwenden refcount des Objekts in einem Getter. (Also, durch die Zuweisung, erhöht sich die Nachzählung und der Wert ändert sich)
quelle
C #
Zwei einfache Möglichkeiten:
Oder wir könnten einfach in den gleichen Speicher schreiben:
quelle
TeX, viel kürzer als andere Antworten hier
Als Schriftsatzsystem hat TeX einen "Box" -Typ, der Schriftsatzmaterial enthält. Da der häufigste Anwendungsfall darin besteht, dieses Material zu verschieben, zu teilen usw., anstatt Kopien davon anzufertigen, werden Boxen normalerweise gelöscht, wenn sie verwendet werden auf eine aktuelle Box im Speicher). Keine Notwendigkeit für Magie.
quelle
C ++ 11 (Also habt ihr unique_ptr / shared_ptr vergessen :-))
quelle
Fortran 03
Dies ist der Antwort von Hugo D etwas ähnlich, ist aber etwas versteckter (teilweise, weil wer das # $% ^ Objektorientierte Fortran kennt)?
Die Ausgabe ist
Wenn Sie herausfinden können, was passiert ist, erhalten Sie Bonuspunkte! Wenn nicht:
quelle
Power Shell
Dadurch wird ein Objekt erstellt, dessen
state
Eigenschaft die Namen der Variablen sind, die auf das Objekt verweisen.Ausgabe
Hinweis: Dies funktioniert nicht, wenn die Zuweisung in einem untergeordneten Bereich erfolgt.
Ausgänge
quelle
Perl 5
Hier ist eine Möglichkeit, dies in Perl zu tun:
Dies gibt aus:
Erläuterung:
Dies ist eine einfache Anwendung von Überladung . Insbesondere überlade ich den String-Konvertierungsoperator
""
, der aufgerufen wird, wenn das überladene Objekt zugewiesen wirdsubstr()
(was in Perl ein zulässiger Wert ist).Es gibt auch viele spezielle Variablen in Perl, die alles, was ihnen zugewiesen ist, aufgreifen. Zum Beispiel funktioniert auch Folgendes:
Alternative Lösung
Hier ist ein anderer Weg dorthin:
Hier
state
ist eine Methode (wir könnten sie zu einem Attribut mit weiteren Bindungs- / Überlastungs-Spielereien machen, aber das würde die Dinge komplizieren), die buchstäblich die Anzahl der Verweise auf das Objekt zählt. Anders als in der ersten Lösung müssen Sie also$obj
einer normalen Variablen zuweisen , die eine Objektreferenz enthalten kann, um den Status zu ändern.quelle
JavaScript
Ok, also habe ich eine kürzere Version erstellt, die als SSCCE funktioniert, aber nicht mehr versucht, JavaScript richtig zu analysieren, sodass die Referenzzählung möglicherweise nicht funktioniert, wenn sie in ein komplexeres Skript eingefügt wird.
quelle
Python
Es schummelt ein bisschen, aber wie wäre es mit:
quelle
C ++ 11
Dies kann jedoch für andere Sprachen erweitert werden, die implizite / explizite Destruktoren unterstützen
quelle
new
ohne eine einzigedelete
im Programm. Obwohl, für diese Aufgabe ist es gut genug, denke ich :)cout
Linie vor dem}
und prüfen Sie, ob dies funktioniert. :-)Scala
Mit impliziten Konvertierungen können Sie dies erreichen, während Sie einer normalen lokalen Variablen zuweisen:
Dies können Sie auch mit abgeleiteten Typen erreichen:
Sie können auch eine benutzerdefinierte Setter-Methode verwenden, allerdings muss der L-Wert ein Feld sein:
quelle
D
Ausgabe:
quelle
Rubin
Wie versprochen, hier ist die Antwort, die die Frage inspiriert hat.
Class.new
erstellt eine anonyme Klasse. Wenn Sieto_s
eine anonyme Klasse aufrufen, wird die Standardzeichenfolgendarstellung von Objekten angezeigt, die wie folgt aussieht#<Class:0x007fe3b38ed958>
. Sobald jedoch die Klasse einer Konstanten zugewiesen wurde,to_s
wird diese Konstante. In Ruby ist eine Konstante eine Variable, die mit einem Großbuchstaben beginntobj
eine Referenz auf die Klasse, mit der sie anonym bleiben kann.Mein Code wird
to_s
in einestate
Methode eingebunden , sodass die Ausgabe erfolgtIm Gegensatz zu den meisten hier beschriebenen Lösungen funktioniert dies nur einmal: Wenn Sie
obj
eine andere Konstante zuweisen , wird die Zeichenfolgendarstellung nicht geändert, und es wird auch kein neuer Wert zugewiesenLValue
.quelle
In Java
In Java hielt ich das für unmöglich. Aber…
Hauptklasse :
Klasse Katze:
Ich wurde von @tbodt inspiriert.
quelle
Cat.x = 2
und dann druckenCat.x
.Cat otherCat = tom
hätte, hätte sich der Zustand überhaupt nicht geändert. Es fällt mir schwer zu glauben, dass dies dem Buchstaben oder Geist der Regeln entspricht.C ++
Dieses Verhalten ist tatsächlich im Standard festgelegt (und wurde deshalb nicht mehr empfohlen).
Ausgabe
Der Prozess, der dies verursacht, ist derselbe wie bei Abhijit, jedoch ohne
std::move
und derselbe wie bei Marinus, jedoch unter Verwendung einer Standardklasse, anstatt sie selbst zu definieren.Bearbeiten: Ich füge eine Erklärung hinzu. In der Ausgabe ist "irgendeine Adresse" tatsächlich ein Hexadezimalwert für die Adresse der zugewiesenen Ganzzahl.
std::auto_ptr
Gibt den Speicherzeiger frei, wenn er einem anderen zugewiesen wurde,auto_ptr
und setzt den internen Zeiger auf 0. Durch Aufrufen wird derget()
Zugriff auf den Speicherzeiger abgerufen.quelle
get()
? Warum würde es am Ende 0 zurückgeben?auto_ptr
es veraltet ist.Python
quelle
Python 2.x
Ich konnte keinen richtigen Weg finden, um dies zu tun, ohne eine zusätzliche Klasse zu definieren.
quelle
Java
Alle anderen Lösungen verwenden die Form der Operatorüberladung ihrer Sprache. Java hat keine Operatorüberladung, also dachte ich, ich stecke fest. Aber mir ist etwas eingefallen.
Hier ist die Hauptklasse:
Es gibt ein paar verdächtige Zeilen, aber sie würden nichts tun, wenn die
Thing
Klasse völlig normal wäre. Es ist nicht:Es ist nicht garantiert, dass es aufgrund der Threads funktioniert, aber ich habe es auf JDK 1.8u5 getestet und es funktioniert dort.
quelle
Common Lisp
Ich definiere Zustand als die Anzahl der an einen Vektor gebundenen speziellen Variablen. Die Zuweisung zu einer speziellen Variablen ändert also den Status.
Ausgabe:
Es funktioniert nur mit Zuweisungen zu speziellen Variablen, nicht zu lexikalischen Variablen oder zu Slots innerhalb eines Objekts.
Passen Sie das auf
do-all-symbols
in allen Paketen gesucht wird, sodass Variablen fehlen, die kein Paket enthalten. Es kann vorkommen, dass Symbole, die in mehreren Paketen vorhanden sind, doppelt gezählt werden (wenn ein Paket das Symbol aus einem anderen Paket importiert hat).Rubin
Ruby ist fast dasselbe, aber ich definiere state als die Anzahl der Konstanten, die sich auf ein Array beziehen.
Ausgabe:
Dies ist eine Verallgemeinerung der Antwort des Histokraten auf Ruby-Objekte, die keine Klassen oder Module sind. Die Warnung wird angezeigt, weil die Konstante Config den Code, der die Warnung erstellt hat, automatisch lädt.
quelle
C ++
Das Ergebnis kann auf verschiedenen Plattformen unterschiedlich sein. Auf ideone getestet .
Ausgabe:
quelle
C #
Ausgabe:
quelle
=
?B
zu einemA
, weil dasimplicit operator A(B b)
Nebenwirkungen hat.