2011-10-09 14 views
5

मैं रूबी की मूल बातें सीख रहा हूं (बस शुरू करना), और मैं Hash.[] method पर आया। यह थोड़ा सोचा के साथरूबी सिंटेक्टिक चीनी के लिए "नियम" हैं?

a = ["foo", 1, "bar", 2] 
=> ["foo", 1, "bar", 2] 
Hash[*a] 
=> {"foo"=>1, "bar"=>2} 

साथ पेश किया गया था, मैं पता लगा कि Hash[*a]Hash.[](*a) या Hash.[] *a के बराबर है। मेरा सवाल यह है कि ऐसा क्यों है। यह क्या है जो आपको स्क्वायर ब्रैकेट के अंदर *a डालने देता है, और क्या वहां और कब "इसे" इस्तेमाल किया जा सकता है, इसके लिए कोई नियम है?

संपादित करें: मेरा शब्द कुछ भ्रम पैदा कर रहा है। मैं सरणी विस्तार के बारे में नहीं पूछ रहा हूँ। मै समझ गया। मेरा सवाल मूल रूप से है: यदि [] एक विधि का नाम है, तो ब्रैकेट के अंदर तर्क डालना ठीक क्यों है? ऐसा लगता है कि लगभग - लेकिन काफी नहीं - जैसे कि आपके पास Foo.dood विधि है, और आप इसे "hey" स्ट्रिंग पास करना चाहते हैं, तो आप Foo.do"hey"od लिख सकते हैं।

+0

मुझे एक विधि आमंत्रण में '* ए' पर ध्यान केंद्रित करने वाले बहुत सारे उत्तर दिखाई देते हैं। हालांकि, अन्य प्रोडक्शंस को संबोधित करना अच्छा लगेगा, जैसे कि '[1, * ए]' काम करता है "अपेक्षित" (जो '[1, ए]' से भिन्न परिणाम उत्पन्न करता है और क्यों '[* ए, 1] 'अमान्य है। यह देखना भी अच्छा होगा कि कैसे "विभाजन" असाइनमेंट से संबंधित है और यह रूबी के असाइनमेंट-अपघटन के साथ कैसे बातचीत कर सकता है ... शायद तर्कसंगत रूप से एक अलग SO प्रश्न पूरी तरह से ;-) यह वास्तव में अच्छा होगा * अगर वहां था अर्ध औपचारिक रूबी विनिर्देश। अर्ध-विनिर्देशों के लिंक उत्तर बेहतर बनाएंगे। –

+0

@pst: अच्छे प्रश्न। यदि आप इसके बारे में एक नया SO सवाल पूछते हैं, तो यहां लिंक पोस्ट करें ताकि मैं इसका अनुसरण कर सकूं। –

+0

ध्यान दें कि इसका उपयोग करने का सामान्य तरीका जोड़ों की एक सरणी भेजना है: हैश [[[key1, value1], [key2, value2]]] – tokland

उत्तर

3

कि माणिक आप एक विशेष में फोन की सुविधा देता है एक जोड़े तरीकों रहे हैं मार्ग। जैसा कि आपने उल्लेख किया है, [] हैं, +, -, == और जैसा कि किसी और ने बताया है।एक अन्य महत्वपूर्ण उदाहरण फॉर्म something=(value) के तरीके हैं जिन्हें object.something = value के साथ बुलाया जा सकता है और आपको एक्सेसर्स बनाने की अनुमति मिलती है।

संपादित करें:

मज़ेदार तथ्य 1: यदि आप एक + विधि को परिभाषित आप मुक्त करने के लिए += मिलता है।

मज़ेदार तथ्य 2: यदि आप एक <=> परिभाषित आप सभी तुलना तरीकों, Comparable

+0

तो क्या इस "विशेष" सामान में कहीं भी एक सूची है? –

+1

