[Rd] SaveImage, LazyLoad, S4 and all that {was "install.R ... files"}

Seth Falcon sfalcon at fhcrc.org
Fri Feb 3 17:42:44 CET 2006

On  3 Feb 2006, ripley at stats.ox.ac.uk wrote:
> The short answer is that there are no known (i.e. documented)
> differences, and no examples on CRAN which do not work with
> lazy-loading (except party, which loads the saved image in a test).
> And that includes examples of packages which share S4 classes.  But
> my question was to tease things like this out.

The issue I was seeing with the graph packge is caused by the Ruuid
package creating class instances at the C level using MAKE_CLASS.
MAKE_CLASS doesn't know about namespaces and if it gets called when a
package is loaded via an import, the class def will not be found.

With SaveImage *and* listing Ruuid in Depends, the Ruuid package ends
up in the right place for the class def to be found.  If one uses
LazyLoad, the Ruuid package does not end up in the same place.
Similarly, if one only specifies Ruuid in Imports, then both SaveImage
and LazyLoad fail.

I did a quick test of adding R_do_MAKE_CLASS_NS (see below) to allow
one to get class definitions from a specified namespace.  This seems
to work: I can use LazyLoad on a package (graph) that imports a
package that creates class instances in C code (Ruuid).

/* in src/main/objects.c */
SEXP R_do_MAKE_CLASS_NS(char *what, char *where)
    static SEXP s_getClass = NULL;
    SEXP val, call, namespace, force;
	error(_("C level MAKE_CLASS macro called with NULL string pointer"));
	s_getClass = Rf_install("getClass");
    PROTECT(force = allocVector(LGLSXP, 1));
    LOGICAL(force)[0] = 0;
    PROTECT(namespace = R_FindNamespace(mkString(where)));
    PROTECT(call = allocVector(LANGSXP, 4));
    SETCAR(call, s_getClass);
    val = CDR(call);
    SETCAR(val, mkString(what));
    val = CDR(val);
    SETCAR(val, force);
    val = CDR(val);
    SETCAR(val, namespace);
    val = eval(call, R_GlobalEnv);

+ seth

More information about the R-devel mailing list