可以反编译R字节码吗?

时间:2015-11-20 00:58:30

标签: r compilation package

是否可以从包中的编译R代码转回R源代码?我想从CRAN或其他来源安装的软件包中获取各种功能的源代码。我知道我可以通过单独下载来下载完整的源代码。

2 个答案:

答案 0 :(得分:2)

您可以使用args()body()提取包中的函数文本。要列出包中的所有对象,可以使用ls()并指定包环境。

警告:下面的方法会为您提供源代码,但不会为NAMESPACEDESCRIPTION提供。

例如,要打印ggplot2中所有内容的源代码,请尝试以下操作:

library(ggplot2)
pkg <- as.environment("package:ggplot2")
allfuns <- ls(envir = pkg)

for(f in allfuns[1:2]){
  args <- capture.output(print(args(f)))[1]
  body <- paste(capture.output(print(body(f))), collapse = "\n")
  cat(sprintf("%s <- %s\n%s\n\n", f, args, body))
}

这会给你:

%+% <- function (e1, e2) 
{
    e2name <- deparse(substitute(e2))
    if (is.theme(e1)) 
        add_theme(e1, e2, e2name)
    else if (is.ggplot(e1)) 
        add_ggplot(e1, e2, e2name)
}

%+replace% <- function (e1, e2) 
{
    if (!is.theme(e1) || !is.theme(e2)) {
        stop("%+replace% requires two theme objects", call. = FALSE)
    }
    e1[names(e2)] <- e2
    e1
}

答案 1 :(得分:1)

Andrie 上面的回答对我很有帮助。我不得不使用不在 CRAN 或 git 上的包,并且仅作为为 R 3.0.1 构建的编译包分发。很明显,当我尝试将它与 R 4 一起使用时,它不起作用,而且我不想在 R 版本之间来回切换,所以我不得不反编译包,重建源代码,然后重新安装。

然而,Andrie 的代码示例有一些缺点,最重要的是它只反编译导出的函数,而不是内部函数。显然这篇文章已经很旧了,但我在这里发布了我的更新,以防它对其他人尝试做同样的事情有所帮助。

packagename <- "ggplot2" #input package name here

pkg <- asNamespace(packagename) # importing as namespace rather than package accesses internals

allfuns <- ls(name = pkg)

for(f in allfuns){
  # Andrie's [1] subset didn't work if the function arguments were more than one line long
  args <- head(capture.output(print(args(getFromNamespace(f, packagename)))), -1) 
  body <- paste(capture.output(print(body(getFromNamespace(f, packagename)))), 
                collapse = "\n")
  # This now writes directly to an R code file, rather than the console, to avoid copy/paste
  # You could tweak this to create a separate file for each function, if desired.
  cat(sprintf("%s <- %s\n%s\n\n", f, args, body), 
      file = paste(packagename, "functions.R"), 
      append = TRUE)
}