Hi, my approach is similar to Ladislav's, except I
don't presume that the user of the "library" context
necessarily wants the functions set into the global
context. So I do not use "set notation" anymore in
this situation. Instead, the user must explicitly
ask for the words that it is interested in having
set into the global context. That way there is no
hidden side effect when simply doing a file.
So the system works like this:
Contents of %your-lib.r:
context [
page-size: 58
print-before-1: func [...][...]
]
User code for a single word:
print-before-1: get in do %your-lib.r 'print-before-1
Or, User code for multiple files and words:
use [ctx][
foreach [file words][
%your-lib.r [print-before-1]
;%your-other-lib.r [some-func another-func ...]
][
ctx: do file foreach word words [
set in system/words word get in ctx word
]
]
]
So in the above case, only 'print-before-1 is added to the global
context. This is good because it was explicitly asked for in the
*user's* script, usually a different file from the reusable library
file(s).
Any problems with global words being overwritten can be seen and
fixed within the user's script.
Now imagine a situation where you are using various other people's
library files, and two of them set the same word in the global
context, and you are using that word in your program, but you are
expecting the first definition, not the second one.
You will have to debug, and it will take you time to look through
each file to see where this global setting you didn't ask for
happened.
I actually have an INCLUDE function to make the above user
code simpler, with error checking etc. and it looks in the script's
header for a block of "public-functions", which is basically just
the words the values of which the user is gently suggested it will
find the most useful.
So, contents of %your-lib.r:
rebol [
title: "hard-copy printing library"
public-functions: [print-before-1]
]
context [
print-before-1: func [...][...]
]
(It doesn't have to be called "public-functions", it could be
called "suggested-global-words" or something like that..)
My INCLUDE function actually insists that the public-functions
block exists in the script header, but in hindsight, it's probably
better not to be so strict. Really the only condition a library
file should meet to satisfy an "include system" is that it should
return an anonymous context when DOne.
Another approach, which looks so nice at first, is for
%your-lib.r to contain simply:
rebol []
page-size: 58
print-before-1: func [...][...]
And the user code:
print-before-1: get in context load %your-lib.r 'print-before-1
So it is the user code which wraps in a context.
However, I found that if the library wants to do something like this:
rebol []
lib-dir: what-dir ; store where this library is kept
page-size: 58
print-before-1: func [...][...]
then WHAT-DIR will return the current directory from the point of view
of the user's script, at the time when the library file is loaded.
(which is not the expected result.)
What you want is the current directory to be where the library file
is stored, and you only get that if you DO the file.
Another desirable thing when using DO is that the script header is
relative to the library file as well.
(An include function could work around these things, but it's not
as nice as just using DO.)
So DO is better than CONTEXT LOAD.
My include system:
http://www.lexicon.net/antonr/rebol/library/include.r
Anton.
> my approach is as follows:
>
> context [
> page-size: 58
> set 'print-before-1 func [etc]
> ]
>
> My context is anonymous, as opposed to your solution. I discern the
> words that I want to access only locally and the words that should be
> available globally. e.g. 'print-before-1 may be a global word, while
> 'page-size will be a local word not supposed to be accessed globally.
>
> -L
--
To unsubscribe from the list, just send an email to
lists at rebol.com with unsubscribe as the subject.