Skip to content

Instantly share code, notes, and snippets.

@wch
Created August 7, 2012 01:17
Show Gist options
  • Save wch/3280369 to your computer and use it in GitHub Desktop.
Save wch/3280369 to your computer and use it in GitHub Desktop.
Sample code for unlocking environments in R
library(inline)
inc <- '
/* This is taken from envir.c in the R source */
#define FRAME_LOCK_MASK (1<<14)
#define FRAME_IS_LOCKED(e) (ENVFLAGS(e) & FRAME_LOCK_MASK)
#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~ FRAME_LOCK_MASK))
'
src <- '
if (TYPEOF(env) == NILSXP)
error("use of NULL environment is defunct");
if (TYPEOF(env) != ENVSXP)
error("not an environment");
UNLOCK_FRAME(env);
// Return TRUE if unlocked; FALSE otherwise
SEXP result = PROTECT( Rf_allocVector(LGLSXP, 1) );
LOGICAL(result)[0] = FRAME_IS_LOCKED(env) == 0;
UNPROTECT(1);
return result;
'
unlockEnvironment <- cfunction(signature(env = "environment"),
includes = inc,
body = src)
unlockEnvironment(new.env()) # TRUE
unlockEnvironment('foo') # error
# Wrapper function should return(invisible(TRUE)) if successful, error otherwise.
# Wrapper function should also check type
# ============== test unlocking bindings
e <- new.env()
e$x <- 5
e$x # 5
lockEnvironment(e, bindings = TRUE)
e$x <- 6 # ERROR
environmentIsLocked(e) # TRUE
e$y <- 6 # ERROR
bindingIsLocked('x', e) # TRUE
unlockBinding('x', e)
bindingIsLocked('x', e) # FALSE
e$x <- 7 # OK
# Re-lock environment and bindings
lockEnvironment(e, bindings = TRUE)
e$y <- 6 # ERROR
# Run our custom function
unlockEnvironment(e) # TRUE
environmentIsLocked(e) # FALSE
e$y <- 8 # OK
bindingIsLocked('x', e) # TRUE
e$x <- 7 # ERROR
unlockBinding(ls(e, all.names=TRUE), e)
e$x <- 7 # OK
bindingIsLocked('x', e) # FALSE
bindingIsLocked('y', e) # FALSE
e$y <- 8
e$z <- 9
@jangorecki
Copy link

Soon it will be is 3 years since that gist, maybe there is some better way? without inline dependency?

@SymbolixAU
Copy link

This SO answer looks like an alternative?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment