7 Stimmen

Dynamisch Wörter zu einem Kontext in REBOL hinzufügen

Stellen Sie sich den folgenden REBOL-Code vor:

foo: context \[bar: 3\]

Jetzt habe ich einen Kontext foo, in dem 'bar definiert ist. Wie kann ich dynamisch ein neues Wort in diesen Kontext einfügen? Ist das möglich?

Ich habe es versucht:

set/any in foo 'baz 3

Aber das funktioniert nicht, weil der Ausdruck in foo 'baz fehlschlägt, da im foo-Kontext kein Wort 'baz definiert ist.

Ich sollte hinzufügen, dass mir bewusst ist, dass man dies auf folgende Weise tun kann:

foo-Prototyp: \[bar: 3\]
foo: context foo-Prototyp
foo: context head append foo-Prototyp \[baz: 3\]

Aber was ist, wenn Sie keinen Zugriff auf den Prototypenblock von foo haben?

8voto

Peter W A Wood Punkte 863

Sie können das Gleiche erreichen, indem Sie das vorhandene Objekt als Prototyp verwenden, um ein neues Objekt zu erstellen.

>> foo: make object! [bar: 3]
>> foo: make foo [baz: 3]
>> probe foo
make object! [
    bar: 3
    baz: 3
]

1 Stimmen

Dies ist einer der grundlegenden Aspekte von REBOL, aber zum Zeitpunkt, als ich diese Frage stellte, war mir nicht bewusst, dass man dies tun konnte.

4voto

Christian Ensel Punkte 136

Es gibt mehrere Möglichkeiten, um das Problem zu umgehen, dass es in REBOL/2 einfach nicht möglich ist, Objektkontexte zu erweitern.

Vielleicht können Sie einfach BLOCK!s anstelle von OBJECT!s verwenden:

>> blobject: [foo 1]
== [foo 1]
>> blobject/bar
** Skriptfehler: Ungültiger Pfadwert: bar
** In der Nähe von: blobject/bar
>> append blobject [bar 2]
== [foo 1 bar 2]
>> blobject/bar: 3
== 3

Sie können auch 'self' einfach funktionieren lassen, indem Sie das Objekt selbst anhängen:

>> insert blobject reduce ['self blobject]
== [[...] foo 1 bar 2]
>> same? blobject blobject/self
== true

Aber da Sie nach der Erweiterung von OBJECT!s gefragt haben, können Sie Peter W A Woods Lösung nutzen und einfach das Objekt klonen. Bedenken Sie jedoch, dass bei diesem Ansatz der resultierende Klon wirklich etwas anderes als das Originalobjekt ist.

Also, wenn ein Wort gesetzt wurde, um das Objekt vor dem Klonen/Erweitern zu halten, dann wird dieses Wort nach dem Klonen des Objekts immer noch das unerweiterte Objekt halten:

>> remember: object: make object! [foo: 1]
>> object: make object [bar: 2]
>> same? remember object
== false
>> probe remember
make object! [
   foo: 1
]

Falls es für Sie wichtig ist, "Referenzen" zum Objekt intakt zu halten, könnten Sie das Objekt, das Sie erweitern müssen, in einem äußeren Objekt einbetten, wie folgt:

>> remember: object: make object! [access: make object! [foo: 1]]
>> object/access: make object/access [bar: 2]
>> same? remember object
== true

Sie können dann das Objekt sicher erweitern, vorausgesetzt, Sie speichern nur Referenzen zum Container.

Übrigens, REBOL/3 wird das Hinzufügen von Wörtern zu OBJECT!s ermöglichen.

0 Stimmen

Sehr informative Antwort! Ich habe eine MENGE über REBOL gelernt, seit ich diese Frage gepostet habe.

1voto

liumengjiang Punkte 51

Wie im REBOL/Core Benutzerhandbuch gesagt: "Viele Blöcke enthalten andere Blöcke und Zeichenketten. Wenn ein solcher Block kopiert wird, werden seine Unterblöcke nicht kopiert. Die Unterblöcke werden direkt referenziert und enthalten dieselben Daten wie der Originalblock."

0 Stimmen

Bitte korrigiere mich, aber bezieht sich das nicht auf Objekte! anstelle von Blöcken!?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X