Frage

Kann ich eine S4 -Superklasse von "Funktion" erstellen und aus dem Funktionsaufruf auf die Slots dieses Objekts zugreifen? Im Moment habe ich:

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

Nun, was ich wirklich will, ist, dass die Funktion X zur Kraft des @pow -Slot von sich selbst ist. Wenn ich also:

> z@pow=3 

Ich bekomme Würfel und wenn ich es tue:

> z@pow=2

Ich bekomme Quadrate.

Aber ich sehe nicht, wie ich einen Hinweis auf 'Selbst' bekomme, wie ich es in Python tun würde. Ich vermute, es ist irgendwo in der Umgebung irgendwo ...

So funktioniert es in 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

Könnte nicht wirklich einfacher sein, und ich musste nicht einmal "Anigravität importieren".

War es hilfreich?

Lösung

Auf eine kleine Sprachmanipulation zurückgreifen

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

und dann

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

Obwohl, wie Spaceman sagt, Dinge schief gehen können

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

Ein bisschen mehr in den Zeilen, aber von der Problemspezifikation abweichen und wahrscheinlich nicht weniger einfach in den Augen ist

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))

mit

> f = g = new("ParameterizedFunFactory")
> g@param = 3
> fun(f)(2)
[1] 4
> fun(g)(2)
[1] 8

Andere Tipps

Ich denke, es hängt davon ab, was Sie wirklich wollen. Ist diese Implementierung näher an Ihrem Ziel?

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

Es scheint, dass auf die übergeordnete Funktion über die Überprüfung der übergeordneten Funktionen übertragen werden kann 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

Ich weiß nicht, ob sys.function existiert jedoch, als diese Frage zuerst diskutiert wurde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top