Bug 15267 - S3 methods lose track of own generic in some cases
S3 methods lose track of own generic in some cases
Status: CLOSED FIXED
Product: R
Classification: Unclassified
Component: Language
R 3.0.0
All All
: P5 normal
Assigned To: R-core
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2013-04-11 15:12 UTC by Peter Dalgaard
Modified: 2013-07-03 19:13 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Dalgaard 2013-04-11 15:12:26 UTC
This cropped up in the context of namespaces. Package tseries imports zoo, but some methods wouldn't work unless zoo was actually loaded (notably, you could not diff() a "zoo" object). 

The deeper reason, however, seems to be the one displayed by the following minimal example


dd <- Sys.Date()
f <- function () {
    h <- function(x) UseMethod("h")
    h.bar <- function(x) "bar"
    x <- structure(1, class = "bar")
    dd[h(x)] 
}

f() ## Error in h(x) : could not find function "h"

----

The culprit seems to be the way UseMethod goes looking for the generic. It assumes that is is in the scope of R_GlobalContext->sysparent, but in the above case, methods dispatch and lazy evaluation conspire to create a situation where the assumption fails. 

Check src/main/object.c:37--44.
Comment 1 Peter Dalgaard 2013-04-12 12:39:50 UTC
Addendum:

Modifying the example to use


 f <- function () {
    h <- function(x) {s <- sys.status(); print(s) ; UseMethod("h")}
<...>

yields the output below. Notice in particular, that the parent of the call to NextMethod is frame 3, the evaluation environment of [.Date. This also ends up as the parent of the call to h(), but h is not in its scope. 

It is tempting to conclude that NextMethod ought to have the same parent as its caller. 


$sys.calls
$sys.calls[[1]]
f()

$sys.calls[[2]]
dd[h(x)]

$sys.calls[[3]]
`[.Date`(dd, h(x))

$sys.calls[[4]]
NextMethod("[")

$sys.calls[[5]]
h(x)

$sys.calls[[6]]
sys.status()


$sys.parents
[1] 0 1 1 3 3 5

$sys.frames
$sys.frames[[1]]
<environment: 0x7f89045ec388>

$sys.frames[[2]]
<environment: 0x7f8905701498>

$sys.frames[[3]]
<environment: 0x7f89056fdc60>

$sys.frames[[4]]
<environment: 0x7f890570b188>

$sys.frames[[5]]
<environment: 0x7f8905714200>

$sys.frames[[6]]
<environment: 0x7f8905716990>
Comment 2 Peter Dalgaard 2013-07-03 19:13:46 UTC
Looks like r63147 fixes this (in R-devel only for now).