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

Object lesson, please?

 [1/5] 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

 [2/5] from: g:santilli:tiscalinet:it at: 23-Oct-2003 17:53


Hi SunandaDH, On Thursday, October 23, 2003, 5:19:47 PM, you wrote: Sac> I need a function that expands an object to add extra fields. Just some quick notes... 1. you can do this:
>> original: context [a: 1 b: 2] >> template: context [a: b: c: none] >> probe changed: make template original
make object! [ a: 1 b: 2 c: none ] to update the original object based on a template. 2. you could just recursively apply this function to all the sub-objects... this way you get a copy of all the objects so you won't need the mold anymore. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [3/5] from: SunandaDH:aol at: 24-Oct-2003 4:34


Gabriele:
> 1. you can do this: > > >> original: context [a: 1 b: 2] > >> template: context [a: b: c: none] > >> probe changed: make template original
Thanks, Gabriele. The one thing I hadn't thought of trying was context -- the word had slipped from my mental context. I had to change the code around as context takes a block, not an object -- hence the the "content third xxx" to grab the block inside the object. But even then a simple conversion of the code didn't work -- I ended up with inner objects still being cloned. I've had to do a copy/deep of the originals to break the cloning. That's almost as unsatisfactory as the original code. Here's the latest version, with a simpler set of test data: ;;========== the function ========== Rebol [] update-object: func [obj [object!] template [object!] /local obj-copy template-copy ] [ obj-copy: make object! copy/deep third obj template-copy: make object! copy/deep third template foreach field next first template-copy [ ;; add a field if it doesn't exist if error? try [obj-copy/:field] [ obj-copy: context join third obj-copy [to-set-word field template-copy/:field] ] ;; recurse adding fields if field is an object if object? template-copy/:field [ obj-copy: context join third obj-copy [to-set-word field update-object obj-copy/:field template-copy/:field] ] ] ;; for return obj-copy ;; no more do mold ! ] ;; func ;; ========== Some test data data ========== original-object: make object! [] template: make object! [a: make object! [b: 1]] new-object1: update-object original-object template new-object2: update-object original-object new-object1 print "status messages follow -- all say true if it's worked" print not same? new-object1/a template/a print not same? new-object1/a new-object2/a print equal? mold new-object1 mold new-object2 ============= Sunanda.

 [4/5] from: g:santilli:tiscalinet:it at: 24-Oct-2003 11:20


Hi SunandaDH, On Friday, October 24, 2003, 10:34:39 AM, you wrote: Sac> Thanks, Gabriele. The one thing I hadn't thought of trying was context -- the Sac> word had slipped from my mental context. It is just a shortcut for MAKE OBJECT!... What I wanted to point out was that you could just use MAKE to update your object. I.e. (QAD): update-object: func [obj template] [ obj: make template obj foreach word next first obj [ if all [object? get in obj word in template word object? get in template word] [ set in obj word update-object get in obj word get in template word ] ] obj ] Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amiga Group Italia sez. L'Aquila --- SOON: http://www.rebol.it/

 [5/5] from: nitsch-lists:netcologne at: 24-Oct-2003 16:51


with inner objects i would go with your do mold object it has the additional advantage that it checks your data for moldability. today its prety reliable, but in the old days a bad string could break it. when i stored data to disk, i checked them that way, instead of saving broken data. either attempt[do mold data][save %file data][alert "Internal error"] So doing it more often may help stability. -Volker Am Freitag, 24. Oktober 2003 10:34 schrieb [SunandaDH--aol--com]: