如何使用跟踪将 S4 泛型函数单步执行到实际调度的方法中?
How to use trace to step through S4 generic function into method actually dispatched?
我有一组简单的 S4 classes,只有一个通用方法。我希望能够使用 trace()
来调试 S4 方法。
$ cat s4class.R
add<-function(a,b){
d=0
e=9
return(a+b)
}
setClass('astrophys_object',
representation(mass="numeric", spin="numeric", radius="numeric",
v="numeric", x="numeric", charge="numeric"),
prototype(mass=1, spin=1.92e41, radius=6.957e8, v=c(0,0,0),
x=c(0,0,0), charge=0)
)
setClass('star',
contains="astrophys_object",
representation(type="character", metallicity="numeric", temp="numeric"),
prototype(type="MS", metallicity=0.0122, temp=5700)
)
setClass('galaxy',
contains="astrophys_object",
representation(type="character", sfr="numeric"),
prototype(type="spiral", sfr=1.65, mass=5.8e11, spin=1.0e67)
)
setGeneric("spin_object", function(object){
standardGeneric("spin_object")
})
setMethod("spin_object", signature(object = "galaxy"), function(object){
object@spin = 66
return(object)
})
setMethod("spin_object", signature(object = "star"), function(object){
object@spin = 99
return(object)
})
我能够单步执行测试函数 add()
。
> trace(add, browser, at=1)
[1] "add"
> add(9,8)
Tracing add(9, 8) step 1
Called from: eval(expr, p)
Browse[1]> n
debug: `{`
Browse[2]> n
debug at R/Whosebug.R#19: d = 0
Browse[2]> n
debug at R/Whosebug.R#20: e = 9
Browse[2]> n
debug at R/Whosebug.R#21: return(a + b)
Browse[2]> n
[1] 17
现在让我们尝试单步执行 spin_object
泛型方法。
> trace(spin_object, browser, at=1)
Constructing traceable class “nonstandardGenericFunctionWithTrace”
Environment of class “nonstandardGenericFunction” is locked; using global environment for new class
[1] "spin_object"
attr(,"package")
[1] ".GlobalEnv"
> s<-new('star')
> spin_object(s)
Tracing spin_object(s) step 1
Called from: eval(expr, p)
Browse[1]> n
debug: `{`
Browse[2]> n
debug at R/Whosebug.R#45: standardGeneric("spin_object")
Browse[2]> s
debugging in: loadMethod(function (object)
{
object@spin = 99
return(object)
}, "spin_object", <environment>)
debug: standardGeneric("loadMethod")
Browse[3]> n ##### <<<---- If I step here, I end up stepping into "loadMethod" NOT spin_object
exiting from: loadMethod(function (object)
{
object@spin = 99
return(object)
}, "spin_object", <environment>)
An object of class "star"
Slot "type":
[1] "MS"
Slot "metallicity":
[1] 0.0122
Slot "temp":
[1] 5700
Slot "mass":
[1] 1
Slot "spin":
[1] 99
Slot "radius":
[1] 695700000
Slot "v":
[1] 0 0 0
Slot "x":
[1] 0 0 0
Slot "charge":
[1] 0
问题 我如何实际逐步完成为 star
class 分派的 spin_object
?如果我尝试进入 Browser[3]
,我最终会进入 loadMethod
并且 NOT 正在调度的方法。
为此,我需要为 trace()
指定签名参数
trace(what='spin_object', tracer=browser, at=1, signature='star')
我有一组简单的 S4 classes,只有一个通用方法。我希望能够使用 trace()
来调试 S4 方法。
$ cat s4class.R
add<-function(a,b){
d=0
e=9
return(a+b)
}
setClass('astrophys_object',
representation(mass="numeric", spin="numeric", radius="numeric",
v="numeric", x="numeric", charge="numeric"),
prototype(mass=1, spin=1.92e41, radius=6.957e8, v=c(0,0,0),
x=c(0,0,0), charge=0)
)
setClass('star',
contains="astrophys_object",
representation(type="character", metallicity="numeric", temp="numeric"),
prototype(type="MS", metallicity=0.0122, temp=5700)
)
setClass('galaxy',
contains="astrophys_object",
representation(type="character", sfr="numeric"),
prototype(type="spiral", sfr=1.65, mass=5.8e11, spin=1.0e67)
)
setGeneric("spin_object", function(object){
standardGeneric("spin_object")
})
setMethod("spin_object", signature(object = "galaxy"), function(object){
object@spin = 66
return(object)
})
setMethod("spin_object", signature(object = "star"), function(object){
object@spin = 99
return(object)
})
我能够单步执行测试函数 add()
。
> trace(add, browser, at=1)
[1] "add"
> add(9,8)
Tracing add(9, 8) step 1
Called from: eval(expr, p)
Browse[1]> n
debug: `{`
Browse[2]> n
debug at R/Whosebug.R#19: d = 0
Browse[2]> n
debug at R/Whosebug.R#20: e = 9
Browse[2]> n
debug at R/Whosebug.R#21: return(a + b)
Browse[2]> n
[1] 17
现在让我们尝试单步执行 spin_object
泛型方法。
> trace(spin_object, browser, at=1)
Constructing traceable class “nonstandardGenericFunctionWithTrace”
Environment of class “nonstandardGenericFunction” is locked; using global environment for new class
[1] "spin_object"
attr(,"package")
[1] ".GlobalEnv"
> s<-new('star')
> spin_object(s)
Tracing spin_object(s) step 1
Called from: eval(expr, p)
Browse[1]> n
debug: `{`
Browse[2]> n
debug at R/Whosebug.R#45: standardGeneric("spin_object")
Browse[2]> s
debugging in: loadMethod(function (object)
{
object@spin = 99
return(object)
}, "spin_object", <environment>)
debug: standardGeneric("loadMethod")
Browse[3]> n ##### <<<---- If I step here, I end up stepping into "loadMethod" NOT spin_object
exiting from: loadMethod(function (object)
{
object@spin = 99
return(object)
}, "spin_object", <environment>)
An object of class "star"
Slot "type":
[1] "MS"
Slot "metallicity":
[1] 0.0122
Slot "temp":
[1] 5700
Slot "mass":
[1] 1
Slot "spin":
[1] 99
Slot "radius":
[1] 695700000
Slot "v":
[1] 0 0 0
Slot "x":
[1] 0 0 0
Slot "charge":
[1] 0
问题 我如何实际逐步完成为 star
class 分派的 spin_object
?如果我尝试进入 Browser[3]
,我最终会进入 loadMethod
并且 NOT 正在调度的方法。
为此,我需要为 trace()
trace(what='spin_object', tracer=browser, at=1, signature='star')