Page 1 of 1

Trying to make include guards, having issues...

Posted: Sun Aug 31, 2008 4:24 am
by 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:

Code: Select all

;; 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?

Posted: Sun Aug 31, 2008 8:08 am
by 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".

Code: Select all

(if-not Class
   (begin 
    (context 'Class) 
    (load ...
Jeff's written some dependency handling code... http://static.artfulcode.net/newlisp/nlmod.lsp.html ...

Posted: Sun Aug 31, 2008 8:09 am
by cormullion
sorry for double post: the forum was unhappy this morning...

Posted: Sun Aug 31, 2008 11:47 am
by Lutz
Just put a

Code: Select all

(set 'MyClass:loaded true)
into each module file, where MyClass is the class name of that module. Then you can do:

Code: Select all

(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.

Posted: Sun Aug 31, 2008 5:59 pm
by itistoday
cormullion wrote: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:

Code: Select all

; 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.
Lutz wrote:Just put a

Code: Select all

(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?

Posted: Sun Aug 31, 2008 6:19 pm
by itistoday
Edit: never mind, this does.?? work

Code: Select all

; 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:

Code: Select all

(load "util.lsp")
(load-once "some.lsp" "classes.lsp" "load.lsp" "poorly.lsp")

Posted: Sun Aug 31, 2008 8:43 pm
by itistoday
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!

Posted: Sun Aug 31, 2008 9:33 pm
by itistoday
OK... I think it does work, and here's a slightly simplified version, as I think I had some unnecessary stuff:

Code: Select all

(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.

Posted: Sun Aug 31, 2008 10:19 pm
by cormullion
truly awesome and flexible "template" system
looking forward to that...!