Next: Sorting and merging, Previous: Input and Output, Up: Core library [Contents][Index]
• Loading Scheme file: | ||
• Loading dynamic library: | ||
• Require and provide: | ||
• Autoload: | ||
• Operations on libraries: |
Next: Load dynamic library, Previous: Loading Programs, Up: Loading Programs [Contents][Index]
[R7RS+ load]
Loads file, that is, read Scheme expressions in file and
evaluates them.
An extension “.scm
” may be omitted from file.
If file doesn’t begin with “/” or “./” or “../”,
it is searched from the system file search list,
stored in a variable *load-path*
.
Or you can explicitly specify the search path by passing
a list of directory names to the keyword argument paths.
On success, load
returns the string pathname of the file
actually loaded.
If the specified file is not found, an error is signaled unless
the keyword argument error-if-not-found is #f
, in
which case load
returns #f
.
By default, load
uses a coding-aware port
(see Coding-aware ports) so that the "coding:
" magic
comment at the beginning of the source file is effective.
(See Multibyte scripts, for the details of
the coding magic comment). If a true value is given to the
keyword argument ignore-coding, load
doesn’t
create the coding-aware port and directly reads from the
file port.
If a module is given to the keyword argument environment,
load
works as if the given module is selected at the beginning
of the loaded file.
The current module is preserved; even select-module
is
called in file, the module in which load
is called
is restored afterwards.
Gauche’s load
is upper-compatible to R5RS load
, but
R7RS load
differs in optional arguments; see scheme.load
- R7RS load.
If you want to load a library file, it’s better to use ‘use
’
(see Defining and selecting modules), or ‘require
’ described below.
See Compilation, for difference between load
and require
.
Keeps a list of directories that are searched by load
and
require
.
If you want to add other directories to the search path,
do not modify this variable directly; use add-load-path
,
described below, instead.
Adds a path path to the library load path list.
Path must be a literal string, for load paths must be
known at compilation time.
If path is a relative path, it is resolved relative to
the current working directory, unless :relative
flag is given.
Path doesn’t need to exist; nonexisting paths in load path list
are simply ignored. However, if path does exist, add-load-path
searches for architecture-dependent paths; see below.
Each flag argument may be one of the followings.
:after
Append path to the end of the current list of load paths. By default, path is added in front of the load path list.
#t
The same as :after
. This is for the backward compatibility.
:relative
Interpret path as a relative path to the directory of the current file, instead of the current working directory. If the current file can’t be determined (e.g. evaluated in REPL, or the expression is read from a socket), this flag is ignored.
Use this form instead of changing *load-path*
directly.
This form is a special form and recognized by the compiler;
if you change *load-path*
, it is in effect at run time,
and that may be too late for “use” or “require”.
Furthermore,
add-load-path
looks for the architecture dependent directories
under the specified path and if it exists, sets up the internal
path list for dynamic loading correctly. Suppose you have
your Scheme module in /home/yours/lib
, and that requires
a dynamic loadable library. You can put the library under
/home/yours/lib/ARCH/
, where ARCH is
the value (gauche-architecture)
returns (see Environment inquiry).
Then you can have compiled libraries for multiple platforms and
Gauche can still find the right library.
Reads Scheme expressions from an input port port and evaluates them, until EOF is read.
Note that unless you pass a coding-aware port to port,
the "coding:
" magic comment won’t be handled.
These procedures allows you to query the current context of loading. They returns the following values when called inside a file being loaded:
current-load-port
Returns the port object from which this form is being loaded.
current-load-path
Returns the pathname of the file from which this form is being loaded.
Note that this may return #f
if the source of load
is
not a file.
current-load-history
Returns a list of pairs of a port and a line number (integer),
representing the nesting of loads. Suppose you load
foo.scm, and from its line 7 it loads bar.scm,
and from its line 18 it loads baz.scm. If you call
current-load-history
in the file baz.scm, you’ll get
((#<port "foo.scm"> . 7) (#<port "bar.scm"> . 18))
current-load-next
Returns a list of remaining directories to be searched
at the time this file is found. Suppose the *load-path*
is ("." "../lib" "/home/gauche/lib" "/share/gauche/lib")
and you load foo.scm, which happens to be in ../lib/.
Then, inside foo.scm, current-load-next
returns:
("/home/gauche/lib" "/share/gauche/lib")
When called outside of load
, these procedures returns
#f
, #f
, ()
and ()
, respectively.
Next: Require and provide, Previous: Loading Scheme file, Up: Loading Programs [Contents][Index]
Loads and links a dynamic loadable library (shared library) file.
File shouldn’t contain the suffix (“.so” on most systems);
dynamic-load
adds it, for it may differ among platforms.
The keyword argument init-function specifies the initialization function name of the library in a string. By default, if the file basename (without extension) is “foo”, the initialization function name is “Scm_Init_foo”.
Usually a dynamic loadable library is provided with wrapping Scheme module, so the user doesn’t have to call this function directly.
There’s no way to unload the loaded libraries.
Next: Autoload, Previous: Load dynamic library, Up: Loading Programs [Contents][Index]
Require
and provide
are a traditional Lisp way to ensure
loading a library file only once. If you require a feature
for the first time, a library file that provides it is loaded
and the fact that the feature is provided is memorized.
Subsequent request of the same feature doesn’t need to load the file.
In Gauche, the use
syntax (see Using modules) hides
the require mechanism under the hood so you hardly need to see
these forms. These are provided just in case if you want to
do some non-trivial management of libraries and thus want to
bypass Gauche’s standard mechanism.
If feature is not loaded, load it. Feature must be a string, and it is taken as a file name (without suffix) to be loaded. This loading takes place at compile time.
If you load SLIB module, require
is extended. see slib
- SLIB interface for
details.
If the loaded file does not contain provide
form at all,
the feature is automatically provided, as if
(provide feature)
is called at the end of the loaded
file. We call this autoprovide feature.
Note that require
first sets the current module to
an immutable module called gauche.require-base
and then load the file. The files
loaded by require
usually have define-module
/select-module
or define-library
for the first thing, so you rarely notice the
gauche.require-base
module. However, if the loaded file
has toplevel defines or imports (use
’s) without specifying
a module, you’ll get an error like the following:
*** ERROR: Attempted to create a binding (a) in a sealed module: #<module gauche.require-base>
Rationale: Generally it’s difficult to guarantee
when the specified file is loaded by require
(because some other
module may already have required it). If we just used the caller’s current
module, there would be a couple of issues: The form define-module
or
define-library
may not be visible from the current module, and
you can’t guarantee if the toplevel defines without specifying modules
in the loaded file inserts the caller’s current module, since they may
have been loaded into a different module.
It is just a bad idea to insert
toplevel definitions or to import other modules without specifying which
module you put them in. So we made them an error.
Adds feature to the system’s provided feature list, so that
the subsequent require
won’t load the same file again.
Because of the autoproviding, i.e. require
automatically provides the required feature, you hardly need to
use a provide
form explicitly. There are a couple of scenarios that
you may want to use a provide
form:
Suppose feature X supersedes feature Y and providing
compatible APIs of Y but with different implementation.
Once X.scm is loaded, you don’t want Y.scm to be loaded;
so you want to tell the user that X.scm also provides the feature Y.
Adding (provide "X")
and (provide "Y")
at the end of
X.scm accomplish that. (Note: If you add a provide form,
require
no longer autoprovides the feature, so you need
to specify (provide "X")
in X.scm explicitly to
provide X as well.)
Of course, this doesn’t prevent users from loading Y.scm by
specifying (require "Y")
before (require "X")
.
It should be considered just as a workaround in a production
where other solutions are costly, instead of a permanent solution.
#f
as feature
prevents autoproviding by require
without providing any
feature.
This should also be a temporary solution. One possible scenario is
that you are changing X.scm very frequently during
development and you want (require "X")
always causes loading
the file. Don’t forget to remove (provide #f)
when you release
the file, though. Besides, for interactive reloading, consider
using gauche.reload
(see gauche.reload
- Reloading modules) instead.
Returns #t
if feature is already provided.
Next: Operations on libraries, Previous: Require and provide, Up: Loading Programs [Contents][Index]
Sets up item … to be autoloaded. That is, when an item is referenced for the first time, file/module is loaded before the item is evaluated. This delays the loading of file/module until it is needed.
You can specify either a string file name or a symbol module name
to file/module. If it is a string, the named file is
loaded. If it is a symbol, the named module is loaded (using the
same rule as of use
), then the binding of item in the
file/module is imported to the module used the autoload
(See Defining and selecting modules, for details of use
).
Item can be either a variable name (symbol),
or a form (:macro symbol)
. If it is a variable,
the named file/module is loaded when the variable is
about to be evaluated. If it is the latter form,
the named file/module is loaded when a form
(symbol arg …)
is about to be compiled,
which enables autoloading macros.
file/module must define symbol in it, or an error is signaled when file/module is autoloaded.
The following is an example of autoloading procedures.
(autoload "foo" foo0 foo1) (autoload "bar" bar0 bar1) (define (foobar x) (if (list? x) (map bar0 x) (foo0))) (foobar '(1 2)) ; "bar" is loaded at this moment (foobar #f) ; "foo" is loaded at this moment
Note that if you set to autoload macro, the file/module is loaded immediately when such form that uses the macro is compiled, regardless of the piece of the code is executed or not.
Previous: Autoload, Up: Loading Programs [Contents][Index]
There are several procedures you can use to check if certain libraries and/or modules are installed in the system.
In the following descriptions, pattern is either a
symbol or a string. If it is a symbol, it specifies
a module name (e.g. foo.bar
). If it is
a string, it specifies a partial pathname of the library
(e.g. "foo/bar"
), which will be searched under
library search paths.
You can also use glob-like metacharacters *
and
?
in pattern.
A basic iterator for library/module files.
This procedure searches Scheme program files which matches
pattern, under directories listed in paths
(the default is the standard file load paths, *load-path*
).
For each matched file, it calls proc with three arguments:
the matched module or library name, the full path of the program
file, and the state value. Seed is used as the initial
state value, and the value proc returns is used as the state
value for the next call of proc. The value returned from
the last proc becomes the return value of library-fold
.
If pattern is a symbol and the keyword argument strict?
is #t
(which is the default), this procedure calls
library-has-module?
on the files whose name seems to
match the given pattern of module name, in order to find out
the file really implements the module. It can be a time consuming
process if you try to match large number of modules; you can pass
#f
to strict? to avoid the extra check.
If pattern is a string, matching is done only for file names
so strict? is ignored.
By default, if there are more than one files that have the same name
that matches pattern in paths, only the first
one appears in paths is taken. This gives you
the file you’ll get if you use require
or use
for that library. If you want to iterate all of matching files,
pass #t
to the allow-duplicates? keyword argument.
Here are some examples (the result may differ in your environment).
(library-fold 'srfi.1 acons '())
⇒ ((srfi.1 . "../lib/srfi/1.scm"))
(library-fold "srfi.1" acons '())
⇒ (("srfi.1" . "../lib/srfi/1.scm"))
;; Note the returned list is in a reverse order of
;; how acons
is called.
(library-fold 'srfi.1 acons '() :allow-duplicates? #t)
⇒ ((srfi.1 . "/usr/share/gauche-0.98/0.9.13/lib/srfi/1.scm")
(srfi.1 . "../lib/srfi.1.scm"))
;; Finds available dbm implementations
(library-fold 'dbm.* acons '())
⇒ ((dbm.cdb . "/usr/share/gauche-0.98/0.9.13/lib/dbm/cdb.scm")
(dbm.gdbm . "../lib/dbm/gdbm.scm")
(dbm.ndbm . "../lib/dbm/ndbm.scm")
(dbm.odbm . "../lib/dbm/odbm.scm"))
Map
and for-each
version of iterator over matched
libraries/modules. See library-fold
above for detailed
operation of matching and the meanings of keyword arguments.
Proc receives two arguments, the matched module/library name
and full path of the file. Library-map
returns a list
of results of proc. Library-for-each
discards
the results.
(library-map 'srfi.4 list :allow-duplicates? #t) ⇒ ((srfi.4 "../lib/srfi/4.scm") (srfi.4 "/usr/share/gauche-0.98/0.9.13/lib/srfi/4.scm")) (library-map 'dbm.* (lambda (m p) m)) ⇒ (dbm.odbm dbm.ndbm dbm.gdbm dbm.cdb)
Search a library or a module specified by mod/path,
and returns a true value if it finds one. Paths and strict?
keyword arguments have the same meaning as library-fold
.
Unlike the iterator procedures above, this procedure first
checks loaded libraries and modules in the calling process,
and returns true if it finds mod/path in it,
without looking into the filesystem. Passing #t
to
force-search? keyword arguments skips the checking of
loaded libraries and modules.
Returns #t
iff a file specified by path exists and
appears to implement a module named by module
. path must be
an actual filename.
(library-has-module? "./test/foo/bar.scm" 'foo.bar)
⇒ #t ;; if ./test/foo/bar.scm implements module foo.bar.
This procedure assumes a typical layout of the source code
to determine if the given file implements the module, i.e.,
it reads the first form of the code and see if it is a
define-module
form that is defining the given module.
Next: Sorting and merging, Previous: Input and Output, Up: Core library [Contents][Index]