Whit Armstrong
2009-Mar-31 15:45 UTC
[Rd] what is the preferred method to create a package local variable?
for the moment, I'm using: .onAttach <- function(libname, pkgname) { .bbg.db.conn <<- dbConnect(dbDriver("PostgreSQL"), user="blah","blah") } .onUnload <- function(libpath) { dbDisconnect(.bbg.db.conn) } which results in a hidden global variable in the global environment. I would prefer to make the assignment only in the package namespace. I've looked at assignInNamespace, but I can't seem to make it work. Is there a preferred method for doing this? When I try adding an assignment directly in the source file, I get the "cannot change value of locked binding" error. What am I missing? Thanks, Whit
Martin Morgan
2009-Mar-31 16:41 UTC
[Rd] what is the preferred method to create a package local variable?
Hi Whit -- Whit Armstrong <armstrong.whit at gmail.com> writes:> for the moment, I'm using: > > .onAttach <- function(libname, pkgname) { > .bbg.db.conn <<- dbConnect(dbDriver("PostgreSQL"), user="blah","blah") > } > > .onUnload <- function(libpath) { > dbDisconnect(.bbg.db.conn) > } > > > which results in a hidden global variable in the global environment. > > I would prefer to make the assignment only in the package namespace. > I've looked at assignInNamespace, but I can't seem to make it work. > > Is there a preferred method for doing this?I don't konw about preferred, but one method is pkgVars <- local({ x <- NULL list(getX=function() x, setX=function(value) x <<- value) }) with use> pkgVars$getX()NULL> pkgVars$setX(123) > pkgVars$getX()[1] 123 This introduces a different programming paradigm (a list of functions) that might not be familiar for end-users and is not readily amenable to documentation. A probably better way is pkgVars <- new.env(parent=emptyenv()) getX <- function() get("x", pkgVars, inherits=FALSE) setX <- function(value) assign("x", value, envir=pkgVars)> getX()Error in get("x", pkgVars, inherits = FALSE) : object 'x' not found> setX(123) > getX()[1] 123 A tidier response to the first getX() could be arranged with something like pkgVars <- local({ env <- new.env(parent=emptyenv()) env[["x"]] <- NULL env }) pkgVars, getX, and setX can be exported from the name space or not. FWIW, usually one wants .onLoad rather than .onAttach, so that a package import-ing your package (not just depend-ing, or when used directly in an interactive session) will execute the setup code. Hope that helps and is not too misleading. Martin> When I try adding an assignment directly in the source file, I get the > "cannot change value of locked binding" error. > > What am I missing? > > Thanks, > Whit > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel-- Martin Morgan Computational Biology / Fred Hutchinson Cancer Research Center 1100 Fairview Ave. N. PO Box 19024 Seattle, WA 98109 Location: Arnold Building M2 B169 Phone: (206) 667-2793
hadley wickham
2009-Mar-31 16:53 UTC
[Rd] what is the preferred method to create a package local variable?
For saving the previous plot in ggplot2, I use the following: .plot_store <- function() { .last_plot <- NULL list( get = function() .last_plot, set = function(value) .last_plot <<- value ) } .store <- .plot_store() set_last_plot <- function(value) .store$set(value) last_plot <- function() .store$get() which is basically equivalent to Martin's first suggestion, with some wrapper functions. Hadley On Tue, Mar 31, 2009 at 10:45 AM, Whit Armstrong <armstrong.whit at gmail.com> wrote:> for the moment, I'm using: > > .onAttach <- function(libname, pkgname) { > ? ?.bbg.db.conn <<- dbConnect(dbDriver("PostgreSQL"), user="blah","blah") > } > > .onUnload <- function(libpath) { > ? ?dbDisconnect(.bbg.db.conn) > } > > > which results in a hidden global variable in the global environment. > > I would prefer to make the assignment only in the package namespace. > I've looked at assignInNamespace, but I can't seem to make it work. > > Is there a preferred method for doing this? > > When I try adding an assignment directly in the source file, I get the > "cannot change value of locked binding" error. > > What am I missing? > > Thanks, > Whit > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- http://had.co.nz/
Gabor Grothendieck
2009-Mar-31 17:09 UTC
[Rd] what is the preferred method to create a package local variable?
Look at the zzz.R file in the lattice package and the .LatticeEnv variable in particular. Also, when running lattice try this and look for .LatticeEnv in the output: ls(asNamespace("lattice"), all = TRUE) On Tue, Mar 31, 2009 at 11:45 AM, Whit Armstrong <armstrong.whit at gmail.com> wrote:> for the moment, I'm using: > > .onAttach <- function(libname, pkgname) { > ? ?.bbg.db.conn <<- dbConnect(dbDriver("PostgreSQL"), user="blah","blah") > } > > .onUnload <- function(libpath) { > ? ?dbDisconnect(.bbg.db.conn) > } > > > which results in a hidden global variable in the global environment. > > I would prefer to make the assignment only in the package namespace. > I've looked at assignInNamespace, but I can't seem to make it work. > > Is there a preferred method for doing this? > > When I try adding an assignment directly in the source file, I get the > "cannot change value of locked binding" error. > > What am I missing? > > Thanks, > Whit > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Roger Peng
2009-Mar-31 19:35 UTC
[Rd] what is the preferred method to create a package local variable?
I usually use environments for this. So, in one of the R files for the package, just do .localstuff <- new.env() Then, in functions you can do things like .localstuff$bbg.db.conn <- dbConnect(...) -roger On Tue, Mar 31, 2009 at 11:45 AM, Whit Armstrong <armstrong.whit at gmail.com> wrote:> for the moment, I'm using: > > .onAttach <- function(libname, pkgname) { > ? ?.bbg.db.conn <<- dbConnect(dbDriver("PostgreSQL"), user="blah","blah") > } > > .onUnload <- function(libpath) { > ? ?dbDisconnect(.bbg.db.conn) > } > > > which results in a hidden global variable in the global environment. > > I would prefer to make the assignment only in the package namespace. > I've looked at assignInNamespace, but I can't seem to make it work. > > Is there a preferred method for doing this? > > When I try adding an assignment directly in the source file, I get the > "cannot change value of locked binding" error. > > What am I missing? > > Thanks, > Whit > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Roger D. Peng | http://www.biostat.jhsph.edu/~rpeng/