Обновить метод ссылочного класса

#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