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

[REBOL] Re: More dialects than you think, validating function input.

From: joel:neely:fedex at: 13-Sep-2002 7:50

Hi, Dick, You've given me an idea... (Thanks!) [reffy--ulrich--net] wrote:
> Watching the thread on error handling ... >
...
> As a developer, I would like to be able to place begin/end markers > in my code. The purpose of the markers is to signal the language > execution engine the type/degree of capturing trace information. > I can imagine several fine/coarse grained levels. The coarseness of > the tracing could be at the function level, the statement level, > maybe even other levels. > > I like this approach because I probably don't want the execution > engine burdened with something which might yield an overall > performance hit. I/you can probably be the best judge of when/what > we need information about. It would be up to us to cause the > performance hit of tracing/tracking flow of control. >
This is a *real* QAD, but the idea was to write something that would let me "enclose" a block with a marker so that any error occurring within that block would generate a display of all currently active markers as well as the error message itself. Again, this is a quick hack with much room for improvement... Here's the error zone manager, in %errzone.r: 8<---------- errzone: make object! [ zones: [] init: func [] [zones: copy []] new: func [/local newself] [ newself: make self [] newself/init newself ] nest: func [s [string!] b [block!] /local err] [ insert tail zones s either error? set/any 'err try b [ print ["^/Error within"] foreach zone zones [print ["^-" zone]] print ["was^/" mold disarm err newline] halt ][ remove back tail zones ] ] ] 8<---------- Here are some error-prone routines that use ERRZONE, either recursively or in nested function evaluations: 8<---------- do %errzone.r irecurrence: func [n [integer!] /local rzone _recurrence] [ rzone: errzone/new do _recurrence: func [ p [integer!] n [integer!] /local result ][ rzone/nest rejoin ["tracing: " p ", " n] [ result: _recurrence p / n n - 1 ] result ] 1000 n ] nrecurrence: func [n [integer!] /local rzone _recurrence] [ rzone: errzone/new do _recurrence: func [ p [number!] n [integer!] /local result ][ rzone/nest rejoin ["tracing: " p ", " n] [ result: _recurrence p / n n - 1 ] result ] 1000 n ] gzone: errzone/new eenie: func [n [integer!]] [ gzone/nest "eenie" [ loop random 5 [print "blah "] print 1 / n loop random 5 [print "yak "] ] ] meenie: func [n [integer!]] [ gzone/nest "meenie" [ loop random 5 [print "blah "] eenie n loop random 5 [print "yak "] ] ] meinie: func [n [integer!]] [ gzone/nest "meinie" [ loop random 5 [print "blah "] meenie n loop random 5 [print "yak "] ] ] moe: func [n [integer!]] [ gzone/nest "moe" [ loop random 5 [print "blah "] meinie n loop random 5 [print "yak "] ] ] 8<---------- Here are some annotated results of using the above "clients": 8<----------
>> irecurrence 5
Error within tracing: 1000, 5 tracing: 200, 4 tracing: 50, 3 was make object! [ code: 303 type: 'script id: 'expect-arg arg1: '_recurrence arg2: 'p arg3: [integer!] near: [result: _recurrence p / n] where: 'nest ] 8<---------- I included this one because it surprised me at first. (I didn't read the error object carefully enough!) The value of 50 / 3 is not integral, so the attempt to invoke _RECURRENCE failed because of an argument type error. 8<----------
>> nrecurrence 5
Error within tracing: 1000, 5 tracing: 200, 4 tracing: 50, 3 tracing: 16.6666666666667, 2 tracing: 8.33333333333333, 1 tracing: 8.33333333333333, 0 was make object! [ code: 400 type: 'math id: 'zero-divide arg1: none arg2: none arg3: none near: [result: _recurrence p / n] where: 'nest ] 8<---------- Our classic poster-child error... 8<----------
>> moe 1
blah blah blah blah blah blah blah blah blah blah blah blah 1 yak yak yak yak yak yak yak yak yak yak yak yak yak yak = []
>> moe 0
blah blah blah blah blah blah blah blah blah blah blah blah blah Error within moe meinie meenie eenie was make object! [ code: 400 type: 'math id: 'zero-divide arg1: none arg2: none arg3: none near: [print 1 / n loop] where: 'nest ] 8<---------- The first call to MOE succeeded (producing lots of simulated work and output), but the second failed four levels of function evaluation down. As I said above, this is a bit kludged up, but serves as a proof of concept. For example, we could define a new function-defining word something like this safe-foo: zonefunc zoneobj "FOO Zone" [...args...] [...body...] in contrast with foo: func [...args...] [...body...] to wrap the body of the newly-defined function with an appropriate use of the ERRZONE concept. -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]