Использование метода / функции в одноименном методе ссылочного класса

При определении нового ссылочного класса в R существует множество шаблонных методов, которые ожидаются (согласно соглашениям R), например length, show и т. Д. Когда они определены, они агрессивно маскируют похожие именованные методы / функции при вызове изнутри методы класса. Поскольку вы не обязательно можете знать пространство имен сторонней функции, использовать спецификатор package:: невозможно.

Есть ли способ указать методу игнорировать свои собственные методы, если они не вызываются специально с использованием .self $?

Пример:

tC <- setRefClass(
  'testClass',
  fields = list(data='list'),
  methods = list(
    length=function() {
      length(data)
    }
  )
)

example <- tC(data=list(a=1, b=2, c=3))
example$length()    # Will cause error as length is defined without arguments

В качестве альтернативы можно было бы прибегнуть к определению методов S4 для класса (поскольку ссылочные классы - это классы S4 под капотом), но это, похоже, работает против идеи ссылочного класса ...

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

tC <- setRefClass(
  'testClass',
  fields = list(data='list'),
  methods = list(
    length=function() {
      length(data)
    },
    combineLengths = function(otherObject) {
      .self.length() + length(otherObject)
    }
  )
)

example <- tC(data=list(a=1, b=2, c=3))
example$combineLength(rep(1, 3))    # Will cause error as length is defined without arguments

Я знаю, что можно написать собственную отправку для правильного метода / функции, но это кажется такой распространенной ситуацией, что я подумал, что она, возможно, уже была решена в пакете методов (своего рода обратное usingMethods())

У меня такой вопрос, и я прошу прощения, если это не было ясно раньше: есть ли способы игнорировать там методы и поля ссылочного класса в определениях методов и полагаться исключительно на .self для доступа к ним, так что методы / функции, определенные вне класса не замаскированы?


person ThomasP85    schedule 05.10.2014    source источник
comment
Мне кажется, что вы всегда знаете пространство имен чужой функции. Вы можете увидеть это, например, на странице справки. В вашем примере base::length(data) будет достаточно, чтобы он заработал.   -  person nicola    schedule 05.10.2014
comment
В случае, если вы знаете, что ввод - это список, да. Но представьте ситуацию, когда пользователь предоставляет данные, то есть длина не вызывается в одном из полей, поэтому вы не знаете, что передается. Вы можете разрешить методу принимать несколько разных объектов, определенных в разных пакетах. Чтобы использовать ::, вам нужно будет изучить объекты и выполнить отправку вручную - что R обычно сделает за вас.   -  person ThomasP85    schedule 05.10.2014
comment
@ ThomasP85 ваш пример непонятен, и ваш последний комментарий тоже. Вы используете класс, чтобы явно установить тип данных (в данном случае это список), так как же вы не можете его тип?   -  person agstudy    schedule 05.10.2014


Ответы (1)


Пример не очень ясный. Я не знаю, по какой причине вы не можете знать пространство имен вашего метода. Как бы то ни было, вот несколько способов обойти эту проблему:

  1. Вы можете использовать другое имя для метода ссылочного класса Length с заглавной буквой "L", например
  2. Вы можете динамически найти пространство имен универсальной функции.

Например:

  methods = list(
    .show =function(data) {
      ns = sub(".*:","",getAnywhere("show")$where[1])
      func = get("show",envir = getNamespace(ns))
      func(data)
    },
    show=function() {
      .show(data)
    }
  )
  1. Вы можете использовать новый эталонный класс System R6.

Например:

tC6 <- R6Class('testClass',
  public = list(
    data=NA,
    initialize = function(data) {
      if (!missing(data)) self$data <- data
    },
    show=function()   show(self$data)
  )
)
person agstudy    schedule 05.10.2014