Dear R-Core Team,

I found an unexpected behaviour in utils::removeSource (also present in r-devel as of today).

---

# create a function which accepts NULL argument
foo <- function(x, y) {
  if (is.null(y)) y <- "default foo"
  attr(x, "foo") <- y
  x
}

# create a function which utilizes 'foo'
testSrc <- function() {
  x <- 1:3
  x <- foo(x, NULL)
  x
}

# this works fine
testSrc()

# this fails
testNoSrc <- utils::removeSource(testSrc)
testNoSrc()

# removeSource removes NULL from the 'foo' call
print(testNoSrc)

---

I traced back the bug to this row in removeSource:

(line 33 in sourceutils.R)
part[[i]] <- recurse(part[[i]])

it should be (IMHO):
part[i] <- list(recurse(part[[i]]))

---

# create a function with the above patch
rmSource <- function (fn) {
  stopifnot(is.function(fn))
  if (is.primitive(fn))
    return(fn)
  attr(fn, "srcref") <- NULL
  attr(body(fn), "wholeSrcref") <- NULL
  attr(body(fn), "srcfile") <- NULL
  recurse <- function(part) {
    if (is.name(part))
      return(part)
    attr(part, "srcref") <- NULL
    attr(part, "wholeSrcref") <- NULL
    attr(part, "srcfile") <- NULL
    if (is.language(part) && is.recursive(part)) {
      for (i in seq_along(part))
        part[i] <- list(recurse(part[[i]]))
    }
    part
  }
  body(fn) <- recurse(body(fn))
  fn
}

# test
( testNoSrc2 <- rmSource(testSrc) )
testNoSrc2()


Regards,
Denes

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to