как добавить функции в существующую среду - PullRequest
6 голосов
/ 25 января 2012

Можно ли использовать env() вместо пространств имен, и как проверить, существует ли среда, прежде чем добавлять к ней функции?

Это связано с этим вопросом и предложением Брендана Как организовать большие R-программы? Я понимаю точку зрения Дирка в этом вопросе, однако для разработки иногда нецелесообразно помещать функции в пакеты.

РЕДАКТИРОВАТЬ: Идея состоит в том, чтобы имитировать пространства имен между файлами,и, следовательно, чтобы иметь возможность загружать разные файлы независимо.Если файл был ранее загружен, тогда не нужно создавать среду, просто добавьте в.

Спасибо за идеи

РЕДАКТИРОВАТЬ: Таким образом, предположительно, этот код ниже будет эквивалентен пространствам именна других языках: -

 # how to use environment as namespaces

# file 1

# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) {   e <- new.env(parent=baseenv()) }

e$f1 <- function(x) {1}


# file 2
# equivalent of 'namespace e' if (!(exists("e") && is.environment(e))) {   e <- new.env(parent=baseenv()) }

e$f2 <- function(x) {2}

Ответы [ 3 ]

6 голосов
/ 26 января 2012

Да, вы можете по большей части.У каждой функции есть среда, в которой она ищет другие функции и глобальные переменные.Используя свою собственную среду, вы получаете полный контроль над этим.

Обычно функции также присваиваются среде (присваивая им имя), и обычно эти две среды одинаковы -но не всегда.В пакете среда пространства имен используется для обоих, но затем (разная) среда пакета в пути поиска также имеет те же (экспортируемые) функции, которые определены.Таким образом, среды различаются.

# this will ensure only stats and packages later on the search list are searched for
# functions from your code (similar to import in a package)
e <- new.env(parent=as.environment("package:stats"))

# simple alternative if you want access to everything
# e <- new.env(parent=globalenv())

# Make all functions in "myfile.R" have e as environment
source("myfile.R", local=e)

# Or change an existing function to have a new environment:
e$myfunc <- function(x) sin(x)
environment(e$myfunc) <- e

# Alternative one-liner:
e$myfunc <- local(function(x) sin(x), e)

# Attach it if you want to be able to call them as usual.
# Note that this creates a new environment "myenv".
attach(e, name="myenv")

# remove all temp objects
rm(list=ls())

# and try your new function:
myfunc(1:3)

# Detach when it's time to clean up or reattach an updated version...
detach("myfile")

В приведенном выше примере e соответствует пространству имен, а присоединенный «myenv» соответствует среде пакета (например, «package: stats» в пути поиска).).

4 голосов
/ 26 января 2012

Пространства имен являются средами, поэтому вы можете использовать точно такой же механизм.Поскольку R использует лексическую область видимости, родительский объект среды определяет, что будет видеть функция (т. Е. Как связаны свободные переменные).И точно так же, как пространство имен, вы можете присоединять окружения и искать их.

Таким образом, чтобы создать новое «пространство имен вручную», вы можете использовать что-то вроде

e <- new.env(parent=baseenv())
# use local(), sys.source(), source() or e$foo <- assignment to populate it, e.g.
local({
  f <- function() { ... }
  #...
}, e)
attach(e, name = "mySuperNamespace")

Теперь оно загружается и присоединяется так же, какпространство имен - так что вы можете использовать f так же, как это было в пространстве имен.Пространства имен используют еще одну родительскую среду для разрешения импорта - вы можете сделать это тоже, если вам не все равно.Если вам нужно проверить свою прохладную среду, просто проверьте путь поиска, например, "mySuperNamespace" %in% search().Если вам нужна реальная среда, используйте as.environment("mySuperNamespace")

2 голосов
/ 25 января 2012

Вы можете проверить, что среды существуют так же, как и любая другая переменная.

e <- new.env()
exists("e") && is.environment(e)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...