Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limiting variable scope

Tags:

scope

r

I'm trying to write a function, which limits the scope of R variables. For example,

source("LimitScope.R")
y = 0
f = function(){
   #Raises an error as y is a global variable
   x = y
}

I thought of testing the variable environment, but wasn't really sure of how to do this.

The why

I teach R to undergrads. In their first couple of practicals a few of them always forget about variable scope, so their submitted functions don't work. For example, I always get something like:

n = 10
f = function(x){
  #Raises an error
  #as I just source f and test it for a few test cases.
  return(x*n)
}

I was after a quick function that would 'turn off' scope. As you can imagine it doesn't have to be particularly robust, as it would just be offered for the few practicals.

like image 658
csgillespie Avatar asked Jul 18 '10 22:07

csgillespie


People also ask

What are the three types of variable scope?

PHP has three different variable scopes: local. global. static.

What type of variable is limited to the scope of a given method?

Local variables are a variable, which has a scope limited to a boundary within which it is declared.

What are the four types of variable scopes?

You will learn about the four different scopes with the help of examples: local, enclosing, global, and built-in. These scopes together form the basis for the LEGB rule used by the Python interpreter when working with variables.

What are the scopes of variables?

In simple terms, scope of a variable is its lifetime in the program. This means that the scope of a variable is the block of code in the entire program where the variable is declared, used, and can be modified.


2 Answers

I'm not sure that you want to do this in general, but the local() function should help, as should the codetools library.

In your example, try

f = local( function() { ... }, baseenv())

It does not do exactly what you want, but it should get you closer.

like image 105
deinst Avatar answered Sep 16 '22 12:09

deinst


You can force a variable to be the local version with this function:

get_local <- function(variable)
{
  get(variable, envir = parent.frame(), inherits = FALSE)  
}

Compare these cases

y <- 0    
f <- function()
{
  x <- y
}    
print(f())        # 0

y <- 0    
f <- function()
{
  y <- get_local("y")
  x <- y
}    
print(f())        # Error: 'y' not found

Depending on what you are doing, you may also want to check to see if y was an argument to f, using formalArgs or formals.

g  <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0

formalArgs(g)
# [1] "x"   "y"   "z"   "..."

formals(g)
#$x
#
#
#$y
#[1] TRUE
#
#$z
#c("foo", "bar")
#
#$...

EDIT: The more general point of 'how to turn off lexical scoping without changing the contents of functions' is harder to solve. I'm fairly certain that the scoping rules are pretty ingrained into R. An alternative might be to use S-Plus, since it has different scoping rules.

like image 22
Richie Cotton Avatar answered Sep 18 '22 12:09

Richie Cotton