2012-01-06 28 views
10

जब कोई रूबी में किसी विधि के लिए तर्क पारित करता है तो मुझे क्या लगता है, इस पर कोई भी विस्तार, सही या सत्यापित कर सकता है। क्या इनमें से कोई भी मुद्दा गलत है? क्या मुझे कोई टुकड़ा याद आ रहा है?तर्क या मूल्य के अनुसार विधियों को पारित तर्क हैं?

  • रूबी में सब कुछ एक वस्तु है।
  • वेरिएबल ऑब्जेक्ट्स
  • (किसी विधि में एक चर में गुजरते समय) के संदर्भ हैं: वैरिएबल को पकड़ने वाली विधि में पैरामीटर उस विधि के लिए एक स्थानीय चर है। पैरामीटर (स्थानीय चर) अब भी एक ही वस्तु का संदर्भ है।
  • मैं ऑब्जेक्ट (जगह में) बदल सकता हूं और जब विधि का दायरा निकलता है तो यह परिवर्तन होगा। विधि स्कोप के बाहर इस ऑब्जेक्ट का संदर्भ देने वाला कोई भी चर प्रतिबिंबित करेगा कि ऑब्जेक्ट बदल दिया गया है।
  • उस पैरामीटर (स्थानीय चर) के लिए एक नया असाइनमेंट मूल ऑब्जेक्ट को नहीं बदलता है, इस प्रकार विधि का दायरा छोड़ने पर इसका कोई संदर्भ अपरिवर्तित रहेगा।
  • यदि मैं एक इंटेगर का संदर्भ देने वाली विधि में एक चर पारित कर रहा हूं तो प्रभावी ढंग से कोई तरीका नहीं है कि एक बार जब यह विधि निकल जाए तो मैं उस चर को एक नया इंटीजर संदर्भित कर सकता हूं।

क्या कोई तरीका है जो एक पैरामीटर को एक इंटीजर के रूप में लेता है, कुछ सामान करता है, और शायद साइड इफेक्ट के रूप में मूल्य बदलता है, जिससे विधि बाहर निकलने के बाद उस बदलाव को प्रतिबिंबित किया जाता है। शायद मैं सिर्फ "रूबी रास्ता" नहीं सोच रहा हूं।

+2

संभव डुप्लिकेट [शून्य फू (int और x) -> रूबी? संदर्भ द्वारा पूर्णांक पास करना?] (Http://stackoverflow.com/questions/2650634/void-fooint-x-ruby-passing-integers-by-reference) – derekerdmann

उत्तर

20

रूबी में सब कुछ एक वस्तु है।

पर्याप्त बंद करें। जब एक चर का मूल्यांकन किया जाता है, यह वस्तु है कि यह वर्तमान में "नाम" का मूल्यांकन करता है:

चर वस्तुओं

नहीं, एक चर "नाम" एक वस्तु के लिए संदर्भ। आंतरिक रूप से यह किसी ऑब्जेक्ट पर "पॉइंटर संग्रहीत" (या समतुल्य तंत्र) द्वारा किया जाता है। (हालांकि एक कार्यान्वयन हमेशा संकेत का उपयोग करने की जरूरत नहीं है: रूबी एमआरआई में, उदाहरण के लिए, Fixnum मान वास्तव में बिना मौजूद एक वास्तविक वस्तु।)

(जब एक विधि में एक चर में गुजर): पैरामीटर वैरिएबल को पकड़ने वाली विधि में उस विधि के लिए एक स्थानीय चर है। पैरामीटर (स्थानीय चर) अब भी एक ही वस्तु का संदर्भ है।

नहीं। ऊपर देखें। हालांकि, दोनों चर अब एक ही ऑब्जेक्ट का नाम (या "मूल्यांकन") करते हैं। मापदंडों आंतरिक पारित कर रहे हैं Call-by-Value का उपयोग कर - जो है, आंतरिक, वस्तुओं के लिए संकेत पारित कर रहे हैं - हालांकि रूबी Call-by-Object-Sharing अर्थ विज्ञान है, जो एक अवधि मैं के रूप में मुझे लगता है यह संक्षेप व्यवहार का वर्णन करता है बढ़ावा देने की कोशिश है।

मैं ऑब्जेक्ट (जगह में) बदल सकता हूं और विधि स्कोप बाहर निकलने पर यह परिवर्तन होगा। विधि स्कोप के बाहर इस ऑब्जेक्ट का संदर्भ देने वाला कोई भी चर प्रतिबिंबित करेगा कि ऑब्जेक्ट बदल दिया गया है।

हां, एक वस्तु स्वयं ही है। यदि आप को पर ऑब्जेक्ट करते हैं, तो आप को म्यूटेट करते हैं जो ऑब्जेक्ट को ऑब्जेक्ट करता है। लेकिन ध्यान दें: कोई भी चर बदल नहीं है। अंदर और बाहरी चर दोनों अभी भी नाम (या "मूल्यांकन") समान ऑब्जेक्ट होगा।

उस पैरामीटर (स्थानीय चर) के लिए एक नया असाइनमेंट मूल ऑब्जेक्ट को नहीं बदलता है, इस प्रकार विधि के दायरे को छोड़ने पर इसका कोई संदर्भ अपरिवर्तित रहेगा।

सही। यदि आप स्थानीय चर के लिए एक अलग मान निर्दिष्ट करते हैं तो आप इसे स्थानीय चर, एक अलग वस्तु नाम देते हैं। रूबी Call-by-Reference है इसलिए कॉलिंग संदर्भ में चर बदल दिया नहीं गया है।

यदि मैं एक इंटीजर का संदर्भ देने वाली विधि में चर बदल रहा हूं तो प्रभावी ढंग से कोई तरीका नहीं है कि एक बार जब यह विधि निकल जाए तो मैं उस चर को एक नया इंटीजर संदर्भित कर सकता हूं?

चर कभी पास नहीं हुए। वैरिएबल का मूल्यांकन उन वस्तुओं के लिए किया जाता है जिन्हें वे नाम देते हैं और उन वस्तुओं को पास किया जाता है। वैसे भी, हम जानते हैं कि:

  1. रूबी नहीं कॉल-दर-संदर्भ और है;
  2. पूर्णांकों (Fixnums)

इस प्रकार अपरिवर्तनीय हैं:

x = 1 
y.foo(x) 

कर सकते हैं कभी नहीं परिवर्तन क्या x नाम, और न ही यह भी वस्तु x नाम की सामग्री को बदल सकते हैं (क्योंकि यह अच्छी तरह से अपरिवर्तनीय)। यहां तक ​​कि अगर उद्देश्य यह है कि x नामित परिवर्तनशील था, विधि बदल क्या वस्तु x नाम नहीं हो सकता है: यह केवल उत्परिवर्तित उद्देश्य यह है कि x के मूल्यांकन से हुई हो सकता था।

हैप्पी कोडिंग।


अब, रूबी तरीका - मेरी किताब में - बेहतर लाभ मूल्य कि सभी नए राज्य को घेर लिया उपयोग करने के लिए होगा, और फोन करने वाले डाल देना, जहां यह जाना :-) की जरूरत है

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


