#r #methods #reference-class
#r #методы #ссылочный класс
Вопрос:
В настоящее время я разрабатываю ссылочные классы (R5) для больших объектов, для создания которых требуется время, и мне интересно, знает ли кто-нибудь лучший способ разработки методов, чем переопределение класса с помощью setRefClass и воспроизведение объекта каждый раз, когда я обновляю метод.
Другими словами: можно ли переопределить методы существующего объекта ссылочного класса?
Ответ №1:
Я рассматривал возможность выполнения следующего:
test <- setRefClass("TEST",
fields = list(a = "numeric"),
methods = list(
funA = function(){
a <<- a 1
},
initialize = function(){
a <<- 1
callSuper()
}
)
)
ex1 <- test$new()
ex1$funA()
test$methods(funA = function(){
a <<- a 10
}
)
ex$funA
# Class method definition for method funA()
# function ()
# {
# a <<- a 1
# }
# <environment: 0x0537f8ac>
ex1 <- test$new()$import(ex1)
ex$funA
# Class method definition for method funA()
# function ()
# {
# a <<- a 10
# }
# <environment: 0x04badc5c>
Я полагаю, что вы можете перезаписать предыдущий метод в классе с помощью class$methods(
, затем вы можете установить новый объект из вашего переопределенного класса и импортировать старый объект. Я бы отметил:
«Все методы для класса должны быть определены в исходном коде, который определяет класс, обычно как часть пакета. В частности, методы не могут быть переопределены в классе в прикрепленном пакете с пространством имен: метод класса проверяет наличие заблокированной привязки определения класса.» также из ?setRefClass
.
Ответ №2:
Эта проблема беспокоила меня уже несколько месяцев. Сегодня я нашел очень удобное решение, вдохновленное https://stat.ethz.ch/pipermail/r-help/2012-January/299743.html
Давайте начнем с ReferenceClass, который имеет ошибочную реализацию:
MyClass <- setRefClass(
"MyClass",
fields = list(
xy = "data.frame"
),
methods = list(
initialize = function( df ){
if( !missing( df ) ){
xy <<- df
}
},
getSecondRow = function(){
# A mistake happend here
return( xy[1,] )
}
)
)
mc <- MyClass$new( data.frame( a = 1:10, b = rnorm(10) ) )
mc$getSecondRow()
a b
1 1 0.1349983
Реализация getSecondRow
, очевидно, не дает желаемого результата. Таким образом, фиксированный метод на самом деле должен выглядеть как
getSecondRow = function(){
return( xy[2,] )
}
Классы без явной реализации конструктора
Хитрость вместо загрузки класса и воспроизведения объекта с нуля заключается в создании нового объекта из существующего, используя функциональность конструктора копирования конструктора по умолчанию initialize( ... )
. После отладки и перезагрузки класса вы можете просто скопировать существующий объект с реализацией в ту же переменную с помощью
# NOTRUN
mc <- MyClass$new( mc )
Классы с перезаписанным конструктором.
Однако в представленном здесь случае стандартный конструктор уже перезаписан. Но в таких случаях вы можете просто использовать функциональность callSuper( ... )
так, чтобы ваш конструктор выглядел как
initialize = function( df, ... ){
callSuper( ... )
if( !missing( df ) ){
xy <<- df
}
}
Наконец, ваш фиксированный объект получен с помощью
mc <- MyClass$new( mc$xy, mc )
mc$getSecondRow()
a b
2 2 0.8452587