2014-09-25 23 views
12

मैंने देखा है कि जब मैं पर पर प्राइमेटिव फ़ंक्शंस के कुछ पर कॉल करता हूं, बाइट-कोड भी दिखाए जाते हैं। लेकिन अन्य प्राइमेटिव्स पर, कोई बाइट-कोड प्रकट नहीं होता है। उदाहरण के लिएकुछ प्राइमेटिव्स के पास बाइट कोड क्यों हैं और कुछ नहीं करते हैं?

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

वह क्यों है?

पहले मैंने सोचा कि यह ... तर्क से संबंधित हो सकता है, लेकिन निम्नलिखित सिद्धांत को अस्वीकार करता है।

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

यह मुझे भ्रमित कर रहा है कि बाइट-कोड केवल इनमें से कुछ में दिखाई देता है, न कि दूसरों में। मैं हमेशा इस धारणा के तहत रहा हूं कि सभी प्राइमेटिव विशेष हैं और वे सभी एक ही "गुण" साझा करते हैं (एक बेहतर शब्द की कमी के लिए, वास्तविक आर गुण नहीं)।

+0

मुझे लगता है कि प्रिंटिंग अंतर अधिक ऐतिहासिक कारणों के लिए है। कंसोल प्रिंटिंग के लिए 'args' का अधिक उपयोग किया जाता है, शायद अधिक सुसंगत आउटपुट प्राप्त करने के लिए' फॉर्मल्स 'का उपयोग करें। – agstudy

उत्तर

9

जैसा कि अजीब ने नोट किया, यह 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 यह उल्लेख नहीं है। मुद्रित होने पर प्राथमिक कार्य बाइटकोड संदेश नहीं दिखाते हैं, और केवल कभी-कभी तर्क के साथ बुलाए जाने पर बाइटकोड संदेश दिखाते हैं।

+3

सरल स्पष्टीकरण: यह 'args() 'में एक बग है। इसे कभी भी बाइटकोड संकलन स्थिति प्रदर्शित नहीं करना चाहिए, क्योंकि यह किसी फ़ंक्शन की तर्क सूची की संपत्ति नहीं है। – hadley

1

रिपोर्ट के लिए धन्यवाद। यह व्यवहार अनजान है (जैसा कि हैडली कहते हैं, एक बग), यह आंतरिक रूप से संगत नहीं है क्योंकि बाइटकोड पता केवल बिल्टिन और विशेष के लिए प्रदर्शित होता है और केवल तभी जब उनके फॉर्म .ArgsEnv में होते हैं (वे .GenericArgsEnv में भी हो सकते हैं)। अब आर-डेवेल में तय किया गया है। बग रिपोर्ट्स आर बगज़िला में सही निर्देशित हैं (आर-डेवेल मेलिंग सूची भी काम करती है)।

संबंधित मुद्दे

 संबंधित मुद्दे