Even I make mistakes<g>
[1/3] from: ralph:abooks at: 18-Sep-2000 10:02
If anyone tried to order either REBOL FOR DUMMIES or REBOL: THE OFFICIAL
GUIDE yesterday, you found your order would not go through, even with all
the correct information. Why? Even I flub up on occasion. The forms are now
fixed and orders go though fine.
The mistake was a dumb one (as opposed to a Dummies one) and I reveal it
since you may find such instructive in your own coding. I wrote this really
slick little credit card validation function (published earlier on this
list) Saturday. Tested it rigorously, and it worked fine. So I dropped it
into the order forms; tested them briefly; all seemed fine; so I went live
with the changes. Then I get e-mail this morning from a couple of people who
tried to order books yesterday and the orders would not record. Here's the
mistake! One of the REBOL words I defined in my credit card validation
function was the same as one in my form processing script (but the words, of
course, did different functions). This mismatch did not crash the script
(such would have pointed to an obvious problem) but rather caused a more
subtle misoperation; i.e. orders would not record.
The moral of this tale? Document! I stress that in REBOL FOR DUMMIES. If you
don't document, scripts sometimes will coil around and bite you on the ....
well, anyway, I fixed it<g>.
Best,
--Ralph Roberts
Soldier of the REBOLution
[2/3] from: rebol:techscribe at: 18-Sep-2000 13:08
Hi Ralph,
modules will hopefully reduce the likelyhood of name clashes in the future.
For now I think that using objects helps to avoid this kind of errors in
scripts that evolve over time.
Another trick is to execute a trial run while PROTECTing all of those words
that one wishes to keep unique. Name clashes will then become evident when
a word is inadvertently reused.
The following script can be helpful. Given a script file filename.r it
writes a new filename.rp file.
input: filename.r
output: filename.rp
When you DO the script filename.rp all globally defined words in this
script will be PROTECTed. Attempting to redefine any of these words will
result in an error message.
How it works:
The script prompts you for a filename or a directory name.
If you provide a comma separated list of filename, the script will process
all the filenames provided.
If you provide a directory name the script will process all the files in
that directory.
Hit return if you want to process all script files in the current
directory. You do not need to provide the current directory name.
The script assumes that the files you wish to process have the extension
.r
. If a filename does not have the ".r" extension, the script will add
that extension, regardless of whether or not the filename contains a
different extension.
The script loads the script file, identifies tokens that will be defined in
the global context by the script it loaded and creates a new script file
that has the same filename as the original file. It replaces the ".r"
extension by the extension ".rp".
The script appends two things to the original script file which it saves in
the
.rp file.
1. A block called __set-words. This block contains all globally defined
words in the script (with exception of words that are defined by using the
set function.)
2. A foreach expression that protects all the words listed in the
__set-words block.
If you subsequently attempt to load a script that redefines the same word,
you will get a word protected error, which will alert you to those globally
defined words that are being redefined in this other script.
You can easily test the script by first running it to generate a ".rp"
file, DO the .rp file and then DO the original .r file.
Example:
1. First prepare a .rp file:
>> do %protect-words.r
Script: "Protect-Words" (none)
Note: Only files with a .r extension will be protected. They will be
saved to
a file that has the same name and the extension .rp.
Please enter
1. the names of the files you wish to protect separated by commas; or
2. the qualified pathname to the directory containing the files you
wish to protect; or
3. hit <enter> to protect all files with a .r extension in the
current directory.
>: %test-prscript.r
2. Now evaluate the .rp file
>> do %test-prscript.rp
Script: "Untitled" (none)
3. When you now try to redefine the globally defined word in
test-prscript.rp by evaluating the original test-proscript.r file, you are
notified of the attempt to redefine protected words:
>> do %test-prscript.r
Script: "Untitled" (none)
** Script Error: Word this is protected, cannot modify.
** Where: this: 1
that: func []
The file test-prscript.r contains the following script:
REBOL []
this: 1
that: func [] [ x: 1]
and-more: "this is more."
The resulting file test-prscript.rp contains:
REBOL []
this: 1
that: func [] [ x: 1]
and-more: "this is more."
__set-words: [and-more that this]
foreach word __set-words [
protect word
]
The protect-words.r script file contains:
REBOL [
title: "Protect-Words"
file: %protect-words.r
]
script: none
set-words: none
protect-set-words: {
foreach word __set-words [
protect word
]
}
dir: system/script/path
read-script: func [filename [%file]] [
set-words: make block! 100
script: read filename
filename
]
collect-set-words: func [filename [file!] /local tokens] [
set-words: make block! 100
tokens: load/next filename
while [not empty? tokens] [
if set-word? first tokens [
insert set-words to word! first tokens
]
tokens: load/next second tokens
]
set-words
]
make-protected-script: func [filename [file!] /local protected-filename
tokens] [
tokens: mold collect-set-words read-script filename
append script join newline "__set-words: "
append script tokens
append script join newline protect-set-words
protected-filename: append filename #"p"
write protected-filename script
]
protect-these-files: ask {
Note: Only files with a .r extension will be protected. They will be
saved to
a file that has the same name and the extension .rp.
Please enter
1. the names of the files you wish to protect separated by commas; or
2. the qualified pathname to the directory containing the files you
wish to protect; or
3. hit <enter> to protect all files with a .r extension in the
current directory.
>: }
either found? find protect-these-files "," [
protect-these-files: parse/all protect-these-files ","
][
either empty? protect-these-files [
protect-these-files: load %./
][
either dir? load protect-these-files [
dir: load protect-these-files
if (last dir) <> #"/" [ append dir #"/" ]
protect-these-files: load dir
][
protect-these-files: load protect-these-files
]
]
]
either block? protect-these-files [
foreach file protect-these-files [
if not found? find file ".r" [
append file ".r"
]
file: join dir load file
if all [
file? file
not dir? file
exists? file
(last file) = #"r"
][
make-protected-script file
]
]
][
if not found? find file ".r" [
append file ".r"
]
make-protected-script protect-these-files
]
At 10:02 AM 9/18/00 -0400, you wrote:
>If anyone tried to order either REBOL FOR DUMMIES or REBOL: THE OFFICIAL
>GUIDE yesterday, you found your order would not go through, even with all
<<quoted lines omitted: 18>>
>--Ralph Roberts
>Soldier of the REBOLution
;- Elan [ : - ) ]
author of REBOL: THE OFFICIAL GUIDE
REBOL Press: The Official Source for REBOL Books
http://www.REBOLpress.com
visit me at http://www.TechScribe.com
[3/3] from: ralph::abooks::com at: 18-Sep-2000 16:27
thanks, Elan... handy stuff.
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted