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!]
    ]
    ; ...
]

> - 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?
>
> ;# mailto: [EMAIL PROTECTED]
>
>

Reply via email to