This is related to the following post Problems passing arguments with callNextMethod() in R
I am writing accessors for two S4 classes, 'foo' and 'bar'. 'bar' inherits from foo and is extended only by a few slots. Instead of writing a full accessor function for objects of class 'bar' I want to pass the arguments to callNextMethod() when accessing a slot that is inherited by 'foo'. My code looks like this:
foo <- setClass("foo", representation(x = "numeric", y = "numeric"))
bar <- setClass("bar", representation(distance = "numeric"), contains = "foo")
setMethod("[", "bar", function(x, i, j, drop) {
if (i == "distance") {
return(x@distance)
} else {
callNextMethod()
}
}
)
setMethod("[", "foo", function(x, i, j, drop) {
if (i == "x") {
return(x@x)
} else {
if (i == "y") {
return(x@y)
}
}
}
)
Now let's try this:
f <- new("foo", x = 1, y = 2)
b <- new("bar", x = 3, y = 4, distance = 5)
f["x"]
f["y"]
The accessor for object 'f' of class 'foo' properly returns:
> f["x"]
[1] 1
> f["y"]
[1] 2
If I try to access the slot 'distance' of the object 'b' of class 'bar' the accessor also properly returns:
> b["distance"]
[1] 5
The problem occurs when I try to access any of the slots of the object 'b' of class 'bar' which are inherited from 'foo'. If I try:
b["x"]
b["y"]
I get the following error message:
Error in callNextMethod() : bad object found as method (class “function”)
I have read the recommendations from this post Problems passing arguments with callNextMethod() in R but I cannot define a generic for '[' and trying to pass the arguments explicitly to callNextMethod() also failed.
Surely I am doing something wrong! I have read several resources on inheritances and cannot identify the problem and I hope you folks will be able to guide me towards the right direction.
Thanks
Max
Your methods both leave out one of the five formal arguments required by any [
method, namely the ellipsis (...
).
args(getGeneric("["))
# function (x, i, j, ..., drop = TRUE)
# NULL
Including it as a formal in both method definitions solves your problem:
setMethod("[", "bar", function(x, i, j, ..., drop) {
if (i == "distance") {
return(x@distance)
} else {
callNextMethod()
}
}
)
setMethod("[", "foo", function(x, i, j, ..., drop) {
if (i == "x") {
return(x@x)
} else {
if (i == "y") {
return(x@y)
}
}
}
)
b["distance"]
# [1] 5
b["x"]
# [1] 3
b["y"]
# [1] 4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With