From james.f.hester at gmail.com  Tue Dec 22 17:28:04 2015
From: james.f.hester at gmail.com (Jim Hester)
Date: Tue, 22 Dec 2015 11:28:04 -0500
Subject: [Rd] unloadNamespace() does not address unevaluated promises in the
 S3 Methods Table
Message-ID: <CAD6tx95oGh5zQQ2239to25_DG2gJ7Tt8+Ueue=X2Qj0C7Rw6QA@mail.gmail.com>

Given the extremely simple package at
https://github.com/jimhester/testUnload, which includes only one S3 method
'print.object' the following code produces a lazy load error from a new R
session (R-devel r69801)

install.packages("testUnload", repos = NULL)
library("testUnload")
unloadNamespace("testUnload")
install.packages("testUnload", repos = NULL)
library("testUnload")
#> Error in get(method, envir = home) :
#>   lazy-load database '{sic}/testUnload/R/testUnload.rdb' is corrupt
#> In addition: Warning message:
#> In get(method, envir = home) : internal error -3 in R_decompress1
#> Error: package or namespace load failed for ?testUnload?

Upon investigation this is because the code in registerS3Methods creates a
promise using 'delayedAssign' for 'print.object' function in the
'.__S3MethodsTable__.' environment within the base environment (which is
where the 'print' generic is defined). (see lines 1387-1489 in
src/library/base/R/namespace.R).

When the second install.packages is called the files are changed before the
original promise is evaluated, which causes the error. An easy way to see
this is to explicitly evaluate the promise prior to the reinstall, which
removes the error.

library("testUnload")
get(".__S3MethodsTable__.", envir = baseenv())$print.object
#> function(x, ...) x
#> <environment: namespace:testUnload>
unloadNamespace("testUnload")
install.packages("testUnload", repos = NULL)
library("testUnload")


Explicitly deleting the promise after unloading the namespace also fixes
this issue.

library("testUnload")
unloadNamespace("testUnload")
rm(list="print.object", envir = get(".__S3MethodsTable__.", envir =
baseenv()))
install.packages("testUnload", repos = NULL)
library("testUnload")


In my opinion, once the namespace is unloaded the corresponding entries
should be removed in the S3 Methods Table by default.

If others agree with this assessment I can try to provide a patch to
'unloadNamespace' to fix this, but I imagine it will be somewhat tricky to
get correct so others more familiar with this code may be better suited
than I.

Jim

	[[alternative HTML version deleted]]



[Rd] unloadNamespace() does not address unevaluated promises in the S3 Methods Table
Jim Hester