On Sep 10, 3:41 am, Eduardo Cavazos <[email protected]> wrote:
> Jose A. Ortega Ruiz wrote:
>
> > In both Guile and MzScheme, the meaning is to enter the module's
> > namespace, meaning that all identifiers bound inside the module (not
> > just the exported ones) are in scope.
>
> I would definately find that handy...
>
> It's happened soooo many times that I throw a library together and then
> need to debug one (or more) of the non-exported procedures/macros. At
> this point the workflow is:
>
> Manually adjust the exports
>
> Manually restart and reimport
> (possibly alot of stuff to get to the point I was at)
>
> Or instead of restarting, uninstall the library and reimport
>
> Debug
>
> Manually adjust the exports back
> (I wonder how many of you have littered 'exports' because you
> skipped this step! :-) )
>
> Ed
h...@all!
I first replied via google groups without realizing that I have to be
subscribed to ikarus-users too ... so here we go again.
I also wanted to be able to test library internals at the repl (you
can do this in DrScheme by the way). So I came up with this:
(library (in-library)
(export in-library)
(import (ikarus)
(xitomatl match))
(define (in-library l)
(let ((filename (find-library-by-name l)))
(if filename
(match (with-input-from-file filename read)
(('library libname
('export export-spec ...)
('import import-spec ...)
body ...)
(let* ((env (new-interaction-environment))
(eval (lambda (x) (eval x env))))
(eval `(define library-name ',libname))
(eval `(define library-exports ',export-spec))
(eval `(define library-imports ',import-spec))
(eval `(import ,@import-spec))
(for-each eval body)
(new-cafe eval)))
(_ (error 'in-library "not a r6rs library" l)))
(error 'in-library "library file not found" l))))
(define (find-library-by-name lib)
(define (make-filename lib)
(assert (and (list? lib) (not (null? lib))))
(cond
((null? (cdr lib))
(symbol->string (car lib)))
((list? (cadr lib))
(symbol->string (car lib)))
(else
(string-append (symbol->string (car lib)) "/" (make-filename
(cdr lib))))))
(let ((filename (make-filename lib)))
(let pathloop ((paths (library-path)))
(if (null? paths)
#f
(let ((path (car paths)))
(let extloop ((exts (library-extensions)))
(if (null? exts)
(pathloop (cdr paths))
(let ((fullpath (string-append path "/" filename
(car exts))))
(if (file-exists? fullpath)
fullpath
(extloop (cdr exts))))))))))))
It does the following:
1. resolve a library name to a full path (Hopefully identically to
ikarus's internal find-library-by-name)
2. read the first form of from the file and destructure it into
library name, exports, imports, body forms
3. create a new interaction-environment and bind the name, exports,
imports to variables, import the libraries imports into the new
environment, evaluate all body forms in the new environment
4. create a "sub-repl" with the new environment
Usage:
juer...@nix:~$ rlwrap ikarus
Ikarus Scheme version 0.0.4-rc1+, 64-bit (revision 1854, build
2009-09-08)
Copyright (c) 2006-2009 Abdulaziz Ghuloum
> (import (in-library))
;;; switch to sub-repl:
> (in-library '(in-library))
;;; ask library name
>> library-name
(in-library)
;;; ask library exports
>> library-exports
(in-library)
;;; ask library imports
>> library-imports
((ikarus) (xitomatl match))
;;; use library private function
>> (find-library-by-name '(xitomatl match))
"/home/juergen/Scheme/collects/xitomatl/match.sls"
;;; exit sub-repl by pressing Control-D
;;; try to evaluate the private function on the standard repl:
> find-library-by-name
Unhandled exception
Condition components:
1. &undefined
2. &who: eval
3. &message: "unbound variable"
4. &irritants: (find-library-by-name)
You can't save anything, but I think it's ok for simple testing of
library internals.
And finally a BIG THANK YOU to Abdulaziz for ikarus, your work is
outstanding and much appreciated!
Greetings, Juergen
P.S. This message might be doubled, because the first one was replied
by the mailler daemon with something like "waiting for approval ... "
so just ignore one, or both ;-)