Доступ к слотам суперкласса функции S4 - PullRequest
3 голосов
/ 30 ноября 2011

Могу ли я создать S4 суперкласс "function" и получить доступ к слотам этого объекта из вызова функции?На данный момент у меня есть:

> setClass("pow",representation=representation(pow="numeric"),contains="function")
[1] "pow"
> z=new("pow",function(x){x^2},pow=3)
> z(2)
[1] 4

Теперь, что я действительно хочу, чтобы функция была х в степени слота @pow сама по себе, так что если я тогда сделаю:

> z@pow=3 

Я получаю кубы, и если я получаю:

> z@pow=2

Я получаю квадраты.

Но я не понимаю, как получить ссылку на «я», как я бы сделалв Python.Я думаю, это где-то в среде где-то ...

Вот как это работает в Python:

class Pow:
    def __init__(self,power):
        self.power=power
        self.__call__ = lambda x: pow(x,self.power)

p = Pow(2) # p is now a 'squarer'
print p(2) # prints 4

p.power=3 # p is now a 'cuber'
print p(2) # prints 8

Не может быть проще, и мне даже не пришлосьсделать "импорт антигравитации" ....

Ответы [ 3 ]

3 голосов
/ 01 декабря 2011

прибегая к небольшим языковым манипуляциям

setClass("Pow", representation("function", pow="numeric"),
         prototype=prototype(
           function(x) {
               self <- eval(match.call()[[1]])
               x^self@pow
           }, pow=2))

, а затем

> f = g = new("Pow")
> g@pow = 3
> f(2)
[1] 4
> g(2)
[1] 8

хотя, как говорит Spacedman, все может пойти не так

> f <- function() { Sys.sleep(2); new("Pow") }
> system.time(f()(2))
   user  system elapsed 
  0.002   0.000   4.005 

Немного больше в рамках, но отклонение от спецификации проблемы и, вероятно, не менее легкое для глаз

setClass("ParameterizedFunFactory",
         representation(fun="function", param="numeric"),
         prototype=prototype(
           fun=function(x, param) function(x) x^param,
           param=2))

setGeneric("fun", function(x) standardGeneric("fun"))
setMethod(fun, "ParameterizedFunFactory",
          function(x) x@fun(x, x@param))

с

> f = g = new("ParameterizedFunFactory")
> g@param = 3
> fun(f)(2)
[1] 4
> fun(g)(2)
[1] 8
0 голосов
/ 26 августа 2017

Похоже, что к родительской функции можно получить доступ через sys.function.

setClass("pow", slots = c(pow = "numeric"), contains = "function")
z <- new("pow", function (x) x^(sys.function()@pow), pow = 2)
z(6)
# [1] 36
z@pow <- 3
z(6)
# [1] 216

Я не знаю, существует ли sys.function, когда этот вопрос впервые обсуждался.

0 голосов
/ 30 ноября 2011

Я думаю, это зависит от того, что вы действительно хотите.Эта реализация ближе к вашей цели?

setClass("pow",representation=representation(pow="numeric"),contains="function")
z=new("pow",function(x, pow=3){x^pow})
>  z(2)
[1] 8
 z(2,4)
#[1] 16
...