आर

2012-09-26 10 views
36

में संकुल में वैश्विक चर आर। मैं आर में एक पैकेज विकसित कर रहा हूं। मेरे पास कार्यों का एक गुच्छा है, उनमें से कुछ को कुछ वैश्विक चर की आवश्यकता है। मैं संकुल में वैश्विक चर का प्रबंधन कैसे करूं?आर

मैंने पर्यावरण के बारे में कुछ पढ़ा है, लेकिन मुझे नहीं पता कि यह कैसे काम करेगा, अगर यह चीजों के बारे में जाने का तरीका भी है।

+0

क्या आप अपनी विशिष्ट स्थिति पर और विस्तार कर सकते हैं? फिर हम आपको विकल्पों को खोजने में मदद कर सकते हैं, अधिमानतः ... –

+0

http://stackoverflow.com/questions/5526322/examples-of-the-perils-of-globals-in-r-and-stata –

उत्तर

9

सामान्य वैश्विक चर में बुरा है। अंतर्निहित सिद्धांत वे बुरा क्यों हैं कि आप अपने पैकेज में इंटरकनेक्शन को कम करना चाहते हैं। इन इंटरकनेक्शन अक्सर कार्यों के साइड इफेक्ट्स का कारण बनते हैं, यानी यह न केवल इनपुट तर्कों पर निर्भर करता है कि नतीजा क्या है, बल्कि कुछ वैश्विक चर के मूल्य पर भी निर्भर करता है। खासकर जब कार्यों की संख्या बढ़ती है, तो सही और नरक को डीबग करना मुश्किल हो सकता है।

आर में वैश्विक चर के लिए यह SO post देखें।

अपनी टिप्पणी के जवाब में संपादित करें: एक विकल्प केवल उन कार्यों के लिए आवश्यक जानकारी को पास करने के लिए हो सकता है, जिनकी आवश्यकता है। आप एक नया वस्तु जो इस जानकारी शामिल बना सकते हैं:

token_information = list(token1 = "087091287129387", 
         token2 = "UA2329723") 

और एक तर्क के रूप में यह है करने के लिए सभी कार्यों कि इस जानकारी की आवश्यकता की आवश्यकता होती है:

do_stuff = function(arg1, arg2, token) 
do_stuff(arg1, arg2, token = token_information) 

इस तरह से यह कोड से स्पष्ट है कि फ़ंक्शन में टोकन जानकारी की आवश्यकता होती है, और आप फ़ंक्शन को अपने आप डीबग कर सकते हैं। इसके अलावा, फ़ंक्शन का कोई साइड इफेक्ट नहीं होता है, क्योंकि इसका व्यवहार पूरी तरह से इसके इनपुट तर्कों द्वारा निर्धारित होता है। एक सामान्य उपयोगकर्ता स्क्रिप्ट कुछ ऐसा दिखाई देगी:

token_info = create_token(token1, token2) 
do_stuff(arg1, arg2, token_info) 

मुझे आशा है कि इससे चीजों को और स्पष्ट हो जाएगा।

+2

उत्तर के लिए धन्यवाद। मुझे प्रोग्रामिंग के साथ अनुभव है, और पता है कि वैश्विक चर आमतौर पर एक नोगो हैं। हालांकि, मैं इस सेवा से जुड़े रहने के लिए, एक सेवा के लिए एक एपीआई पहुंच स्थापित कर रहा हूं, कार्यों को कुछ टोकन की आवश्यकता है। इन टोकन को सभी कार्यों द्वारा एक्सेसिबल होना चाहिए, जो मैंने साथ आया है, एक डेटा बना रहा है। डेटा डेटा जो इस डेटा को स्टोर करता है, लेकिन यह एक बुरा विचारक जैसा लगता है। – Rimbaud

+3

सामान्य आर पैटर्न किसी प्रकार की 'हैंडल' ऑब्जेक्ट है जो आपके टोकन रखता है, और अपने कार्यों को संभालने के लिए पास करता है। यह आपको विभिन्न टोकन के साथ कई समवर्ती सत्र भी देता है। उदाहरण के लिए, डेटाबेस पहुंच के लिए यह पैटर्न है। – Spacedman

+0

@ स्पेस्डमैन +1 जो मैंने सोचा था –

13

आप सेट कर सकते हैं एक option, जैसे

options("mypkg-myval"=3) 
1+getOption("mypkg-myval") 
[1] 4 
+1

यह कहां से संग्रहीत किया जाएगा? – Rimbaud

+0

@ रिमबाउड 'बेस' पैकेज में स्थित 'ओप्शन' नामक एक पार्लिस्ट में। – James

+0

यह आर सत्र के लिए वैश्विक विकल्प सूची में संग्रहीत है जिसमें पैकेज लोड किया गया है। 'विकल्प 'देखें। –

2

प्रश्न स्पष्ट नहीं है:

  • बस एक आर प्रक्रिया या कई?

  • बस एक मेजबान, या कई मशीनों पर?

  • क्या उनके बीच आम फ़ाइल पहुंच है या नहीं?

जटिलता के बढते क्रम में, मैं एक फ़ाइल, एक SQLite बैकएंड का उपयोग करेंगे RSQlite पैकेज या (मेरी पसंदीदा :) rredis पैकेज के माध्यम से करने के लिए सेट करने के लिए/एक Redis उदाहरण से पढ़ें।

37

आप पर्यावरण के माध्यम से पैकेज स्थानीय चर का उपयोग कर सकते हैं। ये चर पैकेज में कई फ़ंक्शंस के लिए उपलब्ध होंगे, लेकिन उपयोगकर्ता (आसानी से) उपयोगकर्ता तक पहुंच योग्य नहीं होंगे और उपयोगकर्ता कार्यक्षेत्र में हस्तक्षेप नहीं करेंगे। एक त्वरित और सरल उदाहरण है:

pkg.env <- new.env() 

pkg.env$cur.val <- 0 
pkg.env$times.changed <- 0 

inc <- function(by=1) { 
    pkg.env$times.changed <- pkg.env$times.changed + 1 
    pkg.env$cur.val <- pkg.env$cur.val + by 
    pkg.env$cur.val 
} 

dec <- function(by=1) { 
    pkg.env$times.changed <- pkg.env$times.changed + 1 
    pkg.env$cur.val <- pkg.env$cur.val - by 
    pkg.env$cur.val 
} 

cur <- function(){ 
    cat('the current value is', pkg.env$cur.val, 'and it has been changed', 
     pkg.env$times.changed, 'times\n') 
} 

inc() 
inc() 
inc(5) 
dec() 
dec(2) 
inc() 
cur() 
+7

यह एक उपयोगी अभ्यास है, जिसके लिए मैं इसे जोड़ता हूं, एक स्थिर उपाय के रूप में वातावरण को परिवर्तनीय कंटेनर के रूप में बनाते समय, किसी को सामान्य रूप से माता-पिता को 'blankenv()' पर सेट करना चाहिए, ताकि गलती से उच्च मूल्यों को चुनने के खिलाफ सुरक्षा हो सके। खोज पथ: इस प्रकार 'new.env (parent = blankenv()) ', केवल' new.env() 'के बजाय। – egnha