World: r3wp
[Core] Discuss core issues
older newer | first last |
Fork 31-Mar-2008 [9806x4] | Thanks Gabriele, I think I understand, and knowing the actual answer is helpful in understanding the fundamental springs and pulleys that make the REBOL machine work. |
One of the first errors I encountered while trying to run an installer that was built in REBOL was that a state machine driven by a variable was failing to match a case and falling through to a default, due to a spurious linefeed on one of the cases that was read in. It was attempting to match foo, but had foo^/ ... and so it fell through to the wrong case. So I have been tinkering with a checked enum for REBOL. | |
If anyone has input on to the approach, I'd appreciate feedback: http://pastebin.com/d698d3c16 | |
Oops, deleted some spurious code and that made a typo, will make a better version that prints section headers for the tests... | |
Anton 1-Apr-2008 [9810x5] | I guess you figured it out already, but you can use TRIM to remove leading and trailing whitespace from your input. |
I'm not sure why you are taking this approach, but it seems to be something which you might implement to make another language more useful :) I don't think it's needed in rebol. Perhaps you could explain how you're using this enum/switch in more detail... | |
A small tip: for index 1 (length? cases) 1 [ is usually better as: repeat index length? cases [ | |
(I almost never use FOR. I use REPEAT very often). | |
Fork, perhaps you can show us the original (approximate) example from your installer state machine, with a few example inputs and expected results. Then we can see what started all this :) | |
Fork 1-Apr-2008 [9815x5] | Here is a better documented version: |
http://pastebin.com/m2e06f2b7 | |
I explain the cases in the header | |
Here is the output with performance data of the testing: | |
http://pastebin.com/m20abc2ca | |
Anton 1-Apr-2008 [9820] | Ok, that explains the enum object well. However, it looks like a waste of time to me ! (sorry) but I haven't felt I needed this in rebol for many years ! |
Fork 1-Apr-2008 [9821x2] | I suppose it depends on what kind of code you write |
This specific case came up when I tried to install a large, professional grade REBOL system written by people who are as I understand it very good at REBOL | |
Anton 1-Apr-2008 [9823] | That may be true. |
Fork 1-Apr-2008 [9824] | There is no integrated debugger, and so tracking this kind of stuff down isn't as easy as it might otherwise be |
Anton 1-Apr-2008 [9825] | Can we see what the specifics of the original case are with respect to the enum ? |
Fork 1-Apr-2008 [9826x5] | nextstep: cgi 'nextstep |
So it was getting a CGI variable in an HTTP post | |
Then it did switch/default nextstep [ (various cases, pages long) ] [ the default case ] | |
A bug in the cgi system left a trailing newline on the nextstep variable | |
SO instead of being "apache1" it was "apache1^" | |
Anton 1-Apr-2008 [9831x3] | Ok, so you saw the enum object as an extra level of protection against this kind of bug. |
To more strictly validate input. | |
Or was it just to catch where the bug was ? | |
Fork 1-Apr-2008 [9834x2] | It validates on all sides, it protects against programmer error in the usage as well as things like this where the data source or function has a problem. |
I do like REBOL from what I've seen so far! But I saw somewhere that it was being compared to modeling clay... it's a paradigm shift for people who are used to systems that do a lot of global analysis of your program before it runs the first line of code to catch basic errors. | |
Anton 1-Apr-2008 [9836x2] | Yes, definitely. |
make-enum-type should define 'ret local. | |
Fork 1-Apr-2008 [9838] | I do remember that, though I don't exactly remember what happens if you don't do it |
Anton 1-Apr-2008 [9839] | It sets 'ret global. Check this by running the script then probe ret in the console. |
Fork 1-Apr-2008 [9840x4] | Ah, ok |
So same for test-block | |
(start/end) | |
And pretty much everything else... I'll go over it. I should probably use "function" as I don't care so much for /local | |
Anton 1-Apr-2008 [9844] | Yes, but that's just your test code. Usually I don't bother being so strict with test code because I know I'm going to throw away the console afterwards. The reusable library part is the important part to be watertight. |
Fork 1-Apr-2008 [9845] | I get the feeling that I'm going to want to have an analysis tool which will read through the functions, find any variable: assignments, and ensure they're in the local list unless there's some sort of indication they should be global. Because it seems relatively uncommon that I would, inside a function, set things in the global space. I'd be happy to use something wordier (set?) for that |
Anton 1-Apr-2008 [9846] | I recommend FUNC over FUNCTION because having "/local" written makes it clearer and explicit what the locals are, and is shorter when there are no locals. Compare: When there are no locals, func wins, because less characters to type. func [] function [][] When there are locals, same number of characters written, but func more clearly specifies the locals. func [/local] function [][] Additionally, when you are modifying your func spec back and forth so that there is a need, or no longer a need, for locals, then func wins by less typing needed. |
Fork 1-Apr-2008 [9847x4] | Hm, well, it's not a tremendous deal but I feel like always being forced to remember typing in that second group would remind me that I need to think about what goes in it |
Is there a way to set things locally in a do block? | |
Or do you have to do a nameless function to get a local context? | |
e.g. do func[/local v] [v: 1+2] | |
Anton 1-Apr-2008 [9851x2] | I go without such a tool for analysing function local variable consistency, which, I think, turns out to be a difficult problem to solve. Some people have written alternative function creators which somehow make set-words into locals by default (Ladislav ? with his lfunc ?) or something like that. I just maintain a strict habit of checking for accidental globals. It's good to review your use of variables regularly anyway, and be aware of what context they're bound to. |
use [v][v: 1 + 2] | |
Fork 1-Apr-2008 [9853] | Ah, an lfunc, that sounds nice |
Anton 1-Apr-2008 [9854x2] | do [ use [v][v: 1 + 2] ] |
context [ v: 1 + 2 print v ] | |
older newer | first last |