Ответ 1
Здесь кандидат:
`=` <- function(...) stop("Assignment by = disabled, use <- instead")
# seems to work
a = 1
Error in a = 1 : Assignment by = disabled, use <- instead
# appears not to break named arguments
sum(1:2,na.rm=TRUE)
[1] 3
R позволяет назначать через <-
и =
.
В то время как между двумя операторами присваивания тонкие различия, похоже, существует широкий консенсус в отношении того, что <-
является лучшим выбором, чем =
, поскольку =
также используется в качестве значений отображения операторов для аргументов, и поэтому его использование может привести к неоднозначным утверждениям. Ниже приведен пример:
> system.time(x <- rnorm(10))
user system elapsed
0 0 0
> system.time(x = rnorm(10))
Error in system.time(x = rnorm(10)) : unused argument(s) (x = rnorm(10))
Фактически код стиля Google запрещает использование =
для назначения (см. комментарии к этому ответ для обратного просмотра).
Я также почти исключительно использую <-
как оператор присваивания. Тем не менее, почти в предыдущем предложении есть причина этого вопроса. Когда =
действует как оператор присваивания в моем коде, он всегда случайный, и если это приводит к проблемам, то их обычно трудно обнаружить.
Я хотел бы знать, есть ли способ отключить назначение через =
, и пусть R выдает ошибку в любое время =
для назначения.
Оптимально это поведение произойдет только для кода в глобальной среде, так как может быть код в прикрепленных пространствах имен, который использует =
для назначения и не должен прерываться.
(Этот вопрос был вдохновлен обсуждением Джонатан Нельсон)
Здесь кандидат:
`=` <- function(...) stop("Assignment by = disabled, use <- instead")
# seems to work
a = 1
Error in a = 1 : Assignment by = disabled, use <- instead
# appears not to break named arguments
sum(1:2,na.rm=TRUE)
[1] 3
Я не уверен, но, возможно, просто переписать назначение =
достаточно для вас. В конце концов, `=`
- это имя, как и любое другое - почти.
> `=` <- function() { }
> a = 3
Error in a = 3 : unused argument(s) (a, 3)
> a <- 3
> data.frame(a = 3)
a
1 3
Таким образом, любое использование =
для назначения приведет к ошибке, тогда как использование его для обозначения аргументов остается в силе. Его использование в функциях может остаться незамеченным, если только соответствующая строка не будет выполнена.
В пакете lint
(CRAN) есть проверка стиля для этого, поэтому, предположим, что у вас есть код в файле, вы можете запустить lint против него, и он предупредит вас об этих номерах строк с =
присваиваниями.
Вот пример:
temp <- tempfile()
write("foo = function(...) {
good <- 0
bad = 1
sum(..., na.rm = TRUE)
}", file = temp)
library(lint)
lint(file = temp, style = list(styles.assignment.noeq))
# Lint checking: C:\Users\flodel\AppData\Local\Temp\RtmpwF3pZ6\file19ac3b66b81
# Lint: Equal sign assignemnts: found on lines 1, 3
Пакет lint
поставляется с еще несколькими тестами, которые могут вам показаться интересными, в том числе:
=
Вы можете включить или выключить любую предопределенную проверку стиля, и вы можете написать свой собственный. Однако пакет все еще находится в зачаточном состоянии: он содержит несколько ошибок (https://github.com/halpo/lint), и документация немного сложна для переваривания. Автор реагирует хотя и медленно делает улучшения.
Если вы не хотите разорвать существующий код, что-то вроде этого (печатать предупреждение, а не ошибку) может работать - вы даете предупреждение, затем назначаете parent.frame
с помощью <-
(чтобы избежать какой-либо рекурсии)
`=` <- function(...){
.what <- as.list(match.call())
.call <- sprintf('%s <- %s', deparse(.what[[2]]), deparse(.what[[3]]))
mess <- 'Use <- instead of = for assigment '
if(getOption('warn_assign', default = T)) {
stop (mess) } else {
warning(mess)
eval(parse(text =.call), envir = parent.frame())
}
}
Если вы установите options(warn_assign = F)
, тогда =
будет предупреждать и назначать. Все остальное выкинет ошибку и не назначит.
# with no option set
z = 1
## Error in z = 1 : Use <- instead of = for assigment
options(warn_assign = T)
z = 1
## Error in z = 1 : Use <- instead of = for assigment
options(warn_assign = F)
z = 1
## Warning message:
## In z = 1 : Use <- instead of = for assigment
Я думаю, что formatR
или lint
и форматирование кода лучше подходят.