From mtmorgan at fhcrc.org  Tue Mar 31 19:51:08 2009
From: mtmorgan at fhcrc.org (Martin Morgan)
Date: Tue, 31 Mar 2009 10:51:08 -0700
Subject: [Rd] what is the preferred method to create a package local
 variable?
In-Reply-To: <8b356f880903311027o7f550d66n12b8608c605f92dd@mail.gmail.com>
References: <8ec76080903310845x3b0a0c2cy22d30cd0799a206e@mail.gmail.com>	
	<6phocvh7ihu.fsf@gopher4.fhcrc.org>
	<8b356f880903311027o7f550d66n12b8608c605f92dd@mail.gmail.com>
Message-ID: <49D2580C.1070602@fhcrc.org>

Stavros Macrakis wrote:
> On Tue, Mar 31, 2009 at 12:41 PM, Martin Morgan <mtmorgan at fhcrc.org 
> <mailto:mtmorgan at fhcrc.org>> wrote:
> 
>     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()
>     ...
>     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.
> 
> 
> Why "not readily amenable to documentation"?  If the user doesn't need

in the sense that ?pkgVars$getX would not do anything useful (I guess -- 
perhaps if there were an alias, I don't really know) and that R CMD 
check would not detect inconsistencies between 'usage', code, and 
documentation, for instance.

> to understand the structure, he can consider the "$" as simply part of 

but that would be additional syntax for the user to learn, which would 
be counter-productive.

> the function name.  And I wouldn't name it pkgVars but pkg.

In general I would rather expose the interface than the object, which 
lead me to my so-called 'better way'.

>  
> 
>     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)
> 
> 
> I think a simpler, clearer way to make getX etc. globally visible is:
> 
>   local({
>    x <- NULL
>    getX <<- function() x
>    setX  <<- function(value) x <<- value
>  })

By 'globally' you mean in the package name space, I guess (this is 
relying on a fairly nuanced understanding of what the 'top' environment 
is during package building). For me the paradigm of <<- to the top 
environment (or first getX found in the search path) opens the door to 
doing dumb things like overwriting user variables. Maybe a risk you're 
willing to engage within your own name space...

Martin

> 
> To my taste, this is much cleaner than explicitly referencing environments.
> 
>             -s


-- 
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



[Rd] what is the preferred method to create a package local variable?
Martin Morgan