2014-01-18 2 views
3

Я пытаюсь назначить версии Pascal-Case переменных true, false, na и null в мой пакет R. Это очень легко сделать, но я также хочу заблокировать привязку, чтобы предотвратить переименование переменной.Назначение заблокированной переменной в пакете R

# An anti-example from the base libraries 
F <- TRUE 
T <- FALSE 

T && T 
FALSE 

Я не могу понять, как заблокировать переменную в пакете, чтобы предотвратить дальнейшую модификацию. Следовать фиктивный пакет не работает

# test.R 
True <- TRUE 
lockBinding('True', environment()) 

#DESCRIPTION 
Collate: 
    'test.R' 

При запуске R CMD проверить я получаю следующее сообщение об ошибке:

Error in eval(expr, envir, enclos) : 
    cannot change value of locked binding for 'True' 

Что такое правильный способ блокировки переменной R пакет, чтобы он не может быть переназначенная?

изменение: включено неправильное сообщение об ошибке.

+2

Вы не рассказываете нам всю историю. Токен 'Na' не зарезервирован в R, поэтому вы должны создать его или попытаться получить к нему доступ, когда он не существует ... или что-то еще. Ошибка mesasage не относится к «True» (также не зарезервированное слово в R.) –

+0

FWIW, как только пакет загружен, привязка заблокирована в любом случае, поэтому вы будете только предотвращать изменение кода, находящегося внутри пакета, при изменении привязка при начальной установке и загрузке. Это действительно ваша цель? –

+0

@MartinMorgan Я не уверен, что это правда.Например, require (plyr); llply <- identity; llply (10) == 10 – RyanGrannell

ответ

11

В основном не отвечает на ваш вопрос. Я согласен с @IShouldByABoat, что есть что-то еще, пакет с простой структурой, которую вы указываете, не генерирует ошибку, которую вы видите для меня. Вероятно, вы пытаетесь изменить True в другом месте вашего кода (!) Или, возможно, у вас есть какой-то рывок в вашем файле .Rprofile или .RData, который мешает - запустите проверку как R --vanilla CMD check.

Функции и символы определены в имени пакета пространстве, например

library(plyr)    ## load package name space, attach to the search() path 
getNamespace(plyr)  ## package name space 
ls(getNamespace(plyr)) ## symbols defined in the name space 
plyr::llply    ## definition of `llply` in the name space 

Имя пакета пространство блокируется после того, как он был загружен

assign("llply", identity, envir=getNamespace("plyr")) 
## Error in assign("llply", identity, envir = getNamespace("plyr")) : 
## cannot change value of locked binding for 'llply' 

Сопоставляя аналогичным названием переменной на командной строки создает новую переменную в .GlobalEnv (первое место на пути поиска()) вместо изменения переменной в пространстве имен пакета

ls()    ## no symbol 'llply' in .GlobalEnv 
llply <- identity ## new symbol 'llply' in .GlobalEnv 
llply(10)   ## use first llply function in search(), i.e., in .GlobalEnv 
plyr::llply(10) ## circumvent search path and use llply from plyr name space 

Так код, такие как

True <- TRUE 
lockBinding("True", environment()) 

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

Возможно, вы хотите создать переменную True в пользовательском .GlobalEnv и сделать так, чтобы ее нельзя было изменить. Это должно быть сделано, когда пакет load'ed (или attach'ed), когда ток .GlobalEnv пользователя виден, с чем-то вроде

.onAttach <- function(...) { 
    assign("True", TRUE, .GlobalEnv) 
    lockBinding("True", .GlobalEnv) 
} 

This только блокирует связывание в .GlobalEnv поэтому она не может быть изменен, но не останавливает пользователя от его удаления (например, с использованием rm("True")). Прослушивание вашего пользователя .GlobalEnv, вероятно, также послужит раздражать вашего пользователя больше, чем ваша программа программирования.

+5

+1 за сообщение, хотел бы добавить +10 для последнего предложения, но не может. –

Смежные вопросы