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

Reply via email to