Обновите метод Reference Class - PullRequest
4 голосов
/ 07 ноября 2011

В настоящее время я разрабатываю справочные классы (R5) для больших объектов, создание которых занимает время, и мне интересно, знает ли кто-то лучший способ разработки методов, чем переопределение класса с помощью setRefClass и воспроизведение объекта каждый раз, когда я обновляю метод.

Другими словами: можно ли переопределить методы существующего объекта класса Reference?

Ответы [ 2 ]

2 голосов
/ 15 мая 2013

Эта проблема беспокоила меня уже несколько месяцев. Сегодня я нашел очень удобное решение, вдохновленное 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
2 голосов
/ 29 сентября 2012

Я подумал сделать следующее:

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 также.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...