आईएमएचओ अनावश्यक डाउनवोट का मुकाबला करने के लिए ऑपरेटर की एक सूची है जिसे [यहां] (http://www.zenspider.com/Languages/Ruby/QuickRef.html#28) –

4

Hash["a", "b", "c", "d"]Hash.[]("a", "b", "c", "d") के बराबर है। रूबी में लगभग हर चीज एक विधि कॉल है। 5 + 55.+(5) के बराबर है।

a = ["a", "b", "c", "d"]Hash[*a]Hash["a", "b", "c", "d"] के बराबर है, जो बदले में Hash.[]("a", "b", "c", "d") के बराबर है। इसी तरह, foo(*a)foo("a", "b", "c", "d") के समतुल्य है इसे विस्फोट ऑपरेटर कहा जाता है, और एक विधि को एक सरणी भेजने की अनुमति देता है और विधि में एक तर्क के रूप में सरणी में प्रत्येक आइटम को विधि में सरणी भेजने के बजाय पहली तर्क के रूप में गिनती है।


विशेष रूप से अपने अद्यतन उत्तर देने के लिए, आप कोष्ठक के अंदर *a डाल देता है कि कुछ खास नहीं है। एक सामान्य विधि कॉल के लिए ब्रैकेट सिर्फ चीनी है। यहां केवल "विशेष" चीज यह है कि आप किसी भी विधि में *a भेज सकते हैं।

+0

तो [सभी] उन जगहों पर क्या हैं जहां विभाजन-विस्तार की अनुमति है? (विधि आमंत्रण AFAIK से संबंधित नहीं है कम से कम एक और।) –

+0

अद्यतन? मैंने कुछ भी अपडेट नहीं किया है। तो क्या आप कह रहे हैं कि कहीं भी स्क्वायर ब्रैकेट्स रूबी में एक विधि नाम के रूप में होते हैं, तो आप तर्क सूची रखने के लिए ब्रांड्स का उपयोग ब्रैकेट का उपयोग कर सकते हैं? I.e कोई पुरानी विधि 'फू। []' तर्क लेते हुए ए, बी, और सी को 'फू [ए, बी, सी]' के रूप में लिखा जा सकता है? क्या यह सिर्फ एक जादुई भाषा सुविधा है? –

+0

यह सही है। नामित एक विधि [] को 'my_obj [foo]' चीनी के साथ बुलाया जा सकता है। [My = नाम की एक विधि 'my_obj [foo] = bar' के साथ बुलाया जा सकता है। यह 'my_obj में बदल जाता है। [] = (Foo, bar)'। यह 'हैश' उदाहरणों के वाक्यविन्यास को शक्ति देता है। वहां 'डिर ["ग्लोब पैटर्न"] भी है, जो' डिर। [] ("ग्लोब पैटर्न") में बदल जाता है। –

0

*<Array> विधि रूबी को सरणी के रूप में सरणी नहीं लेने के लिए बताती है, लेकिन 'विस्तारित' सरणी का उपयोग करने के लिए।

उदाहरण:

def test(*argv) 
    p argv 
end 

a = [1,2,3] 
test(a) #-> [[1, 2, 3]] 
test(*a) #-> [1, 2, 3]  

test(a) साथ सरणी एक एक और केवल पैरामीटर है।

test(*a) के साथ पैरामीटर की सूची के रूप में उपयोग किया जाता है।


आपके मामले में

a = ["foo", 1, "bar", 2] 
Hash[*a] 

Hash[*a] के समान है किया जाएगा

Hash[["foo", 1, "bar", 2]] 
+0

ठीक है, लेकिन यह कहां अनुमति है या अनुमति नहीं है? (उदाहरण के लिए उत्पादन नियम क्या हैं?) –

+0

उस विधि पर निर्भर करें जहां आप इसका उपयोग करते हैं। 'ए' एक सरणी है,' * ए 'पैरामीटर की एक सूची है। तो, सवाल नहीं है, '* ए 'की अनुमति है, लेकिन: क्या मुझे पैरामीटर के रूप में सरणी की आवश्यकता है, या मुझे पैरामीटर सूची की आवश्यकता है। – knut

+0

मेरा प्रश्न सरणी विस्तार के बारे में नहीं है। यह '[]' विधि के बारे में है और विशेष रूप से उन ब्रैकेट्स के अंदर तर्क डालना ठीक क्यों है। –

2

के सौजन्य से मुझे लगता है कि रूबी के वाक्य रचना YARV रूबी के लिए parse.y में परिभाषित किया गया है मिलता है।

+0

+1 ओवरराइड किया जा सकता है। –

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