henrik at singmann.org
2011-Aug-30 10:35 UTC
[Rd] unexpected behavior of callNextMethod() when passing arguments in methods to generic function
Hi, ? there seems to be an unexpected behavior when using callNextMethod() in a method to a (user defined) generic function so that additional arguments to the ones defined in the signature of the generic are not passed correctly (i.e., their value are lost/replaced by the default). ? Problem description: We have two hierarchical classes, "foo" and subclass "bar" and a generic function "foobar". There exists methods for foobar for both "foo" and "bar" that have the same signature, which differs from the signature in the generic function (i.e., there are additional arguments in the methods).There are default values for the additional arguments in the two methods.The method for "bar" contains a callNextMethod() statement. Now calling "foobar" for an object of class "bar" with an additional argument set to a non-defualt value leads to: in the method for "bar", the the additional argument is equal to the input; in the method for "foo" (i.e., within the callNextMethod() statement) the additional argument is equal to the default for that method (i.e., instead of equal to the user input). ? This behavior contrasts with my reading of ?callNextMethod which states: For a formal argument, sayx, that appears in the original call, there is a corresponding argument in the next method call equivalent tox = x. In effect, this means that the next method sees the same actual arguments, but arguments are evaluated only once. ? Therefore I would expect the additional argument be passed on by callNextMethod() as inputted by the user.? ? Example: ? setClass("foo", representation(x = "numeric")) setClass("bar", contains = "foo") setGeneric("foobar", function(object, ...) standardGeneric("foobar")) setMethod("foobar", "foo", function(object, another.argument = FALSE, ...) { ??? print(paste("another.argument in foo-method:", another.argument)) ??? object at x }) setMethod("foobar", "bar", function(object, another.argument = FALSE, ...) { ??? print(paste("another.argument in bar-method:", another.argument)) ??? callNextMethod() }) o1 <- new("bar", x = 4)> foobar(o1, another.argument = TRUE)[1] "another.argument in bar-method: TRUE" [1] "another.argument in foo-method: FALSE" [1] 4 ? Related Issues: I already asked this question on stackoverflow (http://stackoverflow.com/q/7190697/289572) and got a helpful answer with workarounds from Martin Morgan. However, I have the feeling that this may be of interest here, too.? This problem may or may not be related to the following similar bug reported on r-devel:? http://thread.gmane.org/gmane.comp.lang.r.devel/23263/focus=23266 ? Best, Henrik? ? ? PS:> sessionInfo()R version 2.13.1 (2011-07-08) Platform: i386-pc-mingw32/i386 (32-bit) locale: [1] LC_COLLATE=English_United Kingdom.1252? LC_CTYPE=English_United Kingdom.1252??? LC_MONETARY=English_United Kingdom.1252 [4] LC_NUMERIC=C??????????????????????????? LC_TIME=English_United Kingdom.1252??? attached base packages: [1] stats???? graphics? grDevices utils???? datasets? methods?? base???? other attached packages: [1] fortunes_1.4-2