Ограничение переменного объема

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

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

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

Почему

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

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

Я был после быстрой функции, которая 'выключит' объем. Поскольку можно предположить, что это не должно быть особенно устойчиво, как это было бы просто предложено для нескольких practicals.

11
задан csgillespie 19 July 2010 в 14:10
поделиться

4 ответа

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

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

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

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

4
ответ дан 3 December 2019 в 10:43
поделиться

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

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")
#
#$...

EDIT: Более общий вопрос "как отключить лексический скопинг без изменения содержимого функций" решить сложнее. Я уверен, что правила скопирования довольно прочно укоренились в R. Альтернативой может быть использование S-Plus, поскольку в нем другие правила скопирования.

3
ответ дан 3 December 2019 в 10:43
поделиться

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

1
ответ дан 3 December 2019 в 10:43
поделиться

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

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

0
ответ дан 3 December 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: