r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[XML] xml related conversations

Graham
23-Jun-2009
[676]
Using objects means i can store the functions that initialize it 
inside the object.
BrianH
23-Jun-2009
[677]
Not a good idea for data objects, which could number in the thousands, 
each with their own bound copy of the functions.
Maxim
23-Jun-2009
[678]
yes, the best method is to have some form of dtd or schema, and use 
class-based objects.
BrianH
23-Jun-2009
[679]
Class-based objects are emulated in REBOL.
Maxim
23-Jun-2009
[680x2]
the init is a context with one function, to which you supply the 
outer (instance) which holds the data:

my-tag: context [
	data: "tototo"
	attribute-1: "red"
	class: context [
		init: func [instance][
			instance/data: copy ""
			instance/attribute-1:  copy "blue"
		]
	]
]

to init the an instance of my-tag:

new-tag: make my-tag [class/init self]
class is shared amongst all my-tag instances, and is never bound 
to any of them, so its both very fast and very RAM efficient..  exponentially 
so with large classes.
Graham
24-Jun-2009
[682x2]
That's what i was going to do initially, but I thought it would be 
easier to maintain if I kept the init methods inside the objects
Perhaps I'm not clear on this ....  
If I create a pharmacy object like this


pharmacy: make object! [
	name: none
	init: func [ n ][
		self/name: n
	]
]


is the init function shared by all the subsequent pharmacy instances?
Maxim
24-Jun-2009
[684]
it is bound each time, so if you have 2000 instances, you actually 
have 2000 times that function in ram, it adds up quickly for larger 
objects... for such a simple object, it might not be all that bad...
Graham
24-Jun-2009
[685]
what's the diff between yours and mine?
Maxim
24-Jun-2009
[686x2]
my example above, will share the init function amongst all the 2000 
objects... and its going to be faster since no binding occurs... 
well only the CLASS word is bound but its content is the same in 
all instances.
with liquid the difference is staggering when over 10000 objects.
Graham
24-Jun-2009
[688x2]
well, I doubt that I would have more than a few hundred objects... 
but ...
unclear as to why yours is shared and mine isn't
Maxim
24-Jun-2009
[690x2]
but its a large object.  still using the class system, I can allocate 
1000000 nodes using about 400MB.  with instances, 10000 obects take 
much more than that.
R2 shares objects within objects. the class is not re-created at 
each make [].
Graham
24-Jun-2009
[692x2]
Oh ....
is it objects within objects within objects?
BrianH
24-Jun-2009
[694]
But then the class functions are accessed through obj/class/method 
obj, insstead of obj/method.
Graham
24-Jun-2009
[695]
so if I have

pharmacy: make object! [
	address: make addressobj [ ]
]


and the address object has objects in it ... they will be shared??
BrianH
24-Jun-2009
[696]
Yeah.
Graham
24-Jun-2009
[697x3]
Ouch
So, how does one create nested unique objects?
Create them using the init function ??
BrianH
24-Jun-2009
[700x2]
With explicit construction in the spec block, like this:
a: make proto [
    b: make inner-proto [...]
]
Every MAKE object! takes a spec block that is an init function, in 
effect.
Graham
24-Jun-2009
[702x3]
so , instead of 

a: make pharmacy []

I have to 

a: make pharmacy [ address: make addressobj []]
If that is the case, perhaps I need a 'create function with each 
object, and at init time, iterate thru all the objects calling their 
create function ?
As you can see, I've never played with rebol objects before ...
BrianH
24-Jun-2009
[705]
If you like. The standard way of doing things in REBOL is to have 
functions that create objects, rather than constructor methods.
Graham
24-Jun-2009
[706x2]
which is the more robust method?
In terms of maintenance?
BrianH
24-Jun-2009
[708]
OOP in a prototype-based language with function values instead of 
methods is different. Classes are emulated if need be, but don't 
always need to be. In REBOL even delegation is explicit, unlike most 
other prototype-based object languages.


For the best maintenance use factory functions that create objects 
based on standard specs. Beyond that, different models are better 
for different tasks. Sometimes you assign function values to fields, 
sometimes you use class objects, sometimes class names that are looked 
up at runtime.
Maxim
24-Jun-2009
[709]
I usually creat myself a new function which calls make and the  object 
init (wether class or prototype based)  if that init needs to create 
new inner objects, then its responsible for doing so.


in your case the make-xml-object  could accept an xml string and 
then call make-xml-object recursively for each element it finds.
Graham
24-Jun-2009
[710]
I guess I can set the init functions to none after they've done their 
jobs ?
Maxim
24-Jun-2009
[711]
not much would really be gained, but it migh trigger some GC cleanup.
Graham
24-Jun-2009
[712x2]
i wouldn't have 100s of init functions anymore .. :)
Using your method of creating a special context is going to screw 
up my obj2xml function :(
Sunanda
24-Jun-2009
[714]
One way to do init is as open code in the object....That only "inits" 
the original object, not anything MAKEd from it. But it may be useful 
in some cirumstances, and it does not become part of the object:
    o: make object! compose [print "init" (a: 99) a: 1 b: 2]
Graham
24-Jun-2009
[715]
huh?
BrianH
24-Jun-2009
[716]
Code in the spec block doesn't get attached to the object.
Maxim
24-Jun-2009
[717x2]
thats another ways of doing it... instead of storing reference objects 
you store reference spec blocks.
that is how its done in GLayout to assign the same setup to many 
styles.
BrianH
24-Jun-2009
[719]
The spec block is like an init function that goes away after it runs, 
without needing to assign none to any fields.
Maxim
24-Jun-2009
[720]
so graham... instead of doing: 


; note this is an object, context is a shortcut for make object! 
,  like func is a shortcut for make function!
addressobj: context [
	number: 666
	street: "styx lane"
	city: "pandemonium"
]
pharmacy: context [
	address: make addressobj [ ]
]

you do:

; note this is a block
addressobj: [
	number: 666
	street: "styx lane"
	city: "pandemonium"
]

pharmacy: context [
	address: context addressobj
]
Graham
24-Jun-2009
[721]
I'm having to create nested objects 7 levels deep ...
Maxim
24-Jun-2009
[722x2]
in the later, you can add code in the addressobj which will be executed 
everytime you create an object using it.

for example: 
addressobj: [
	number: 666
	street: "styx lane"
	city: "pandemonium"
	address: rejoin [number " " street " " city]
]
does the xml structure change a lot (lists of data, alternative or 
optional elements, etc) or is it really static?
Graham
24-Jun-2009
[724]
static largely
Maxim
24-Jun-2009
[725]
cause with rebol its easy to hack stuff up using out of the box tricks.....