2014-09-25 45 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郵件列表工作)。

相關問題