[Rd] package.skeleton.S4
John Chambers
jmc at r-project.org
Mon Mar 31 19:04:12 CEST 2008
Christophe,
Thanks for your work; unfortunately, at the same time you were
developing your version, the original function was being extended in the
same direction.
The version of package.skeleton() to be included in the 2.7.0 release of
R will deal with S4 classes and methods.
When you have a chance, it would be helpful if you would try out this
version, and let us know whether it deals with your examples.
Version 2.7 of R is currently in alpha testing, meaning that you would
have to compile R from source, so you might prefer to wait. See the
pointer from the main R web page. The projected release date for 2.7.0
is April 22.
John
Christophe Genolini wrote:
> Hi the devel list.
>
> I am adapting the package.skeleton to S4 classes and methods
> I would have been very proud to post a new working function on this list.
> Unfortunately, I do not manage to solve all the problems. Mainly
>
> - sys.source does not compile a file with setClass
> - dumpMethod does not exists yet
>
> In the following code, thise two problems are notified by a line
> #################
>
> Still with this two issues, it is possible to use package.skeleton.S4 in
> the following way:
> - first run package.skeleton (in the classical way, on a file or in the
> console).
> This creates the directories and the files
> - then run package.skeleton.S4.
> It has to be done
> * using the code_files option (since dumpMethod does not exists)
> * providing the list of the class (since sys.source does not
> compile setClass)
> * using the same path than package.skeleton
>
> At this three conditions, package.skeleton.S4 will :
> - modify the DESCRIPTION package,
> - run promptClass on the classes gived in the list,
> - run promptMethod on all the methods related to the classes gives in
> the list.
>
> I tryed to solve the sys.source problem, but I am not good enough in R
> to do it myself.
> I do not even know if it is something hard to do or very easy. So I post
> this uncompleted function...
> If someone is interested in fixing it and then adding it somewhere,
> I then will write the package.skeleton.S4.Rd
>
> sincerly
>
> Christophe
>
>
> --- 8< ----------------- package.skeleton.S4 ---------------------------
>
> package.skeleton.S4 <- function(name = "anRpackage", list, environment =
> .GlobalEnv,
> path = ".", force = FALSE, namespace = FALSE, code_files =
> character(),S4=FALSE)
> {
> cat(missing(list)," EEE\n")
> ### If pakage.skeleton has not been run, run it on false data
> dir <- file.path(path, name)
> code_dir <- file.path(dir, "R")
> docs_dir <- file.path(dir, "man")
> data_dir <- file.path(dir, "data")
> if (!file.exists(dir)){
> environment <- new.env()
> assign("falseData-ToErase",NULL,environment)
>
> package.skeleton(name=name,environment=environment,path=path,namespace=namespace)
> }else{}
>
> ### Build up the list_S4
> ### If list_S4 is empty :
> ### If code_files_S4 is not empty, the file in code_file_S4 are
> source.
> ### then list receive ls() after removing ".__C__" (either if
> code_files is empty or not)
> if (!is.character(code_files)){stop("'code_files S4' should be a
> character vector")}else{}
> use_code_files <- length(code_files) > 0
>
> if (missing(list)){
> ################################################################################
> # Has to be false
> # since sys.source does not work :-(
> if (use_code_files){
> environment <- new.env()
> for (cf in code_files){sys.source(cf, envir = environment)}
> }else{}
> list <- ls(pattern=".__C__",all.names=TRUE)
> list <- substr(list,7,nchar(list))
> }else{}
>
> ### Check that the parameters are of correct type
> if (!is.character(list)){stop("'list' should be a character vector
> naming R objects")}else{}
> if (!is.logical(namespace) || (length(namespace) !=
> 1)){stop("'namespace' should be a single logical")}else{}
> curLocale <- Sys.getlocale("LC_CTYPE")
> on.exit(Sys.setlocale("LC_CTYPE", curLocale), add = TRUE)
> if (Sys.setlocale("LC_CTYPE", "C") != "C"){warning("cannot turn off
> locale-specific chars via LC_CTYPE")}else{}
>
> ### Remove non existing object from the list
> have <- sapply(list, isClass, where = environment)
> if (any(!have))
> warning(sprintf(ngettext(sum(!have), "class '%s' not found",
> "class '%s' not found"), paste(sQuote(list[!have]),
> collapse = ", ")), domain = NA)
> list <- list[have]
> if (!length(list))
> stop("no R classes specified or available")
>
> ### Addition to DESCRIPTION
> message("Adding to DESCRIPTION ...")
> description <- file(file.path(dir, "DESCRIPTION"), "a+b")
> cat("\nDepends: methods\nLazyLoad: yes\nCollate: gives the order in
> which file shall be sourced\n",append=TRUE,file = description,sep = "")
> close(description)
>
> ### Remove elements starting with "." from the list
> internalObjInds <- grep("^\\.", list)
> internalObjs <- list[internalObjInds]
> if (any(internalObjInds)){list <- list[-internalObjInds]}else{}
>
> ### Remplace strange char by "_" and check the name validity (but
> only if code_file is user define)
> if (!use_code_files){
> list0 <- gsub("[[:cntrl:]\"*/:<>?\\|]", "_", list)
> wrong <-
> grep("^(con|prn|aux|clock\\$|nul|lpt[1-3]|com[1-4])(\\..*|)$",list0)
> if (length(wrong)){list0[wrong] <- paste("zz", list0[wrong], sep
> = "")}else{}
> ok <- grep("^[[:alnum:]]", list0)
> if (length(ok) < length(list0)){list0[-ok] <- paste("z",
> list0[-ok], sep = "")}else{}
> list1 <- tolower(list0)
> list2 <- make.unique(list1, sep = "_")
> changed <- (list2 != list1)
> list0[changed] <- list2[changed]
> }else{
> list0 <- list
> }
> names(list0) <- list
>
> ### If code_file is empty, it save all invisible in pack-internal.R
> and all the function one by one in its file
> ### If code_file is not empty, is save the code_file
> if (!use_code_files){
> message("Saving functions and data ...")
> warning("*** Does not work: dumpClass and dumpMethod are not
> implemented yet ***")
> warning("*** Use code_file instead ***")
> ###########################################################################
> # if (any(internalObjInds)){dump(internalObjs, file =
> file.path(code_dir, sprintf("%s-internal.R",name)))}else{}
> # for (item in list) {
> # if (is.function(get(item, envir = environment))){
> # dump(item, file = file.path(code_dir,
> sprintf("%s.R",list0[item])))
> # }else{
> # try(save(list = item, file =
> file.path(data_dir,sprintf("%s.rda", item))))
> # }
> }else{
> message("Copying code files ...")
> file.copy(code_files, code_dir)
> }
>
> ### Help file
> ### For all the internal, a single help file saying "not for user"
> message("Making help files ...")
> if (any(internalObjInds)) {
> Rdfile <- file(file.path(docs_dir,
> sprintf("%s-internal-S4.Rd",name)), "wt")
> cat("\\name{", name, "-internal}\n", "\\title{Internal ",name, "
> objects}\n", file = Rdfile, sep = "")
> for (item in internalObjs) {cat("\\alias{", item, "}\n", file =
> Rdfile, sep = "")}
>
> cat("\\description{Internal ", name, " classes.}\n",
> "\\details{These are not to be called by the user.}\n",
> "\\keyword{internal}", file = Rdfile, sep = "")
> close(Rdfile)
> }
> yy <- try(suppressMessages({
> sapply(list,function(item){
> promptClass(item,filename = file.path(docs_dir,
> sprintf("%s.Rd",list0[item])))
> })
>
> listMethod <- unclass(getGenerics())
> sapply(listMethod,function(metho){
> if(any(sapply(list,function(lis){existsMethod(metho,lis)}))){
> promptMethods(metho,filename = file.path(docs_dir,
> sprintf("%s.Rd",metho)))
> }else{}
> return(invisible())
> })
>
>
> }))
>
> if (inherits(yy, "try-error")){stop(yy)}else{}
> if (length(list.files(code_dir)) == 0){unlink(code_dir, recursive =
> TRUE)}else{}
> if (length(list.files(data_dir)) == 0){unlink(data_dir, recursive =
> TRUE)}else{}
> message("Done.")
> message(gettextf("Further steps are described in
> '%s'.",file.path(dir, "Read-and-delete-me")), domain = NA)
> }
>
>
> # Example
> # Save in myPack.r
> ---- 8< ---------------File myPack.r -----------------
>
> `f1` <- function(x){cat("\nXXX F1 = ",x,"XXX\n")}
> `.f2` <- function(x){cat("\nXXX F2 = ",f1(x^2),"XXX\n")}
>
>
> # Save in myPackS4.r
> ---- 8< ---------------File myPackS4.r ---------------
>
> setClass("AA",representation(a="numeric"))
> setGeneric("aze",function(z){standardGeneric("aze")})
> setMethod("print","AA",function(x){cat("C'est cool")})
> setMethod("aze","AA",function(z){cat("C'est hyper cool")})
>
>
>
> setClass("BB",representation(b="numeric"),validity=function(object){object at b>0})
> setMethod("plot","BB",function(x,y){cat("CCC'est cool")})
> setMethod("aze","BB",function(z){cat("CCC'est hyper cool")})
>
> ---- 8< -----------------------------------------------
>
>
> # Example of use :
>
> package.skeleton("pack",code_files="pack.r")
> package.skeleton.S4("pack",list=c("AA","BB"),code_files="packS4.r")
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
More information about the R-devel
mailing list