Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] How do I dynamically extend an object! instance Re:

From: lmecir::geocities::com at: 10-Sep-2000 21:09

Hi bobr, you wrote:
> 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 > ] > > ;-------- for discussion: > > - can this be written more succinctly yet not hardcode > anything about the object?
I would suggest the following: object-addword: func [ { add a word only if it is not already there, returns a new instance of object examples myobj: object-addword myobj emailaddr dbrecord: object-addword/initial dbrecord areacode 978 } o [object!] "the object to have a word added" ; I prefer not to use unevaluated/fetched arguments w1 [word!] "the word to add" /initial vdef [any-type!] "provide initial value for the word" ] [ if not find (first o) w1 [ o: make o reduce [to set-word! w1 none] ; because you declared vdef to be any-type!, this is the only way to set it error? set/any in o w1 get/any 'vdef ] return o ] Example:
>> probe object-addword/initial make object! [] 'a ()
make object! [ a: unset ] The problem is, that even this is not general enough, as is explained below
> - can it be done without creating a new instance?
No.
> - can a corresponding function for removing a word > from an object be written without evaluating > all the other words/elements?
The general answer is no, IMHO, only special cases can be solved. There are two problems: 1. 'Self can be any-type! in Rebol. 2. There are problems with "complicated" datatypes, eg. functions
> 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? > - 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? > can this be coded without resorting to second-level functions? >
It is feasible, if you don't use unevaluated arguments: object-addword: func [ [catch] o [object! word!] w [object! word!] ] [ if word? o [ set [o w] reduce [w o] ] if not object? o [ throw make error! reduce ['script 'expect-arg 'object-addword 'o object!] ] if not word? w [ throw make error! reduce ['script 'expect-arg 'object-addword 'w word!] ] ; ... ]