Вопрос
Могу ли я создать S4 Superclass «функции» и получить доступ к слотам этого объекта из вызова функции? На данный момент у меня есть:
> setClass("pow",representation=representation(pow="numeric"),contains="function")
[1] "pow"
> z=new("pow",function(x){x^2},pow=3)
> z(2)
[1] 4
Теперь я действительно хочу, чтобы функция была x к мощности слота @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
Не мог быть действительно легче, и мне даже не нужно было делать «импортную антигравитацию» ....
Решение
Прибегая к небольшому манипуляциям с языком
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
Хотя, как говорит Редансман, все может пойти не так
> 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
Другие советы
Я думаю, это зависит от того, чего вы действительно хотите. Это реализация ближе к вашей цели?
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
Кажется, что родительская функция можно получить через 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
существует, когда этот вопрос был впервые обсужден.