World: r3wp
[Rebol School] Rebol School
older newer | first last |
PatrickP61 7-Apr-2009 [2688] | How does ERROR work? What does the kernal actually do when it encounters an error? I see that errors condition can be trapped with commands such as TRY, DISARM, ATTEMPT, but is there a way I can capture the printed results of an error without the error causing my script to stop running? |
Henrik 7-Apr-2009 [2689] | I think you can't, unless you settle for printing the error object. That's possible. The console error messages themselves can't be reached, I think. |
PatrickP61 7-Apr-2009 [2690] | Hi Henrik It is just fine that the console error messages print whatever they print, but I want some way of having my script continue depsite the error message encountered. Is there a way to have REBOL invoke a separate independent console that it could do its own commands in. Then, I could simply submit one rebol command per session, and capture the results in the ECHO file regardless of wheter the command errored out or not. Could that work? |
Henrik 7-Apr-2009 [2691] | it should be enough to: probe disarm error |
PatrickP61 7-Apr-2009 [2692] | I added that at the head of my VT-SCRIPT, but it didn't work ** Script error: error has no value |
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 | |
older newer | first last |