Object Sea - Work in Progress
[1/17] from: al::bri::xtra::co::nz at: 21-Feb-2002 19:33
Hi, everyone!
I've been working on storing Rebol objects to a file and retrieving them
again, which I'm calling a "Object Sea" for want of a better phrase or word.
An object sea looks like:
[
make object! [
M: 123
Name: "Sea #1"
O:
make object! [
M: 456
Name: "Sea #2"
O:
make object! [...]
F: none
]
]
make object! [
M: 456
Name: "Sea #2"
O:
make object! [
M: 123
Name: "Sea #1"
O:
make object! [...]
]
F: none
]
make object! [
outside:
make object! [
N: "Antidisestablishmentarianism"
]
]]
Which is basically a block "containing" a number of objects, in this case, 3
objects with one object "outside" the block or sea. When run through my
'Freeze function, this becomes frozen into:
[
make object! [
M: 123
Name: "Sea #1"
O: './2
]
make object! [
M: 456
Name: "Sea #2"
O: './1
F: none
]
make object! [
outside: './4
]
make object! [
N: "Antidisestablishmentarianism"
]]
With objects all inside the block and object "references" replaced with a
path like:
'./2
which mimics the use of the file directories %.. (parent directory) and
%. (containing directory). This block can then be 'save-ed to disk as a
file, then 'load-ed and 'Melt-ed into a object sea.
At the moment, the 'Freeze-ing and 'Melt-ing functions don't work with
function! values, though they do seem to work with other values (except
maybe block! values...). I'm having a little trouble with Rebol/View
crashing, when I uncomment the script lines that are currently commented
out. No doubt, I'm doing something wrong in my script in handling function!
values.
I'm intending to store function! values in object! at the end of the object
sea block, so that the same functions in multiple objects need only have one
function stored in the 'ice version. Then when 'Melt-ed, all objects are
restored to the object sea with only one function, instead of multiple
copies.
Any one got any ideas or suggestions, on what the script code for handling
function! values should be for 'Melt and 'Freeze?
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
-><-
[
Rebol [
Name: 'Sea
Title: "Sea"
File: %Sea.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 21/Feb/2002
]
Outrider: make object! [
N: "Antidisestablishmentarianism"
]
; Example object sea.
Sea: reduce [
make object! [
M: 123
Name: "Sea #1"
O: none
;F: func [X [integer!]] [M: M + X]
]
make object! [
M: 456
Name: "Sea #2"
O: none
F: none
]
make object! [
outside: Outrider
]
]
; First and second objects contain each other.
Sea/1/O: Sea/2
Sea/2/O: Sea/1
;Sea/2/F: get in Sea/1 'F
Freeze: function ["Freezes Object Sea" Sea [block!] /Compact] [Path Index] [
foreach Object Sea [
foreach Word next first Object [
any [
;if function? in Object :Word [
; true
; ]
if object? Path: Object/:Word [
set in Object Word make lit-path! reduce [
'.
either found? Index: find Sea Path [
index? Index
] [
append Sea Path
length? Sea
]
]
]
]
]
]
Sea ; At this point, the 'Sea has become ice. :)
]
Melt: function ["Melts Object Ice" Ice [block!]] [Path] [
foreach Object Sea [
foreach word next first Object [
Path: Object/:Word
if all [
path? Path
2 = length? Path
'. = first Path
integer? last Path
] [
set in Object Word pick Ice last Path
]
]
]
Ice ; At this point, the 'Ice has become sea. :)
]
probe Melt probe Freeze Sea
halt
]
-- Attached file included as plaintext by Listar --
-- File: Sea.r
[
Rebol [
Name: 'Sea
Title: "Sea"
File: %Sea.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 21/Feb/2002
]
Outrider: make object! [
N: "Antidisestablishmentarianism"
]
; Example object sea.
Sea: reduce [
make object! [
M: 123
Name: "Sea #1"
O: none
;F: func [X [integer!]] [M: M + X]
]
make object! [
M: 456
Name: "Sea #2"
O: none
F: none
]
make object! [
outside: Outrider
]
]
; First and second objects contain each other.
Sea/1/O: Sea/2
Sea/2/O: Sea/1
;Sea/2/F: get in Sea/1 'F
Freeze: function ["Freezes Object Sea" Sea [block!] /Compact] [Path Index] [
foreach Object Sea [
foreach Word next first Object [
any [
;if function? in Object :Word [
; true
; ]
if object? Path: Object/:Word [
set in Object Word make lit-path! reduce [
'.
either found? Index: find Sea Path [
index? Index
] [
append Sea Path
length? Sea
]
]
]
]
]
]
Sea ; At this point, the 'Sea has become ice. :)
]
Melt: function ["Melts Object Ice" Ice [block!]] [Path] [
foreach Object Sea [
foreach word next first Object [
Path: Object/:Word
if all [
path? Path
2 = length? Path
'. = first Path
integer? last Path
] [
set in Object Word pick Ice last Path
]
]
]
Ice ; At this point, the 'Ice has become sea. :)
]
probe Melt probe Freeze probe Sea
halt
]
[2/17] from: carl:cybercraft at: 21-Feb-2002 21:57
On 21-Feb-02, Andrew Martin wrote:
> Hi, everyone!
> I've been working on storing Rebol objects to a file and retrieving
> them again, which I'm calling a "Object Sea" for want of a better
> phrase or word.
Nothing to do with what you're trying to achieve Andrew, but "Object
Sea" is a term used in the Kosh idea...
http://kosh.convergence.org/workinggroups/la1/summary/
Kosh was set up to explore some of Fleecy Moss's ideas, Mr. Moss being
currently Vice President of Development at Amiga Inc.
Anyway, I'm not too sure, (well, haven't a clue:), what you're trying
to do, but I've been storing and receiving REBOL objects by just
saving the objects then loading and do-ing them to get them back to
their original state. ie...
>> an-obj: make object! [a: make object! [b: does [print "hello"]]]
>> an-obj/a/b
hello
>> save %test.txt an-obj
>> obj: load %test.txt
== [
make object! [
a:
make object! [
b: func [] [print "hello"]
]
]
]
>> obj/a/b
** Script Error: Invalid path value: a
** Near: obj/a/b
>> obj-true: do obj
>> obj-true/a/b
hello
You probably know you can do that though...
--
Carl Read
[3/17] from: rotenca:telvia:it at: 21-Feb-2002 16:26
Hi Carl Read
> Anyway, I'm not too sure, (well, haven't a clue:), what you're trying
> to do, but I've been storing and receiving REBOL objects by just
> saving the objects then loading and do-ing them to get them back to
> their original state. ie...
I do not know his goal, but look at this:
>> a: context [b: context [c: none]]
>> a/b/c: a/b
>> do load mold a ;it is like save and load
** Script Error: ... has no value
** Near: ...
Why?
>> print mold load mold a
[
make object! [
b:
make object! [
c:
make object! [...]
]
]
]
Reflexions become [...] but Load can't understand them obviously.
Your code (save + load) works only for object without any reflexions.
It is good also for small object collections: think to an object of 1000
item, with 5 internal references for every object, and save will create a
50.000 "make object []" stuff. Too much overhead, i think.
A good function to save and load complex objects tree is welcome.
---
Ciao
Romano
[4/17] from: rotenca:telvia:it at: 21-Feb-2002 18:02
Hi, Andrew
This is your file with my corrections. I checked only the error problem, not
the work of function.
There was 2 problems: you executed the functions inside objects instead of
only referencing it.
(I ask myself why it crashed Rebol, instead of only throwing an error.)
In general there are other problems with load/save:
1) a file like % which comes from
a: context [b: tail %local/any.r]
can't be restored by load (which gives an error - perhaps other series have
the same problem).
2) series must be saved from head and then re-positioned, if we want to clone
the object.
3) unset value can not be restored (should be called the unset func on every
unset value)
4) i think there is something else but i did not remember what...
Ciao
Romano
-------------------
Rebol [
Name: 'Sea
Title: "Sea"
File: %Sea.r
Author: "Andrew Martin"
eMail: [Al--Bri--xtra--co--nz]
Date: 21/Feb/2002
]
Outrider: make object! [
N: "Antidisestablishmentarianism"
]
; Example object sea.
Sea: reduce [
make object! [
M: 123
Name: "Sea #1"
O: none
F: func [X [integer!]] [M: M + X]
]
make object! [
M: 456
Name: "Sea #2"
O: none
F: none
]
make object! [
outside: Outrider
]
]
; First and second objects contain each other.
Sea/1/O: Sea/2
Sea/2/O: Sea/1
Sea/2/F: get in Sea/1 'F
Freeze: function ["Freezes Object Sea" Sea [block!] /Compact] [Path Index] [
foreach Object Sea [
foreach Word next first Object [
any [
if function? get in Object :Word [
true
]
if object? Path: Object/:Word [
set in Object Word make lit-path! reduce [
'.
either found? Index: find Sea Path [
index? Index
] [
append Sea Path
length? Sea
]
]
]
]
]
]
Sea ; At this point, the 'Sea has become ice. :)
]
Melt: function ["Melts Object Ice" Ice [block!]] [Path] [
foreach Object Sea [
foreach word next first Object [
Path: to path reduce ['Object :Word]
if all [
path? :Path
2 = length? :Path
'. = first :Path
integer? last :Path
] [
set in Object Word pick Ice last :Path
]
]
]
Ice ; At this point, the 'Ice has become sea. :)
]
probe Melt probe Freeze Sea
halt
[5/17] from: al:bri:xtra at: 22-Feb-2002 7:11
Carl wrote:
> Nothing to do with what you're trying to achieve Andrew, but "Object
Sea" is a term used in the Kosh idea...
> http://kosh.convergence.org/workinggroups/la1/summary/
> Kosh was set up to explore some of Fleecy Moss's ideas, Mr. Moss being
currently Vice President of Development at Amiga Inc.
That's where I got the idea from. My implementation of Freeze and Melt is
just a small step along the way.
Romano wrote:
> I do not know his goal,...
It's to save a complex tree or mesh of objects and correctly reload them,
without having duplicates or problems like:
> Reflexions become [...] but Load can't understand them obviously.
My code doesn't handle block! values correctly. That should be fixed later
today, hopefully. Still haven't figured out my problem with function! values
yet. Can anyone help?
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[6/17] from: greggirwin:mindspring at: 21-Feb-2002 12:07
Hi Andrew,
<< Still haven't figured out my problem with function! values yet. Can
anyone help? >>
What is your specific problem? If you use GET IN <object> :<word>, then
you've got the function value. Are you running into some issue when you
MOLD, LOAD, or DO it in the freeze/melt process? Can you use SECOND and
THIRD on the function value to extract the spec and body blocks and operate
on those once you have block support working?
I haven't tried MOLD, et al on complex objects or functions to know what
problems might crop up.
--Gregg
[7/17] from: petr:krenzelok:trz:cz at: 21-Feb-2002 20:24
Folks,
as I don't want you to waste time on fixing some things which can get
fixed in upcoming Rebol release, I just would like to point out to you,
that Rebol reflection capabilities are going to be adressed in some way.
I would have to ask Carl or Holger though, if I could post collected IOS
messages regarding the topic here.
-pekr-
[8/17] from: rotenca:telvia:it at: 22-Feb-2002 1:24
Hi Andrew,
> Romano wrote:
> > I do not know his goal,...
>
> It's to save a complex tree or mesh of objects and correctly reload them,
> without having duplicates or problems like:
I suspected it :-)
> > Reflexions become [...] but Load can't understand them obviously.
>
> My code doesn't handle block! values correctly. That should be fixed later
> today, hopefully. Still haven't figured out my problem with function! values
> yet. Can anyone help?
I have already posted my solution. Remains in it a my typing error:
correct my line:
Path: to path reduce ['Object :Word]
with
Path: to path! reduce ['Object :Word]
Note the ! after "to path".
---
Ciao
Romano
[9/17] from: al:bri:xtra at: 22-Feb-2002 17:18
Romano wrote:
> I have already posted my solution.
Email sending and receiving seems to be very slow at my end of the 'net.
Sorry.
> Remains in it a my typing error:
Thank you for the correction, Romano.
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[10/17] from: al:bri:xtra at: 22-Feb-2002 16:31
Romano wrote:
> This is your file with my corrections. I checked only the error problem,
not the work of function. There was 2 problems: you executed the functions
inside objects instead of only referencing it. (I ask myself why it crashed
Rebol, instead of only throwing an error.)
Thank you, Romano! :) That's great! I'll get on to incorporating block!
value saving so that the MANY part is done.
> In general there are other problems with load/save:
>
> 1) a file like % which comes from
>
> a: context [b: tail %local/any.r]
>
> can't be restored by load (which gives an error - perhaps other series
have the same problem).
> 2) series must be saved from head and then re-positioned, if we want to
clone the object.
Both of these problems are the same, a series which isn't positioned at the
head. I'll make sure that this is compensated for in 'Freeze and 'Melt.
> 3) unset value can not be restored (should be called the unset func on
every unset value)
I'll look for the unset! word and replace with the unset! value in 'Melt.
> 4) i think there is something else but i did not remember what...
Something to do with series, perhaps issue! ? Or maybe bitset value (can't
remember the datatype), where save-d and load-ed values differ IIRC?
Anyone have suggestions?
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[11/17] from: al:bri:xtra at: 22-Feb-2002 16:21
pekr wrote:
> as I don't want you to waste time on fixing some things which can get
fixed in upcoming Rebol release, I just would like to point out to you, that
Rebol reflection capabilities are going to be adressed in some way.
That's OK. When the new version of Rebol/Core and Rebol/View come out, I'll
adjust my script appropriately.
> I would have to ask Carl or Holger though, if I could post collected IOS
messages regarding the topic here.
Those messages would be good to see. I had thought that Rebol/IOS had
stopped, 'cause I couldn't connect on my new computer (and hadn't connected
for a long time on my previous computer). :-\
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[12/17] from: ammonjohnson:yah:oo at: 22-Feb-2002 1:31
Interesting to find someone else experiencing that. I haven't been able to
connect for about a month now since my ISP installed a new Linux
Firewall/Content filter. ;-/
Enjoy!!
Ammon
[13/17] from: al:bri:xtra at: 22-Feb-2002 22:30
Here's my latest implementation of 'Freeze:
Freeze-Value: function [Sea [block!] Value] [Index] [
any [
if any [
function? :Value
object? Value
] [
make lit-path! reduce [
'.
either found? Index: find/last Sea :Value [
index? Index
] [
append Sea :Value
length? Sea
]
]
]
if series? Value [
make lit-path! reduce [
'.
either found? Index: find/last Sea head Value [
index? Index
] [
append Sea head Value
length? Sea
]
index? Value
]
]
Value
]
]
Freeze: function ["Freezes Object Sea" Sea [block!]] [Block Object Value] [
foreach Fish Sea [
any [
if block? :Fish [
Block: Fish
forall Block [
Value: Block/1
Block/1: Freeze-Value Sea :Value
]
]
if object? :Fish [
Object: Fish
foreach Word next first Object [
Value: get in Object Word
set in Object Word Freeze-Value Sea :Value
]
]
]
]
Sea ; At this point, the 'Sea has become ice. :)
]
It correctly handles series that aren't at their head, by appending the
offset onto the path. I haven't yet got 'Melt working properly. I'm fairly
sure that the above two functions can be reduced in size.
Andrew Martin
Antartic Rebol...
ICQ: 26227169 http://valley.150m.com/
[14/17] from: rotenca:telvia:it at: 22-Feb-2002 12:39
Hi, Martin
I remember: the problem is con ports. But i think your program should change
them in a none value.
> Something to do with series, perhaps issue! ? Or maybe bitset value (can't
> remember the datatype), where save-d and load-ed values differ IIRC?
Some notes:
1) With issue there is this problem:
a: to issue! "dff;kkk"
print a
print mold a
2) Your routine doesn't check inner references, like this:
sea/2/O: Sea/1/Name
3) Your path ./ is a valid path, so could be confused with an user path.
---
Ciao
Romano
[15/17] from: al:bri:xtra at: 23-Feb-2002 9:47
Romano wrote:
> I remember: the problem is con ports. But i think your program should
change them in a none value.
Can you give an example of this, please?
> 1) With issue there is this problem:
>
> a: to issue! "dff;kkk"
> print a
> print mold a
>> a: to issue! "dff;kkk"
== #dff
This looks like a problem that Rebol HQ has to fix. :-( At the moment, I
can't see a reasonable way around this. For now, I'll just not use
semicolons in issue! values.
> 2) Your routine doesn't check inner references, like this:
>
> sea/2/O: Sea/1/Name
That's fixed in latest version.
> 3) Your path ./ is a valid path, so could be confused with an user path.
That's true. Which is why I check the path carefully in 'Melt. I'm also
reusing the current directory convention of %./name.txt, so hopefully that's
not a problem with typical cases.
Thanks for your comments, Romano.
Andrew Martin
ICQ: 26227169 http://valley.150m.com/
[16/17] from: rotenca:telvia:it at: 23-Feb-2002 0:31
Hi, Andrew
> Can you give an example of this, please?
>> type? system/ports/input
== port!
>> x: do mold system/ports
>> type? x/input
== object!
Others port problems are unset values, invalid tail series, and internal
buffers (what to do of them?).
Others difficult datatype: event!, error! and structure (?!).
The problem of problem is preserving the binding of words (a impossible thing
in some cases and a nightmare in many others).
> >> a: to issue! "dff;kkk"
> == #dff
>
> This looks like a problem that Rebol HQ has to fix. :-( At the moment, I
> can't see a reasonable way around this. For now, I'll just not use
> semicolons in issue! values.
The workaround is to form the issue! and make a to-issue on the formed value
(but who care?).
---
Ciao
Romano
[17/17] from: greggirwin:mindspring at: 23-Feb-2002 10:39
Hi Andrew,
<< This looks like a problem that Rebol HQ has to fix. :-( At the moment, I
can't see a reasonable way around this. For now, I'll just not use
semicolons in issue! values. >>
Just FYI. It's not only semicolons, but spaces, tabs, and newlines as well.
Maybe more.
--Gregg