4

trace doesn't seem to work correctly inside precompiled functions

For example, in this snippet

xx <- 2:7
nu <- seq(-10, 9, length.out = 2001)
op <- par(lab = c(16, 5, 7))
matplot(nu, t(outer(xx, nu, besselI)), type = "l", ylim = c(-50, 200),
        main = expression(paste("Bessel ", I[nu](x), " for fixed ", x,
                                ",  as ", f(nu))),
        xlab = expression(nu))

Simple trace for xy.coords works fine

trace(xy.coords)
matplot(nu, t(outer(xx, nu, besselI)), type = "l", ylim = c(-50, 200),
        main = expression(paste("Bessel ", I[nu](x), " for fixed ", x,
                                ",  as ", f(nu))),
        xlab = expression(nu))
# trace: xy.coords
# trace: xy.coords
# trace: xy.coords
# trace: xy.coords
# trace: xy.coords
# trace: xy.coords
# trace: xy.coords

But tracing with function doesn't seem to work

trace(xy.coords, tracer = quote(cat("test\n")))
# Tracing function "xy.coords" in package "grDevices"
# [1] "xy.coords"
matplot(nu, t(outer(xx, nu, besselI)), type = "l", ylim = c(-50, 200),
        main = expression(paste("Bessel ", I[nu](x), " for fixed ", x,
                                ",  as ", f(nu))),
        xlab = expression(nu))

While direct call works fine

xy.coords(1:3, 1:2, recycle = TRUE)
# Tracing xy.coords(1:3, 1:2, recycle = TRUE) on entry 
# test
# $x
# [1] 1 2 3
# 
# $y
# [1] 1 2 1
# 
# $xlab
# NULL
# 
# $ylab
# NULL

What is going on and what do I need to change that?

Update I disable compilation of grDevices and other base packages, but trace still doesn't work correctly. When debugging matplot, xy.coords appears to be without tracing.

Update 2 This seems to be related to Override a function that is imported in a namespace, but after trying everything suggested there with assigning in namespace the traced object, the old one still gets called.

Community
  • 1
  • 1
romants
  • 3,660
  • 1
  • 21
  • 33

1 Answers1

1

Acting on the imports of graphics (where matplot belongs) seems to do the trick:

xx <- 2:7
nu <- seq(-10, 9, length.out = 2001)
op <- par(lab = c(16, 5, 7))

trace(xy.coords, tracer = quote(cat("test\n")))

# get the imports env of graphics
nsi <- parent.env(getNamespace('graphics'))

unlockBinding("xy.coords", nsi)
assign('xy.coords', xy.coords, nsi)

matplot(nu, t(outer(xx, nu, besselI)), type = "l", ylim = c(-50, 200),
        main = expression(paste("Bessel ", I[nu](x), " for fixed ", x,
                                ",  as ", f(nu))),
        xlab = expression(nu))


Tracing xy.coords(x, y, xlabel, ylabel, log = log) on entry 
test
Tracing xy.coords(x, y, xlabel, ylabel, log) on entry 
test
Tracing xy.coords(x, y) on entry 
test
Tracing xy.coords(x, y) on entry 
test
Tracing xy.coords(x, y) on entry 
test
Tracing xy.coords(x, y) on entry 
test
Tracing xy.coords(x, y) on entry 
test
Karl Forner
  • 4,175
  • 25
  • 32
  • Thanks, I didn't realize to look into the imports namespace – romants Oct 14 '15 at 23:07
  • @RomanTsegelskyi please explain why simply doing `trace(xy.coords, tracer = quote(cat("test\n")), where = matplot)` wasnt sufficient – rawr Oct 15 '15 at 15:37
  • 1
    looking at trace() code, it seems that with no tracer arg, the tracing is performed by .Primitive(".primTrace"), otherwise by methods:::.TraceWithMethods(). Hence two different implementations. – Karl Forner Oct 15 '15 at 15:43