Aggiunta dinamica di parole a un contesto in REBOL
Domanda
Immagina il seguente codice REBOL:
foo: context [bar: 3]
Ora ho un contesto foo
in cui è definito 'bar
. Come posso inserire dinamicamente una nuova parola in questo contesto? È possibile?
Ho provato:
set/any in foo 'baz 3
Ma ciò non funziona perché l'espressione in foo 'baz
fallisce perché non esiste una parola ' baz
definita nel contesto foo
.
Dovrei aggiungere che mi rendo conto che un modo per farlo è il seguente:
foo-prototype: [bar: 3] foo: context foo-prototype foo: context head append foo-prototype [baz: 3]
Ma cosa succede se non si ha accesso al prototipo di foo
?
Soluzione
Puoi ottenere lo stesso risultato utilizzando l'oggetto esistente come prototipo per creare un nuovo oggetto.
>> foo: make object! [bar: 3]
>> foo: make foo [baz: 3]
>> probe foo
make object! [
bar: 3
baz: 3
]
Altri suggerimenti
Esistono diversi modi per aggirare il fatto che in REBOL / 2 non è semplicemente possibile estendere i contesti degli oggetti.
Probabilmente puoi semplicemente usare BLOCK! s invece di OBJECT! s:
>> blobject: [foo 1]
== [foo 1]
>> blobject/bar
** Script Error: Invalid path value: bar
** Near: blobject/bar
>> append blobject [bar 2]
== [foo 1 bar 2]
>> blobject/bar: 3
== 3
Puoi persino fare un lavoro autonomo semplicemente aggiungendo l'oggetto stesso:
>> insert blobject reduce ['self blobject]
== [[...] foo 1 bar 2]
>> same? blobject blobject/self
== true
Ma come hai chiesto di estendere OBJECT! s , potresti scegliere la soluzione di Peter W A Wood per clonare semplicemente l'oggetto. Basta tenere presente che con questo approccio il clone risultante è davvero una cosa diversa dall'oggetto originale.
Quindi, se una parola è stata impostata per contenere l'oggetto prima della clonazione / estensione, dopo la clonazione dell'oggetto quella parola conterrà l'oggetto non esteso:
>> remember: object: make object! [foo: 1]
>> object: make object [bar: 2]
>> same? remember object
== false
>> probe remember
make object! [
foo: 1
]
Nel caso in cui sia essenziale conservare " riferimenti " all'oggetto intatto, potresti voler avvolgere l'oggetto che devi estendere in un oggetto esterno come in
>> remember: object: make object! [access: make object! [foo: 1]]
>> object/access: make object/access [bar: 2]
>> same? remember object
== true
È quindi possibile estendere in modo sicuro l'oggetto mantenendo, dato che si memorizzano solo riferimenti al contenitore.
REBOL / 3, tra l'altro, consentirà di aggiungere parole a OBJECT! s.
Detto nella Guida dell'utente di REBOL / Core: " Molti blocchi contengono altri blocchi e stringhe. Quando un tale blocco viene copiato, è le sotto-serie non vengono copiate. Le sotto-serie sono citate direttamente e sono uguali dati della serie come blocco originale. "