Hi Neil, On Sun 30 Jan 2011 00:17, Neil Jerram <n...@ossau.uklinux.net> writes:
> Andy Wingo <wi...@pobox.com> writes: > >> If you are using modules, they are already in one global namespace, >> the various roots of which are in the %load-path and/or >> %load-compiled-path. (resolve-module '(foo bar)) should work >> regardless of what file calls it. > > If the modules are installed, that's true. What if they are not? In that case you have to modify the load path, somehow. I have been doing this with scripts that add to $GUILE_LOAD_PATH and $GUILE_LOAD_COMPILED_PATH. (Which is another thing to note; if you have an autotooled project, the .go files go in the $builddir.) So if I'm hacking against an uninstalled tekuti, for example, I run my code within ~/src/tekuti/env. > For scripts that use uninstalled modules, then, some kind of solution is > needed; ideally one that works for both 1.8 and 1.9/2.0, allows the code > needed to live in a single common file, rather than duplicated at the > top of each script; and continues to work if the script+module tree as a > whole is moved to a different place in the filesystem. Also I think > it's preferable if the solution is a Guile one, as opposed to based on > the #! line, or needing a shell script wrapper. How would it look? I guess I am unclear on the actual problem being solved here :) Let's consider that I am hacking on my "analysis" script, which lives at ~/src/foo/analysis. I guess it's helping me in my "foo" project. Now the script gets too big; time to split into modules. How to do that? We have basically one option of a path to automatically add to the load path: ~/src/foo. It seems tractable, unless we start to consider installing the script to /usr/bin, combined with the presence of "" in the default load-extensions list, in which case the unexpected interactions with other members of that path look daunting. No, I think that the script itself will need to indicate some path to add to the load path. What you can do, perhaps, is add a macro: (define-syntax add-relative-load-path (lambda (x) (syntax-case x () ((_ path) (string? (syntax->datum #'path)) (let* ((src (syntax-source #'x)) (current-file (or (and src (assq-ref src 'filename)) (error "Could not determine current file name"))) (vicinity (dirname (canonicalize-path current-file))) (path-elt (in-vicinity vicinity (syntax->datum #'path)))) #`(eval-when (compile load eval) (set! %load-path (cons #,path-elt %load-path)))))))) Then in "analysis", you could `(add-relative-load-path ".")'. But... If you compile a .go, then install both .scm and .go somewhere, the installed .go file will reference the build path, which was inserted into the source via the current-file business. (You could argue that this is precisely the case that we are _not_ interested in, given that currently we only install .go files for files that are in the load path. But I guess we should figure out a better autocompilation story for files in $bindir.) It _is_ true that we need to figure out what's going on with (current-load-port) in 1.9, but it's not clear what to do, exactly, when you have compiled files; you could not have the corresponding .scm at all, or in any case when you've loaded the .go you don't actually have a port to the .scm, and in fact if the file was loaded via `load-from-path' you don't know exactly where the .scm is at all. Perhaps we should residualize into the .go whether the file was compiled for `load' or for `load-from-path', and what was the original path of the file. > Good point, thanks for the reminder about that. But (for 1.9/2.0) > `include' will always be well-defined and reliably relative to the > containing file's name, won't it? Yes, at expansion time. But note the .scm/.go installation case; and also note that the code that chooses when to use a .go over a .scm doesn't know anything about dependencies, currently, so a change to an included file doesn't trigger recompilation of the includer. Andy -- http://wingolog.org/