Zugriff auf Slots einer S4 -Funktion Superklasse
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".
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.