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

World: r3wp

[Rebol School] Rebol School

Henrik
7-Apr-2009
[2693]
sorry, I thought you had a result to test.
PatrickP61
7-Apr-2009
[2694]
I've been reading up a little on generating errors at http://rebol.com/r3/docs/concepts/errors-generating.html
one line in particular captured my attention:


The error message generated for my-error can be printed without stopping 
the script:

disarmed: disarm err
print bind (get disarmed/id) (in disarmed 'id)
this doesn't go into that using my-function

-- Not sure if this has any legs for me?
Henrik
7-Apr-2009
[2695]
if you want to generally test the entire script, the only way is 
to wrap it in a TRY or the elements you run in a TRY. REBOL will 
stop evaluating a block if it encounters an error in it.
PatrickP61
7-Apr-2009
[2696x2]
Yes, but there must be ways to trap an error without stopping the 
script.
Or are you saying that another function such as TRY will "insulate" 
the error from causing my script to stop running?
Henrik
7-Apr-2009
[2698x3]
'err in that example means you have evaluated a block and the result 
is returned to 'err. you can then test if 'err contains a good result 
or an error like so:

if error? err [
	print "oops"
]
or more useful:

if error? err [probe disarm err]
that's the only way. the only way to simply keep going is to wrap 
small bits of code in TRY and that's not good style.
PatrickP61
7-Apr-2009
[2701x5]
trying to understand -- :-/  (still a newbie!!!)
OK, lets take a simple example that I know errors out
UNSET [x]
print x
x is undefined and has no value
so how would I change the PRINT X in such a way to capture an error 
withotu stopping the script?
But, if the command succeeds without error, I want to get the results 
of that as well
Henrik
7-Apr-2009
[2706x2]
unset [x]
set/any 'err try [print x]
if error? err [
	probe disarm err
]
and you may continue after that if err is not an error.
PatrickP61
7-Apr-2009
[2708]
giving it a try!
Henrik
7-Apr-2009
[2709]
but... it all depends on what the ultimate goal of trapping the errors 
is. if the code was written properly, you'd do this:

unset [x]
unless value? 'x [
	print "X has no value"
]
PatrickP61
7-Apr-2009
[2710x5]
Yes, you are correct,  The purpose of THIS script is to test and 
verify the R3 documents and see if the results printed on the website 
is the same as the results you get (for r3alpha)
So, I want to capture the error message as it would appear -- even 
though I know it will stop the script.  I just hoped there was a 
way of having R3 print the error message as it normally would, but 
then have R3 continue to run the script instead of stopping it.  


For example, if I knew that R3 was using the HALT command, then I 
could temprarily redefine the HALT command to an empty block and 
R3 should continue to run, but I am just spouting this off the top 
of my head -- I don't know how R3 "stops" the script.
Henrik,  Your suggestion did achomplish the task of trapping an error 
when it happened so it is better than nothing -- see resutls:

Rebol []
echo  %VT-Results.txt
print {Results below generated from %VT-Script.r}
          print {unset [x]}
                 unset [x]
           print {print x}

set/any 'err try [print x] if error? err [ disarm err print "** error"]
print ""
           print {print x}

set/any 'err try [print x] if error? err [ disarm err print "** error"]
print ""
print {See results stored in %VT-Results.txt file}
echo off
halt

will generate:

Results below generated from %VT-Script.r
unset [x]
print x
print x
See results stored in %VT-Results.txt file
oops, wrong cut and paste -- here is the revised results:

Results below generated from %VT-Script.r
unset [x]
print x
** error

print x
** error

See results stored in %VT-Results.txt file
If only there was a way to "capture" the specific error message at 
the time of disarm err, and print those results 
Could that be done?
Oldes
7-Apr-2009
[2715x5]
of course.. just do:
 probe disarm err
I'm ussing:
attempt: func [value][
    either error? set/any 'value try :value [
        print parse-error disarm value none
    ] [get/any 'value]
]
parse-error: func [
    error [object!]
    /local type id arg1 arg2 arg3 wh
][
    type: error/type
    id: error/id
    wh: mold get/any in error 'where
    either any [
        unset? get/any in error 'arg1
        unset? get/any in error 'arg2
        unset? get/any in error 'arg3
    ] [
        arg1: arg2: arg3: "(missing value)"
    ] [
        arg1: error/arg1
        arg2: error/arg2
        arg3: error/arg3
    ]

    rejoin ["** " system/error/:type/type ": " reduce either block? system/error/:type/:id 
    [
            bind to-block system/error/:type/:id 'arg1
        ] [
            form system/error/:type/:id
        ]
        newline

        reform ["** Where: " wh newline "** Near: " mold error/near newline]
    ]
]
Now when I see the code (which is probably not mine), the handling 
of args is not correct as any missing arg will now set all of them 
as "(missing value)". But at least you can have an idea, how to work 
with the disarmed error!
Anyway, I use modified append to be able see if there is an error 
somewhere (where is unexpected) without stoping the execution. If 
I know, that somewhere can be an error, then I use just simple  error? 
try []
*append = attempt
PatrickP61
7-Apr-2009
[2720]
Thanks Oldes, I'll play with it!
sqlab
8-Apr-2009
[2721]
Wrap your tests in a block, then you can do at least in R2
until [ 
	either error? set/any 'err try [
		t:  do/next tests
	] [
		print disarm err
		tests: next tests
	] [
		tests: second t
	]
	empty? tests
]
 
