ItGo.me Focus on IT Recommend

Home > rebol2 - Dynamically adding words to a context in REBOL

rebol2 - Dynamically adding words to a context in REBOL

Imagine the following REBOL code:

foo: context [bar: 3]

I now have a context foo in which 'bar is defined. How can I dynamically inject a new word into this context? Is it possible?

I've tried:

set/any in foo 'baz 3

But that doesn't work because the expression in foo 'baz fails because there is no word 'baz defined in the foo context.

I should add that I realize one way to do this is as follows:

foo-prototype: [bar: 3]
foo: context foo-prototype
foo: context head append foo-prototype [baz: 3]

But what if you don't have access to foo's prototype block?

rebol rebol2
|
  this question
edited Jun 19 '13 at 1:42 rgchris 2,314 10 17 asked Nov 4 '08 at 20:53 Gregory Higley 8,540 6 46 74

 | 

3 Answers
3

---Accepted---Accepted---Accepted---

You can achieve the same by using the existing object as a prototype to create a new object.

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

|
  this answer
answered Jan 10 '09 at 10:48 Peter W A Wood 740 4 12 1   This is one of the fundamental aspects of REBOL, but at the time I asked this question, I wasn't aware you could do this. –  Gregory Higley Feb 12 '09 at 5:36

 | 

There are several ways to work around the fact that in REBOL/2 it's just not posssible to extend object contexts.

Probably you can just use BLOCK!s instead of 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

You can even make 'self working by just appending the object itself:

Recommend:equality - Are OBJECT and CONTEXT synonyms in Rebol2

context c. Probing them reports the same code construct, and also type is the same (both being type object!): >> o: make object! [a: 1 b: 2]>> c: context [a: 1 b: 2]>> probe omake object! [ a: 1 b: 2]>> probe cmake object!

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

But as you've asked for extending OBJECT!s, you may go for Peter W A Wood's solution to simply clone the object. Just keep in mind that with this approach the resulting clone really is a different thing than the original object.

So, if some word has been set to hold the object prior to cloning/extending, after cloning the object that word will still hold the unextended object:

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

In case it's essential for you to keep "references" to the object intact, you might want to wrap the object you need to extend in an outer object as in

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

You can then safley extend the object while keeping, given you only store references to the container.

REBOL/3, btw, will allow adding words to OBJECT!s.


|
  this answer
answered Jan 10 '09 at 19:41 Christian Ensel 136 3      Very informative answer! I've learned a TON about REBOL since I posted this question. –  Gregory Higley Feb 12 '09 at 5:37

 | 

Said in REBOL/Core User Guide: "Many blocks contain other blocks and strings. When such a block is copied, its sub-series are not copied. The sub-series are referred to directly and are the same series data as the original block."


|
  this answer
answered Nov 18 '10 at 7:06 liumengjiang 36 3      Correct me if I'm wrong, but doesn't this relate to object!s instead of blocks!s? –  Geeky I Mar 21 at 0:30

 | 

Recommend:rebol2 - Retrieving function arguments programatically in Rebol

. So they'll act like "global variables". To suppress that you'd put in your FUNC-spec func [arg1 /local v1 v2]. (Note: Rebol3 has FUNCTION which scans for locals automatically and builds the underlying FUNC for you. But FUNCTION meant some

oriUlr:http://stackoverflow.com/questions/263402/dynamically-adding-words-to-a-context-in-rebol

------splitte line----------------------------