2014-09-25 42 views
12

我注意到,当我打电话args on 一些的原始功能,字节码也显示出来。但在其他原语中,不会出现字节码。例如为什么一些原语有字节码,有些则不?

args(length) 
# function (x) 
# NULL 
args(list) 
# function (...) 
# NULL 
# <bytecode: 0x44a0f38> 

这是为什么?

起初我以为它可能与...的论点有关,但是下面的理论反驳了这个理论。

args(dim) 
# function (x) 
# NULL 
args(unclass) 
# function (x) 
# NULL 
# <bytecode: 0x44a0450> 

让我感到困惑的是,字节码只出现在其中一些字符码中,而不是其他字符码。我一直认为,所有的基元都是特殊的,它们都具有相同的“属性”(缺乏一个更好的词,而不是实际的R属性)。

+0

我想印刷的差异是为了更多的历史原因。 'args'更多地用于控制台打印,也许使用'formals'来获得更加连贯的输出。 – agstudy 2014-09-25 06:17:19

回答

9

正如agstudy所指出的,这与args如何印刷有关。也就是说,args在其输出中是否包含字节码行不是该函数是否是字节编译的可靠指示器。比较:

args(writeLines) 
## function (text, con = stdout(), sep = "\n", useBytes = FALSE) 
## NULL 

writeLines 
## function (text, con = stdout(), sep = "\n", useBytes = FALSE) 
## { 
## if (is.character(con)) { 
##  con <- file(con, "w") 
##  on.exit(close(con)) 
## } 
## .Internal(writeLines(text, con, sep, useBytes)) 
## } 
## <bytecode: 0x000000001bf3aeb0> 

我们可以比较字节码线的印刷为args,相对于标准打印功能。

arg_shows_bytecode <- function(fn) 
{ 
    output <- capture.output(args(fn)) 
    grepl("^<bytecode", output[length(output)]) 
} 

printing_shows_bytecode <- function(fn) 
{ 
    output <- capture.output(print(fn)) 
    length(output) > 1 && grepl("^<bytecode", output[length(output) - 1]) 
} 

base_fns <- Filter(is.function, mget(ls(baseenv()), baseenv())) 
yn_args <- vapply(base_fns, arg_shows_bytecode, logical(1)) 
yn_print <- vapply(base_fns, printing_shows_bytecode, logical(1)) 

值得一提的是,其中args显示字节信息的所有功能都是原语。

head(base_fns[yn_args]) 
## $`%*%` 
## function (x, y) .Primitive("%*%") 
## 
## $as.call 
## function (x) .Primitive("as.call") 
## 
## $attr 
## function (x, which, exact = FALSE) .Primitive("attr") 
## 
## $`attr<-` 
## function (x, which, value) .Primitive("attr<-") 
## 
## $attributes 
## function (obj) .Primitive("attributes") 
## 
## $`attributes<-` 
## function (obj, value) .Primitive("attributes<-") 

反过来是不正确的:一些基本函数,其中args不显示字节码信息是原语;其他人不是。在基础包

yn_prim <- vapply(base_fns, is.primitive, logical(1)) 
table(yn_args, yn_print, yn_prim) 
## , , yn_prim = FALSE 
## 
##  yn_print 
## yn_args FALSE TRUE 
## FALSE  0 988 
## TRUE  0 0 
## 
## , , yn_prim = TRUE 
## 
##  yn_print 
## yn_args FALSE TRUE 
## FALSE  119 0 
## TRUE  63 0 

所以非基本功能都编译,但args没有提到它。原始函数在打印时不显示字节码消息,只有在用args调用时才显示字节码消息。

+3

更简单的解释:这是'args()'中的一个错误。它不应该显示字节码编译状态,因为这不是函数参数列表的属性。 – hadley 2014-09-26 11:35:38

1

感谢您的报告。这种行为是无意的(如哈德利说的一个错误),它在内部并不一致,因为字节码地址只显示内置和特殊字符,并且只有当它们的形式为.ArgsEnv(它们也可以在.GenericArgsEnv中)时才显示。现在固定在R-devel。错误报告最好直接引入R bugzilla(R-devel邮件列表工作)。

相关问题