Ограничение области действия переменной - PullRequest
11 голосов
/ 19 июля 2010

Я пытаюсь написать функцию, которая ограничивает область видимости переменных R.Например,

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

Я думал о тестировании переменной среды, но не совсем знал, как это сделать.

Почему

Я преподаю R старшекурсникам.В своей первой паре практических рекомендаций некоторые из них всегда забывают о переменной области видимости, поэтому представленные ими функции не работают.Например, я всегда получаю что-то вроде:

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

Мне нужна была быстрая функция, которая бы «отключала» прицел.Как вы можете себе представить, он не должен быть особенно надежным, поскольку он будет предложен только для нескольких практиков.

Ответы [ 4 ]

4 голосов
/ 19 июля 2010

Я не уверен, что вы хотите сделать это в целом, но функция local() должна помочь, как и библиотека codetools.

В вашем примере попробуйте

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

Он не делает именно то, что вы хотите, но он должен приблизить вас.

3 голосов
/ 19 июля 2010

Вы можете заставить переменную быть локальной версией с помощью этой функции:

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

Сравните эти случаи

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

В зависимости от того, что вы делаете, вы также можете проверить, является ли y аргументом для f, используя formalArgs или 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")
#
#$...

РЕДАКТИРОВАТЬ: более общий вопрос о том, «как отключить лексическую область видимости без изменения содержимого функций», решить сложнее. Я совершенно уверен, что правила области видимости довольно укоренились в R. Альтернативой может быть использование S-Plus, так как он имеет различные правила области видимости .

1 голос
/ 19 июля 2010

Вы можете проверить, существует ли y в глобальной среде, используя exists('y',envir=.GlobalEnv)

0 голосов
/ 21 июля 2010

Иногда со мной случается то, что у меня есть разделенный экран в ESS с файловым буфером кода R слева и интерпретатором справа.Возможно, я установил некоторые значения в интерпретаторе, пока я отлаживаю код, над которым я работаю, в буфере.Тогда возможно, что код в буфере случайно ссылается на то, что я установил в интерпретаторе.Трудно обнаружить проблему, если я не оцениваю свой буфер в новом интерпретаторе каждый раз, а ESS по умолчанию не работает.

Если это проблема, с которой вы часто сталкиваетесь, rm (list = ls (envir = .GlobalEnv)) в том, что вы делаете, может помочь, но это, конечно, создает другие проблемы, такие как удалениевсе, что они использовали для сохранения состояния при отладке и т. д.

...