एक बंद नोट के रूप में: रूबी बंद की अवधारणा का समर्थन करता है, तो यह एक lexically-दायरे वाले ढंग में संभव है:

x = 1; (lamb­da {|a| x = a}).c­all(2); x // => 2 

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

+0

शानदार उत्तर के लिए धन्यवाद! "नाम" बनाम "संदर्भ" अर्थशास्त्र के रूप में, मुझे अंतर समझ में नहीं आता है। एक ऑब्जेक्ट "नाम" एक ऑब्जेक्ट ... यह ऑब्जेक्ट को "संदर्भ" देता है। क्या किसी ऑब्जेक्ट को "नाम" करना संभव है और इसे "संदर्भ" नहीं है? क्या किसी ऑब्जेक्ट को "संदर्भ" होना संभव है और इसे "नाम" नहीं है? क्या ऐसे उदाहरण हैं जो आप इस रिश्ते को चित्रित कर सकते हैं, और शायद एक और भाषा में एक उदाहरण जहां हुड के नीचे चीजें अलग-अलग होती हैं? मैं सिर्फ यह नहीं देखता कि किसी ऑब्जेक्ट को "नामकरण" और ऑब्जेक्ट "संदर्भ" अलग-अलग चीजें हैं। – slindsey3000

+0

मुझे लगता है कि शब्द अंतर-परिवर्तनीय हैं और "नामकरण" किसी ऑब्जेक्ट का अर्थ है "संदर्भ", और एक वस्तु का संदर्भ "यह दर्शाता है कि आपने इसे" नाम "दिया है। – slindsey3000

+1

@ slindsey3000 मैं शब्द "नाम" पसंद करता हूं - जो कि पायथन में अधिक प्रचलित है - ठीक है क्योंकि यह * संदर्भ "या" किसी भी प्रकार का उपयोग नहीं करता है। "[द्वारा पास] संदर्भ [es]" शब्दों का एक अधिभारित सेट है। लेकिन हाँ, बोलचाल से वे कई बार इलाज किया जाता है। हालांकि, जब केवल "नाम" का उपयोग करते हैं और चर के मूल्यांकन के परिणाम के साथ अपने रिश्ते को परिभाषित करते हैं, तो कई अन्य भाषाओं में मान/चर के बारे में बात करने के लिए दायरे का विस्तार करते समय संघर्ष से बचा जाता है। सी ++ में "int x = 1; // x संदर्भ 1" कहने के लिए, बहुत गलत होगा। "नामकरण" की अवधारणा अधिक सामान्य (और सीमा) है। –