2013-02-14 38 views
21

मैंने this basic question को फिर से नामित वस्तुओं और @Shane के उत्तर पर पढ़ा, मुझे आलसी मूल्यांकन के लिए इंगित किया। अब मुझे आश्चर्य है कि assign का मूल्यांकन भी आलसी है। बस यहाँ की तरह:आर में आलसी मूल्यांकन प्रभावित है?

assign("someNewName",someOldObject) 
rm(someOldObject) 

कारण है कि मैं इस बारे में चिंता निम्नलिखित उपयोग मामला है: मान लें मुझे मिल गया 10K + आर वस्तुओं, जिनमें से प्रत्येक दो विशेषताओं originalName और additionalName कहा जाता है। अब मैं एक ऐसा फ़ंक्शन लिखना चाहता हूं जो उपयोगकर्ता को इन दो विशेषताओं को खोए बिना उपयोगकर्ता को एक नाम से दूसरी तरफ स्विच कर दे। लगभग इस तरह ...

संपादित करें: @ हैडली के इनपुट के आधार पर मैंने अपना कोड बदल दिया है।

switchObjectName <- function(x) { 
    n1 <- attributes(x)$originalName 
    n2 <- attributes(x)$additionalName 
    objName <- deparse(substitute(x)) 
    if(objName == n1) { 
    delayedAssign(n2,x,assign.env=.GlobalEnv) 
    } else { 
    delayedAssign(n1,x,assign.env=.GlobalEnv) 
    } 
    rm(list=c(objName),envir=.GlobalEnv)  
} 

यह अच्छी तरह से काम करता है, लेकिन मैं काफी कुछ rm बयान सही पाने के लिए हमें समस्या हुई। मैंने rm(objName,envir=.GlobalEnv) की कोशिश की लेकिन इसे काम पर नहीं मिला, हालांकि objName निश्चित रूप से एक चरित्र कारण है क्योंकि यह deparse(substitute(x) का परिणाम है।

+12

यदि मैं आपके प्रश्न को सही तरीके से समझता हूं, तो 'देरी से पूछें', https://github.com/hadley/pryr/blob/master/R/assign-delayed.r और "असाइनमेंट: मानों के लिए बाध्यकारी नाम" अनुभाग देखें https://github.com/hadley/devtools/wiki/environments – hadley

+0

एक बार और धन्यवाद। विशेष रूप से आपके विकी में अध्याय के सूचक ने वास्तव में क्या चल रहा है यह समझने में बहुत मदद की। वास्तव में सही संकेत वास्तव में था। –

उत्तर

5

आर भाषा में आमतौर पर मूल्य अर्थशास्त्र है। असाइनमेंट x <- y का अर्थ है कि x और y एक ही ऑब्जेक्ट की स्वतंत्र प्रतियां (y और x पर अपडेट स्वतंत्र होंगे)। x <- y का एक निष्पक्ष कार्यान्वयन हमेशा x के लिए स्मृति आवंटित करेगा और इसमें y पूरी तरह से कॉपी करेगा। जीएनयू-आर इसके बजाय कॉपी-ऑन-राइट मैकेनिज्म का उपयोग करता है, यह प्रतिलिपि तब तक स्थगित कर देगा जब तक कोई अपडेट वास्तव में नहीं होता है, जो ऐसा नहीं होने पर स्मृति/निष्पादन समय बचाता है। आर उपयोगकर्ताओं को इस अनुकूलन के बारे में नहीं पता है, यह पूरी तरह से पारदर्शी है (कुछ दुर्लभ मामलों को छोड़कर जैसे स्मृति त्रुटियों को छोड़कर)। यह तंत्र x <- y और assign("x", y) के रूप में लिखित असाइनमेंट पर लागू होता है।

आलसी मूल्यांकन भाषा के डिजाइन का हिस्सा है और आर उपयोगकर्ताओं/प्रोग्रामर के लिए दृश्यमान है। एक समारोह में तर्क के रूप में अभिव्यक्तियां उत्तीर्ण की गईं, उदा। foo(ls()) में उत्तीर्ण अभिव्यक्ति ls() है, जिसे आलसी मूल्यांकन किया जाता है, केवल तभी किया जाता है जब बुलाए गए फ़ंक्शन के कार्यान्वयन की आवश्यकता होती है।

delayedAssign एक निम्न-स्तरीय फ़ंक्शन है, जो आर उपयोगकर्ताओं/प्रोग्रामर के लिए दृश्यमान है, लेकिन यह वास्तव में केवल पैकेजों की आलसी लोडिंग के लिए उपयोग किया जाता है और उपयोगकर्ता कार्यक्रमों में इसकी आवश्यकता नहीं होनी चाहिए। delayedAssign एक चर के मान की गणना करने के लिए एक अभिव्यक्ति निर्दिष्ट करने की अनुमति देता है; गणना केवल तभी हो जाएगी जब वैरिएबल पहली बार पढ़ा जाए।

तो, सवाल का जवाब देने के लिए, आर में एक असाइनमेंट हमेशा 'आलसी' होता है जिसमें कॉपी-ऑन-राइट तंत्र का उपयोग किया जाता है। असाइनमेंट के दाईं ओर की गणना भी आलसी हो सकती है (delayedAssign का उपयोग करके), लेकिन उपयोगकर्ता प्रोग्राम द्वारा इसकी आवश्यकता/उपयोग नहीं की जानी चाहिए।

मुझे लगता है कि चर के 'नामकरण' के लिए, delayedAssign (क्योंकि दाईं ओर की तरफ गणना नहीं की जाती है) का उपयोग करने की आवश्यकता नहीं है। यह स्थिति को और अधिक जटिल बनाता है और पुस्तक-रखरखाव delayedAssign के कारण प्रदर्शन ओवरहेड होने की संभावना है। अगर मैं चर का नाम बदलना चाहता हूं तो मैं सामान्य असाइनमेंट का उपयोग करूंगा।

कोड स्पष्टता के लिए, मैं भी जब भी संभव हो पर्यावरण से चर हटाने और यहां तक ​​कि एक समारोह से वैश्विक पर्यावरण में असाइन करने से बचने की कोशिश करता हूं, उदाहरण के लिए मैं बस एक नई सूची तैयार करूंगा और इसमें नए बाइंडिंग (चर) डालेंगे।

जीएनयू-आर में वर्तमान कार्यान्वयन के साथ कॉपी-ऑन-राइट तंत्र का उल्लेख करने के बाद, वर्णित समाधानों में से कोई भी संभावित रूप से स्मृति प्रतिलिपि का कारण बनता है जो आवश्यक नहीं होगा कि चर का नाम बदल दिया गया हो। आर स्तर पर इससे बचने का कोई तरीका नहीं है।