I need a function that expands an object to add extra fields.

So I've written one. See below.  From an engineering perspective, it works 
fine.  From a REBOL elegance viewpoint that "return do mold obj" goes clunk in 
my brain. Is there a better way?

A bit of background....I got a system that holds persistent data as molded 
objects in files. I need to add fields that weren't dreamt of in the initial 
release. But I don't need to worry about circular references or the object being 
referenced elsewhere.

The simplest solution is to apply a template of all possible fields to an 
object each time we read it.

The function below is intended to do that. 

The "return do mold obj" seems necessary to stop inner objects that aren't in 
the original being the 'same? as the template object.

How can I do this more elegantly, please?

;;========== the function ==========
Rebol []
update-object: func [obj [object!]
                     template [object!]
                     /local
                 ]
[
 foreach field next first template
    [
     if  error? try [obj/:field]
            [
             obj: construct/with  reduce [to-set-word field template/:field] 
obj
            ]
    if object? template/:field
        [
         obj: construct/with   reduce [to-set-word field update-object 
obj/:field template/:field] obj
        ]
    ] ;; for

return do mold obj  ;; added objects are independent beings.
;;;;return obj          ;; added objects are the 'same? as template

] ;; func

;; ========== Some test data data ==========

test-template: make object! [
         a1: "initial data value"
         a2: "not in test object"
         a3: make object!
                [
                 a3-1: 1-oct-2003
                 a3-2: make object!
                        [a3-2-1: "sss"
                         a3-2-2: "also not in test object"
                         ]
                 a3-3: "rebol [halt]"   ;; dangerous value if loaded
                 a3-4: reduce [now/precise]
                ]
        a4: make object! []         ;; empty object -- not in test
        a5: make object! [a5-1: a5-2: a5-3: true]
        a6: a7: a8: none
        a9: make object! [a9-1: a9-2: a9-3: false]
]

test-object: make object! [
        a1: "got a value"
        a3: make object!
                [a3-1: false
                 a3-2: make object!
                    [a3-2-1: "also got a value"
                    ]
                ]
        ]


loop 10 [print ""]
res1: update-object test-object test-template
wait 0.1    ;; see if nows cause a problem -- they shouldn't in this case
res2: update-object res1 test-template

print "test failure messages follow...."
if strict-not-equal? mold res1 mold res2
            [Print "Something didn't work"]

if same? res1/a4 test-template/a4
        [print "we've got cloning!"]
if same? res1/a9 test-template/a9
        [print "we've got cloning!"]
====================

Thanks!
Sunanda
-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.

Reply via email to