Trying to make include guards, having issues...

Started by itistoday, August 30, 2008, 09:24:42 PM

Previous topic - Next topic

itistoday

The basic idea is to allow a file to be loaded multiple times safely, same concept as with C header guards.  I'm having issues with my solution though which goes like this:


;; file class.lsp

(context MAIN)
(if-not Class (begin

(context 'Class)

(define (some-function) (println "hello!"))

))


This way "class.lsp" can be (load)'ed multiple times from multiple files.



However, it doesn't really work.  For some odd reason the defined functions go into the MAIN context and not the Class context.



Help?
Get your Objective newLISP groove on.

cormullion

#1
I think you have to use load after a context switch. The manual has much to say on symbol creation in contexts, some of which might be the issue here: "a context switch should only occur on the top level of a program, never inside a function".


(if-not Class
   (begin
    (context 'Class)
    (load ...


Jeff's written some dependency handling code... http://static.artfulcode.net/newlisp/nlmod.lsp.html">//http://static.artfulcode.net/newlisp/nlmod.lsp.html ...

cormullion

#2
sorry for double post: the forum was unhappy this morning...

Lutz

#3
Just put a


(set 'MyClass:loaded true)

into each module file, where MyClass is the class name of that module. Then you can do:


(if (not (ThisClass:loaded)) (load "thisclass.lsp"))

(if (not (ThatFile:loaded)) (load "thatfile.lsp"))


Also: loading a module files multiple times will not waste any more memory, but just overwrite previous function definitions.

itistoday

#4
Quote from: "cormullion"I think you have to use load after a context switch. The manual has much to say on symbol creation in contexts, some of which might be the issue here: "a context switch should only occur on the top level of a program, never inside a function".


Hmm... I think I was confused by Lutz's use of it here:


; in CGI:put-page
(context MAIN)
(eval-string (slice page (+ start 2) (- end start 2)))
(context CGI)


But I guess after read that part in the docs it seems to be referring to the idea that any symbols created using (sym) and (load) by eval-string will therefore be created in the MAIN context.


Quote from: "Lutz"Just put a
(set 'MyClass:loaded true)


That seems to work, thanks, but it's kind-of annoying in the sense that if you're using a module that doesn't do that you're going to have to make a custom version of it.  The reason that this matters is because some modules don't just define things, they also execute code, and sometimes you don't want that code to be executed twice (for example, your CGI.lsp or Jeff's Request.lsp).



Why don't (define) and (set) also create the symbols in the current context..?  My approach would work if they did...  And sometimes they seem to but they don't in the way I tried to use it.  Why is this?
Get your Objective newLISP groove on.

itistoday

#5
Edit]


; file util.lsp - this file can safely be loaded multiple times
(context MAIN)

(define (load-once:load-once)
(doargs (file)
(if-not (find file _loaded)
(begin
(push file _loaded)
(context MAIN)
(load file)
(context load-once)
)
)
)
)


That should work right?  Used like so:


(load "util.lsp")
(load-once "some.lsp" "classes.lsp" "load.lsp" "poorly.lsp")
Get your Objective newLISP groove on.

itistoday

#6
I've edited the above post... after testing that doesn't seem to work from apache... but works when running newlisp with -http..  I'd appreciate any help understanding this!
Get your Objective newLISP groove on.

itistoday

#7
OK... I think it does work, and here's a slightly simplified version, as I think I had some unnecessary stuff:


(define (load-once:load-once)
(doargs (file)
(if-not (find file load-once:_loaded)
(begin
(push file load-once:_loaded)
(load file)
)
)
)
)

(context MAIN)


It turned out that the problem was in something else that I was doing... apparently eval-string doesn't like it when it's eval-stringing an eval-string...  I'll soon post what I'm working on, a template system that uses elements from Jeff's Request/Response classes, and Lutz's CGI class, and uses them to create a truly awesome and flexible "template" system.
Get your Objective newLISP groove on.

cormullion

#8
Quotetruly awesome and flexible "template" system


looking forward to that...!