Dinamicamente adicionar palavras a um contexto em REBOL
Pergunta
Imagine a seguinte código REBOL:
foo: context [bar: 3]
Agora tenho uma foo
contexto em que 'bar
está definida. Como posso dinamicamente injetar uma nova palavra nesse contexto? É possível?
Eu tentei:
set/any in foo 'baz 3
Mas isso não funciona porque o in foo 'baz
expressão falha porque não há nenhuma palavra 'baz
definido no contexto foo
.
Devo acrescentar que eu percebo uma maneira de fazer isso é o seguinte:
foo-prototype: [bar: 3] foo: context foo-prototype foo: context head append foo-prototype [baz: 3]
Mas e se você não tem acesso ao bloco protótipo de foo
?
Solução
Você pode conseguir o mesmo usando o objeto existente como um protótipo para criar um novo objeto.
>> foo: make object! [bar: 3]
>> foo: make foo [baz: 3]
>> probe foo
make object! [
bar: 3
baz: 3
]
Outras dicas
Existem várias maneiras de contornar o fato de que em REBOL / 2 não é apenas posssible para estender contextos de objetos.
!Provavelmente você pode apenas usar BLOCO s em vez 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
Você pode até mesmo fazer 'auto de trabalho por apenas acrescentando o próprio objeto:
>> insert blobject reduce ['self blobject]
== [[...] foo 1 bar 2]
>> same? blobject blobject/self
== true
Mas, como você pediu para estender OBJECT! S , você pode ir para a solução de Peter W A Madeira simplesmente clone do objeto. Basta ter em mente que, com esta abordagem, o clone resultante é realmente uma coisa diferente do que o objeto original.
Assim, se alguma palavra foi definida para segurar o objeto antes da clonagem / estendendo, após a clonagem do objeto que a palavra ainda vai realizar o objeto unextended:
>> remember: object: make object! [foo: 1]
>> object: make object [bar: 2]
>> same? remember object
== false
>> probe remember
make object! [
foo: 1
]
No caso, é essencial para você manter "referências" para o objeto intacto, você pode querer envolver o objeto que você precisa estender em um objeto externo como no
>> remember: object: make object! [access: make object! [foo: 1]]
>> object/access: make object/access [bar: 2]
>> same? remember object
== true
Você pode então safley estender o objeto, mantendo, dado apenas armazenar as referências ao recipiente.
REBOL / 3, btw, permitirá adicionar palavras ao objeto! S.
Said em Guia REBOL / Core Usuário: "Muitos blocos conter outros blocos e cordas. Quando um tal bloco é copiado, o seu sub-série não são copiados. Os sub-série são referidos directamente e são os mesmos dados de série como o bloco original ".