[REBOL] How do I dynamically extend an object! instance Re:
From: whip:cs:unm at: 10-Sep-2000 11:06
Howdy Bob:
I see Gabriele's message just came in with similar approach, but
I'll send along mine for good measure.
> I have an existing dataase of saved objects which I wish to add
> fields to (IE add words:). I probably only want to add the words if
> I absolutely must in order to keep size down. I also may already
> have added a particular word to an object instance and dont wish to
> overwrite the value already associated with that word.
>
> Here is what I have so far. questions follow below.
>
> object-addword: func [
> { add a word only if it is not already there, returns a new
> instance of the object
> examples
> myobj: object-addword myobj emailaddr
> dbrecord: object-addword/initial dbrecord areacode 978 }
>
> o [object!] "the object to have a word added"
> 'w1 [any-word!] "the word to add"
> /initial
> vdef [any-type!] "provide initial value for the word"
> /local
> mb "mini block"
> ] [
> if not find (first o) w1 [
> ; try to emulate: set/any in o w1 none
> mb: do rejoin [ {[} :w1 {: none ]} ]
> o: make o mb
> if initial [ set/any in o w1 vdef ]
> ]
> return o
> ]
Here's my crack at it:
add-obj-word: func [ "add word to object iff not already there"
'obj-word [word!]
'word [word!]
/initial init
/local the-obj
][
all [not object? the-obj: get obj-word make error! "No object provided." ]
all [in the-obj word return the-obj]
set obj-word make the-obj reduce [
to-set-word word init
]
]
> ;-------- for discussion:
> - can this be written more succinctly yet not hardcode anything
> about the object?
I think the above does that. Your version was more in a functional
style (needed to reassign the result), mine's more side-effecty.
Also, by leaving out the type specifier for the init value, we'll
exclude unset! values from init.
>- can it be done without creating a new instance?
A new instance which replaces the old instance.
> - can a corresponding function for removing a word from an object be
> written without evaluating all the other words/elements?
I can't think of how with out remaking the object minus that word:
remove-obj-word: func ["remove word from object iff there"
'obj-word [word!]
'word [word!]
/local the-obj words-in-obj vals-in-obj new-body
][
all [not object? the-obj: get obj-word make error! "No object provided." ]
if not in the-obj word [return the-obj]
words-in-obj: next first the-obj
vals-in-obj: next second the-obj
new-body: copy []
foreach w words-in-obj [
if word <> w [
append new-body reduce [to-set-word w vals-in-obj/1]
]
vals-in-obj: next vals-in-obj
]
set obj-word make object! new-body
]
Here's a hacky approach that will fail for removing words that don't
point to simple datatypes:
r-o-w: func [
'obj-word [word!]
'word [word!]
/local the-obj words-in-obj vals-in-obj new-body
][
all [not object? the-obj: get obj-word make error! "No object provided." ]
if not in the-obj word [return the-obj]
new-body: third load mold the-obj ;-yuck
remove/part find new-body to-set-word word 2
set obj-word make object! new-body
]
Above should fail if you try to remove an object word that refers to
another object, for instance. That's the perils of doing your
metalevel work through string manipulation -- so I happily disavow the
above.
> I have tried several arrangements for the arguments and names for
> the function. I have settled on
> object-addword rcvrobj operand
> - are the precedents for putting the word operand first?
The typical REBOL parameter arrangement is that which is operated
on followed by the things to operate on it with.
> - since, from context, you can tell which argument is the object
> and which is simply a word which may need to be added to the object,
> why not make the function figure out which argument is which type
> and do the right thing regardless of how it is called?
Makes for a candy machine interface, IMHO.
> can this be
> coded without resorting to second-level functions?
Sure.
> - is a better name for the function possible? I have considered
> 'object+ and 'object+word as potential names. Is there a precedent
> that I have missed?
The REBOL naming style suggests verb noun. do-thing, remove-thing.
-jeff