Agregar dinámicamente palabras a un contexto en REBOL
Pregunta
Imagine el siguiente código REBOL:
foo: context [bar: 3]
Ahora tengo un contexto foo
en el que se define 'bar
. ¿Cómo puedo inyectar dinámicamente una nueva palabra en este contexto? ¿Es posible?
He intentado:
set/any in foo 'baz 3
Pero eso no funciona porque la expresión en foo 'baz
falla porque no hay una palabra ' baz
definida en el contexto foo
.
Debo agregar que me doy cuenta de que una forma de hacerlo es la siguiente:
foo-prototype: [bar: 3] foo: context foo-prototype foo: context head append foo-prototype [baz: 3]
¿Pero qué pasa si no tiene acceso al bloque prototipo de foo
?
Solución
Puede lograr lo mismo utilizando el objeto existente como prototipo para crear un nuevo objeto.
>> foo: make object! [bar: 3]
>> foo: make foo [baz: 3]
>> probe foo
make object! [
bar: 3
baz: 3
]
Otros consejos
Hay varias formas de evitar el hecho de que en REBOL / 2 simplemente no es posible extender los contextos de objetos.
Probablemente pueda usar BLOCK! s en lugar de 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
Incluso puede hacer que el autoempleo simplemente agregue el objeto en sí:
>> insert blobject reduce ['self blobject]
== [[...] foo 1 bar 2]
>> same? blobject blobject/self
== true
Pero como ha pedido extender OBJECT! s , puede buscar la solución de Peter W A Wood para simplemente clonar el objeto. Solo tenga en cuenta que con este enfoque, el clon resultante es realmente diferente al objeto original.
Entonces, si alguna palabra se ha configurado para contener el objeto antes de la clonación / extensión, después de clonar el objeto, esa palabra aún retendrá el objeto no extendido:
>> remember: object: make object! [foo: 1]
>> object: make object [bar: 2]
>> same? remember object
== false
>> probe remember
make object! [
foo: 1
]
En caso de que sea esencial para usted mantener " referencias " al objeto intacto, es posible que desee envolver el objeto que necesita extender en un objeto externo como en
>> remember: object: make object! [access: make object! [foo: 1]]
>> object/access: make object/access [bar: 2]
>> same? remember object
== true
Luego puede extender de forma segura el objeto mientras lo mantiene, dado que solo almacena referencias al contenedor.
REBOL / 3, por cierto, permitirá agregar palabras a OBJECT! s.
Dicho en REBOL / Core User Guide: " Muchos bloques contienen otros bloques y cadenas. Cuando se copia dicho bloque, su Las sub-series no se copian. Las sub-series se mencionan directamente y son las mismas. datos de la serie como el bloque original. "