Unfortunately it does not work with R3. .(

There you have to wrap every statement in a block  inside the main 
block.
Then you can do them one  by one.
Janko
16-Apr-2009
[2722x2]
if I have rebol object  R2 >>


A: make object [ add: func [ ] [ .... ]   remove: func [ ] [ ....... 
]  parse-rule: [ ..... ] ]
B: make A [ change: func [ ] [ .... ] ]

<< 

and if I make 100 objects like B from A ... does this mean each of 
them has it's own "add remove parse-rules" copy in memory or there 
is just one copy of these functions/blocks that they share it?
it seems it makes copies
PeterWood
16-Apr-2009
[2724]
I believe you are correct. There is no separate "prototype" in Rebol.
sqlab
16-Apr-2009
[2725]
You can use this method, if you don't want to get copies

 A: make object! [ add: func [ ] [ .... ]     sub: make object! [parse-rule: 
 [ ..... ] ]]
then the elements in the subobject are just references.
Janko
16-Apr-2009
[2726x6]
I was away... I tested on these 3 cases... started new rebol each 
time, it took 13MB of ram at start


A: make object! [ a: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 
b: [ 123 1231 13 123 12313 1

2312 3123 123123 12 231 21 312 12 123 31231231 2312 312 1231 2123 
123 12 3123 12 312 312 312 312 31 23 123 123 12 312 31 23 123 12 
312 312 3 123 12 312 31 23

123 12 312 3 123 12 31 3 123 13 12  123 123 12 3 123 1231 23 123 
123 12 312 3 123 12 312 3 123 12 312 3 123 12 31 23 123 12 31 23 
123 1 23 123 12 31 2 23 12 3
1 3 12 312 3 123 12 3 ] ] AS: copy []
loop 100000 [ append AS make A [ ] ]

went to 250MB RAM
-- 



A: make object! [ a: does [ print "something" a: 2 + 3 + 5 loop 10 
[ print "a" ] ] ] AS: copy []
loop 100000 [ append AS make A [ ] ]

went to 50MB of ram
--

A: make object! [ a: "" ] AS: copy []
loop 100000 [ append AS make A [ ] ]

went to 25MB of ram
--
sqlab - I will try what you say.. I asked because at the actor lib 
I am making each actor/thread is one object so I want to have them 
as lightweight as possible
( It is understandable why is this , block (like parse block or block 
of code) , and also func in rebol body is just "data" and you can 
change it in each instance ) ..
sqlab - bravo! your trick works..  


A: make object! [ proto: make object! [ a: does [ print "something" 
a: 2 + 3 + 5 loop 10 [ print "a" ] ] ] ] AS: copy []
loop 100000 [ append AS make A [ ] ]

went to 21MB ram
 
---

I have to see what this means to inheritance and other things
I also tried this but it works the same as if I define block in object 

A-a: [ print "something" a: 2 + 3 + 5 loop 10 [ print "a" ] ]
A: make object! [ a: does A-a ] AS: copy []
loop 100000 [ append AS make A [ ] ]
sqlab: hm.. but do you know for a way that subobject could access 
parent's objects data?
sqlab
16-Apr-2009
[2732]
You have to give the parent object as a parameter to the functions 
in the sub objects, then you can acces the elements as 
pobj/name
Janko
16-Apr-2009
[2733x5]
I tried this.. but self in that context is the subobject ... 

actor-static!: make object! [ 
	parent: none
	act-match: copy []
	act: [ match-do take mbox act-match ]
	test: [ print parent/mbox ]
	mode: 'm
]

actor: make object! [ 
	mbox: copy []
	vars: copy []
	static: make actor-static! [ parent: self ]
]
hm.. but act are blocks of code .. not functions right now so they 
don't have params
so they can be used like this... this is how it currently worked 
(without static)  ... 

cat-boss: make actor [ 
	act-match: [

   [ still-seeking ] [ print "cat boss: our cat agent is still seeking!!" 
   ]
			[ found-fish ] [ print "cat boss: yeey, we found a fish!!" ]
	]
]


... anyway, thanks for your help so far a lot! I need to start my 
brain, it seems it doesn't work very well today
aha, this works, thanks to your ideas.

actor-static!: make object! [ 
	parent: none
	act-match: copy []
	act: [ match-do take parent/mbox act-match ]
	test: [ print parent/mbox ]
	mode: 'm
]

actor: make object! [ 
	S: self
	mbox: copy []
	vars: copy []
	static: make actor-static! [ parent: S ]
]
ah, I am stupid is actor-static is just one for 100 copires than 
parent can't only point to one parent so this won't work
sqlab
16-Apr-2009
[2738]
Unfortunately i do not understand, what you do with your actors.
Janko
16-Apr-2009
[2739x4]
http://itmmetelko.com/blog/2009/04/12/playing-with-making-an-actor-like-distributed-system-in-rebol/
 ... I am thinking that I won't change it all and make usage more 
ugly becase right now I don't even know If I will ever need to have 
100000 actors running..  so for now I will continue using object 
and try to make it elegant without worying about this
(again , it hot distorted) ... I am thinking that I won't change 
it all and make usage more ugly becase right now I don't even know 
If I will ever need to have 100000 actors running..  so for now I 
will continue using object and try to make it elegant without worying 
about this
hot = got
I need to see more how this is used before I start optimising, I 
thought I can make some optimisation without complicating it all 
up and make it less elegant to use and extend