peter-m.schumacher at db.com
2007-Mar-06 20:18 UTC
[Rd] bug: sticky symbol refs? (PR#9555)
Hello. What happens in the following is that I create two simple functions, f and g, on the workspace. Then I replace g. When I then call f, it uses the old version of g. Now clearly, the circumstances for this to happen must be quite special and rare. But I'd say they're not pathological. It seems to require two things: 1) masked versions of f and g on a search position lower down the search list (but I'm not sure that's necessary), and 2) using source() to create the objects, but evaluated in a local environment, not the global one. I'm pretty confident that 2) is necessary for the bug. Practical impact: like I suppose many users, I maintain my own R functions in a .RData file which I've always got attached at pos 2. Periodically I dump() them to file, take that file to another site, and source() them in there. However I don't want all the functions to be created on search pos'n 1, so I have a wrapper my.source() which creates them in a local environment then copies from that down to search pos 2. So that's all fairly innocent, and probably not uncommon. How to reproduce: ########## put this code in /temp/myFuns.R: `f` <- function (x) { g(x) } `g` <- function(x) { is.null(x) } ############ # now create a fresh .RData and attach it at pos 2:> save(list = character(0), file = "/temp/.RData") # to create it > attach( "/temp/.RData", pos=2 )# now source() /temp/myFuns.R in a local env, then copy new objs to search pos 2:> newEnv <- new.env() > eval(expression(source(file = "/temp/myFuns.R", local = T)), envir=newEnv) > for( objName in objects(envir = newEnv, all.names = T) ) {assign(objName, get(objName, envir = newEnv), pos = 2) }> f <- f # copy from pos 2 to workspace; (needed?) > g <- g # copy from pos 2 to workspace; (needed?) > f(1) # gives correct answer[1] FALSE> g <- function(x) stop( "this is the new g" ) > f(1) # gives wrong answer; uses the old g();[1] FALSE # now re-create f from scratch, assign under new name:> f2 <- eval( parse( text=deparse(f) ) ) > f2(1) # gives correct answerError in g(x) : this is the new g # note that the original f() continues to malfunction; --please do not edit the information below-- Version: platform = i386-pc-mingw32 arch = i386 os = mingw32 system = i386, mingw32 status major = 2 minor = 4.1 year = 2006 month = 12 day = 18 svn rev = 40228 language = R version.string = R version 2.4.1 (2006-12-18) Windows XP Professional (build 2600) Service Pack 2.0 Locale: LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United Kingdom.1252;LC_NUMERIC=C;LC_TIME=English_United Kingdom.1252 Search Path: .GlobalEnv, file:/temp/.RData, file:c:/schupl/R/myRLib/.RData, file:c:/schupl/R/myFinanceLib/.RData, file:c:/schupl/R/recycler/.RData, package:stats, package:graphics, package:grDevices, package:utils, package:datasets, package:methods, Autoloads, package:base --- This e-mail may contain confidential and/or privileged infor...{{dropped}}
peter-m.schumacher at db.com wrote:> Hello. What happens in the following is that I create two simple functions, f and g, on the workspace. Then I > replace g. When I then call f, it uses the old version of g. Now clearly, the circumstances for this to happen > must be quite special and rare. But I'd say they're not pathological. It seems to require two things: 1) masked versions > of f and g on a search position lower down the search list (but I'm not sure that's necessary), and 2) using > source() to create the objects, but evaluated in a local environment, not the global one. I'm pretty confident that > 2) is necessary for the bug. > > Practical impact: like I suppose many users, I maintain my own R functions in a .RData file which I've always got > attached at pos 2. Periodically I dump() them to file, take that file to another site, and source() them in there. > However I don't want all the functions to be created on search pos'n 1, so I have a wrapper my.source() which creates > them in a local environment then copies from that down to search pos 2. So that's all fairly innocent, and probably > not uncommon. > > How to reproduce: > > ########## put this code in /temp/myFuns.R: > `f` <- > function (x) > { > g(x) > } > `g` <- > function(x) > { > is.null(x) > } > ############ > > # now create a fresh .RData and attach it at pos 2: > >> save(list = character(0), file = "/temp/.RData") # to create it >> attach( "/temp/.RData", pos=2 ) >> > > # now source() /temp/myFuns.R in a local env, then copy new objs to search pos 2: > >> newEnv <- new.env() >> eval(expression(source(file = "/temp/myFuns.R", local = T)), envir=newEnv) >> for( objName in objects(envir = newEnv, all.names = T) ) { >> > assign(objName, get(objName, envir = newEnv), pos = 2) > } > > >> f <- f # copy from pos 2 to workspace; (needed?) >> g <- g # copy from pos 2 to workspace; (needed?) >> f(1) # gives correct answer >> > [1] FALSE > >> g <- function(x) stop( "this is the new g" ) >> f(1) # gives wrong answer; uses the old g(); >> > [1] FALSE > > # now re-create f from scratch, assign under new name: > >> f2 <- eval( parse( text=deparse(f) ) ) >> f2(1) # gives correct answer >> > Error in g(x) : this is the new g > > # note that the original f() continues to malfunction; >Not a bug, as far as I can see. The environment of f is newEnv, and this is where it goes looking for g copying f to the global environment doesn't change that. That information is part of the function object not a matter of where the object is bound to a variable. Look at environment(f), resp. f2 to see the point.> --please do not edit the information below-- > > Version: > platform = i386-pc-mingw32 > arch = i386 > os = mingw32 > system = i386, mingw32 > status > major = 2 > minor = 4.1 > year = 2006 > month = 12 > day = 18 > svn rev = 40228 > language = R > version.string = R version 2.4.1 (2006-12-18) > > Windows XP Professional (build 2600) Service Pack 2.0 > > Locale: > LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United > > Kingdom.1252;LC_NUMERIC=C;LC_TIME=English_United Kingdom.1252 > > Search Path: > .GlobalEnv, file:/temp/.RData, file:c:/schupl/R/myRLib/.RData, file:c:/schupl/R/myFinanceLib/.RData, file:c:/schupl/R/recycler/.RData, > > package:stats, package:graphics, package:grDevices, package:utils, package:datasets, package:methods, Autoloads, package:base > --- > > This e-mail may contain confidential and/or privileged infor...{{dropped}} > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
Dear Peter, would the problem persist if you maintained your favorite set of R functions in a proper package rather than in some .RData file? Packages offer a lot of goodies such as namespaces, version numbers, man pages. Best wishes Wolfgang ------------------------------------------------------------------ Wolfgang Huber EBI/EMBL Cambridge UK http://www.ebi.ac.uk/huber peter-m.schumacher at db.com wrote:> > Hello. What happens in the following is that I create two simple functions, f and g, on the workspace. Then I > replace g. When I then call f, it uses the old version of g. Now clearly, the circumstances for this to happen > must be quite special and rare. But I'd say they're not pathological. It seems to require two things: 1) masked versions > of f and g on a search position lower down the search list (but I'm not sure that's necessary), and 2) using > source() to create the objects, but evaluated in a local environment, not the global one. I'm pretty confident that > 2) is necessary for the bug. > > Practical impact: like I suppose many users, I maintain my own R functions in a .RData file which I've always got > attached at pos 2. Periodically I dump() them to file, take that file to another site, and source() them in there. > However I don't want all the functions to be created on search pos'n 1, so I have a wrapper my.source() which creates > them in a local environment then copies from that down to search pos 2. So that's all fairly innocent, and probably > not uncommon. > > How to reproduce: > > ########## put this code in /temp/myFuns.R: > `f` <- > function (x) > { > g(x) > } > `g` <- > function(x) > { > is.null(x) > } > ############ > > # now create a fresh .RData and attach it at pos 2: >> save(list = character(0), file = "/temp/.RData") # to create it >> attach( "/temp/.RData", pos=2 ) > > # now source() /temp/myFuns.R in a local env, then copy new objs to search pos 2: >> newEnv <- new.env() >> eval(expression(source(file = "/temp/myFuns.R", local = T)), envir=newEnv) >> for( objName in objects(envir = newEnv, all.names = T) ) { > assign(objName, get(objName, envir = newEnv), pos = 2) > } > >> f <- f # copy from pos 2 to workspace; (needed?) >> g <- g # copy from pos 2 to workspace; (needed?) >> f(1) # gives correct answer > [1] FALSE >> g <- function(x) stop( "this is the new g" ) >> f(1) # gives wrong answer; uses the old g(); > [1] FALSE > > # now re-create f from scratch, assign under new name: >> f2 <- eval( parse( text=deparse(f) ) ) >> f2(1) # gives correct answer > Error in g(x) : this is the new g > > # note that the original f() continues to malfunction; > > --please do not edit the information below-- > > Version: > platform = i386-pc-mingw32 > arch = i386 > os = mingw32 > system = i386, mingw32 > status > major = 2 > minor = 4.1 > year = 2006 > month = 12 > day = 18 > svn rev = 40228 > language = R > version.string = R version 2.4.1 (2006-12-18) > > Windows XP Professional (build 2600) Service Pack 2.0 > > Locale: > LC_COLLATE=English_United Kingdom.1252;LC_CTYPE=English_United Kingdom.1252;LC_MONETARY=English_United > > Kingdom.1252;LC_NUMERIC=C;LC_TIME=English_United Kingdom.1252 > > Search Path: > .GlobalEnv, file:/temp/.RData, file:c:/schupl/R/myRLib/.RData, file:c:/schupl/R/myFinanceLib/.RData, file:c:/schupl/R/recycler/.RData, > > package:stats, package:graphics, package:grDevices, package:utils, package:datasets, package:methods, Autoloads, package:base > --- > > This e-mail may contain confidential and/or privileged infor...{{dropped}} > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel--
Apparently Analagous Threads
- obscure error with subsetting as.list() of a function then assigning that a (PR#9500)
- Functions that write functions in R packages
- how to modify variables of another frame (but not global)
- Enumerate the class of objects
- S4 Reference Classes: undesired behavior when calling method '$field()'