[REBOL] Object lesson, please?
From: SunandaDH::aol::com at: 23-Oct-2003 11:19
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