2011-11-30 38 views
3

我可以創建一個「函數」的S4超類並從函數調用訪問該對象的插槽嗎?目前,我有:訪問S4函數超類的插槽

> 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插槽的力量,所以,如果我再做:

> [email protected]=3 

我得到立方體,如果我這樣做:

> [email protected]=2 

我得到正方形。

但我不明白如何獲得對「自我」的引用,就像我在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 

不能真正容易的,我甚至沒有做「進口反引力「....

+0

我想你可能想使用參考類 – hadley

+0

是啊?這次S語言終於得到了面向對象的編程嗎? – Spacedman

+0

如果按照正確的方式,你的意思是以一種你熟悉java這樣的語言的方式實現,那麼是的。 – hadley

回答

3

求助於小語言操縱

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

然後

> f = g = new("Pow") 
> [email protected] = 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 

多一點的線內但devia婷從問題規範,可能沒有那麼容易對眼睛是

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) [email protected](x, [email protected])) 

> f = g = new("ParameterizedFunFactory") 
> [email protected] = 3 
> fun(f)(2) 
[1] 4 
> fun(g)(2) 
[1] 8 
+0

我可能只是給你。雖然如果你嘗試做一個匿名對象:new(「Pow」)(3),它實際上從eval創建的另一個新對象獲得了@ @pow槽,而不是由最初的「new」調用創建的。不是說它有什麼區別,反正它是一件非常不正常的事情。 eval幾乎總是邪惡的。 – Spacedman

+0

不寒而慄。你讓我的眼睛流血。 – hadley

0

我認爲這取決於你真正想要的。這個實現是否更接近你的目標?

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 
+0

你不需要S4 ... –

0

看來,父函數可以通過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 
[email protected] <- 3 
z(6) 
# [1] 216 

,我不知道是否是時候討論首先這個問題sys.function存在,雖然。