2009-03-04 12 views
418

रूबी में कुछ तरीकों में एक प्रश्न चिह्न (?) है जो include? जैसे प्रश्न पूछता है जो पूछता है कि प्रश्न में वस्तु शामिल है या नहीं, तो यह एक सत्य/झूठा लौटाता है।रूबी विधियों में विस्मयादिबोधक चिह्न क्यों उपयोग किए जाते हैं?

लेकिन कुछ विधियों में विस्मयादिबोधक चिह्न क्यों हैं (!) जहां अन्य नहीं करते हैं?

इसका क्या अर्थ है?

+15

पर्याय: बैंग, विस्मयादिबोधक चिह्न – prusswan

+15

स्वीकार किए जाते हैं जवाब http://stackoverflow.com/a/612653/109618 को बदला जाना चाहिए। देखें http://www.wobblini.net/bang.txt और http://www.ruby-forum.com/topic/176830#773946 - "बैंग साइन का अर्थ है" बैंग संस्करण अधिक गैर- बैंग समकक्ष; देखभाल के साथ संभाल लें "" -मैट्स –

+2

** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** अफसोस की बात है कि वे नहीं हैं, और इसलिए यह याद करने में एक निराशाजनक व्यायाम बन जाता है कि क्या है और क्या म्यूटेबल नहीं है। –

उत्तर

498

सामान्यतः, ! में समाप्त होने वाली विधियों से संकेत मिलता है कि विधि उस ऑब्जेक्ट को संशोधित करेगी जिसे इसे पर बुलाया गया है। रूबी इन्हें "खतरनाक तरीकों" के रूप में कॉल करता है क्योंकि वे उस स्थिति को बदलते हैं जिसके बारे में किसी और का संदर्भ हो सकता है। यहाँ तार के लिए एक सरल उदाहरण है:

foo = "A STRING" # a string called foo 
foo.downcase!  # modifies foo itself 
puts foo   # prints modified foo 

हो जाएगा ताकि उत्पादन:

a string 

मानक पुस्तकालयों में, स्थानों के एक बहुत आप ! साथ इसी नाम के तरीकों की जोड़ी दिखाई देगी, एक देखते हैं और बिना एक। बिना किसी को "सुरक्षित तरीके" कहा जाता है, और वे पर लागू परिवर्तनों के साथ मूल की प्रतिलिपि वापस लेते हैं, प्रतिलिपि, कैली अपरिवर्तित के साथ। यहाँ ! के बिना एक ही उदाहरण है:

foo = "A STRING" # a string called foo 
bar = foo.downcase # doesn't modify foo; returns a modified string 
puts foo   # prints unchanged foo 
puts bar   # prints newly created bar 

यह आउटपुट:

A STRING 
a string 

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

+2

बाहर निकलने के बाहर निकलने जैसे मामलों भी हैं! और (रेल में) बनाम बचाओ बचाओ! –

+13

बहुत सावधान रहें - कई छोटे पुस्तकालय इस सम्मेलन का पालन नहीं करते हैं।अगर अजीब चीजें हो रही हैं, तो अक्सर obj.hhatever जगह बदल रहा है! obj = obj.hhatever के साथ! इसे ठीक करता है अधिक निराश। –

+73

बैंग का उपयोग विधियों के लिए भी किया जाता है जो बिना किसी विधि के अपवाद को बढ़ाते हैं, उदाहरण के लिए: 'save'' और 'save!' 'ActiveRecord' – ecoologic

23

! आमतौर पर इसका मतलब है कि विधि परिणाम लौटने के बजाय ऑब्जेक्ट पर कार्य करती है। Programming Ruby:

"खतरनाक" या रिसीवर को संशोधित करने वाले तरीके, पीछे की ओर "!" के साथ नामित किए जा सकते हैं।

56

यह नामकरण सम्मेलन Scheme से उठाया गया है।

1.3.5 नामकरण सम्मेलनों

परंपरा के मुताबिक, प्रक्रियाओं के नाम है जो हमेशा एक बूलियन मान वापसी आमतौर पर ``? '' में खत्म हो। ऐसी प्रक्रियाएं भविष्यवाणी कहलाती हैं।

परंपरा के मुताबिक, जो पहले आवंटित स्थानों (खंड 3.4 देखें) में मान संग्रहीत प्रक्रियाओं के नाम आमतौर पर ``! '' में खत्म हो। ऐसी प्रक्रिया उत्परिवर्तन प्रक्रियाओं कहा जाता है। सम्मेलन द्वारा, उत्परिवर्तन प्रक्रिया द्वारा लौटाए गए मान को निर्दिष्ट नहीं किया गया है।

+1

इस उत्तर में +1 के बाद से एक दस्तावेज है जो उचित स्पष्टीकरण देता है! उपयोग। वास्तव में अच्छा जवाब स्टीवन – DavidSilveira

+0

धन्यवाद @ डेविड सिल्वीरा! –

118

विस्मयादिबोधक बिंदु का अर्थ कई चीजें हैं, और कभी-कभी आप "यह खतरनाक है, सावधान रहें" के अलावा अन्य से कुछ नहीं बता सकते हैं।

के रूप में अन्य लोगों ने कहा, मानक तरीकों में यह अक्सर एक विधि है जो अपने आप उत्परिवर्तित करने के लिए एक वस्तु का कारण बनता है इंगित करने के लिए प्रयोग किया जाता है, लेकिन हमेशा नहीं। ध्यान दें कि कई मानक तरीकों उनके रिसीवर बदल कि और एक विस्मयादिबोधक बिंदु (pop, shift, clear) की जरूरत नहीं है, और विस्मयादिबोधक अंक के साथ कुछ तरीकों उनके रिसीवर (exit!) नहीं बदलते। उदाहरण के लिए this article देखें।

अन्य पुस्तकालयों इसे दूसरे तरीके से उपयोग कर सकते हैं। रेल में एक विस्मयादिबोधक बिंदु अक्सर इसका मतलब है कि विधि चुपचाप विफल होने की बजाय विफलता पर अपवाद फेंक देगा।

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

13
themomorohoax.com से

:

एक धमाके मेरी निजी वरीयता के क्रम में नीचे दिए गए तरीकों से किया जा सकता है।

1) यदि कोई विधि नहीं करती है तो यह एक सक्रिय रिकॉर्ड विधि त्रुटि उत्पन्न करती है जो यह कहती है।

2) एक सक्रिय रिकॉर्ड विधि रिकॉर्ड की बचत होती है या एक विधि एक ऑब्जेक्ट (उदा पट्टी बचाता है!)

3) एक विधि किसी ऐसे स्थान के लिए कुछ "अतिरिक्त", पोस्ट की तरह होता है, या कुछ कार्रवाई करता है।

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

धमाके अन्य डेवलपर्स के लिए दो संकेतों प्रदान करता है।

1) विधि को कॉल करने के बाद ऑब्जेक्ट को सहेजना आवश्यक नहीं है।

2) जब आप विधि को कॉल करते हैं, तो डीबी बदलने जा रहा है।

http://www.themomorohoax.com/2009/02/11/when-to-use-a-bang-exclamation-point-after-rails-methods

6

सरल स्पष्टीकरण:

foo = "BEST DAY EVER" #assign a string to variable foo. 

=> foo.downcase #call method downcase, this is without any exclamation. 

"best day ever" #returns the result in downcase, but no change in value of foo. 

=> foo #call the variable foo now. 

"BEST DAY EVER" #variable is unchanged. 

=> foo.downcase! #call destructive version. 

=> foo #call the variable foo now. 

"best day ever" #variable has been mutated in place. 

लेकिन अगर आप कभी ऊपर स्पष्टीकरण में एक विधि downcase! कहा जाता है, foo स्थायी रूप से downcase लिए बदल जाएगा। downcase! जगह में एक नया स्ट्रिंग वस्तु वापसी होगी नहीं लेकिन की जगह स्ट्रिंग, पूरी तरह से foo downcase के लिए बदल रहा। मेरा सुझाव है कि आप downcase! का उपयोग न करें जब तक कि यह पूरी तरह से आवश्यक न हो।

13

यह कहना सबसे सटीक है कि बैंग के साथ विधियां! अधिक dangerous या surprising संस्करण हैं। ऐसी कई विधियां हैं जो .destroy जैसे बैंग के बिना उत्परिवर्तित होती हैं और सामान्य तरीकों में केवल बैंग होती है जहां मूल lib में एक सुरक्षित विकल्प मौजूद होता है।

उदाहरण के लिए, सरणी पर हम .compact और .compact! है, दोनों तरीकों सरणी उत्परिवर्तित, लेकिन .compact! रिटर्न स्वयं के बजाय शून्य अगर वहाँ सरणी में कोई नहीं के बराबर है, जो सिर्फ स्वयं लौटने की तुलना में अधिक आश्चर्य की बात है कर रहे हैं।

केवल गैर-परिवर्तनशील विधि मैं एक धमाके के साथ मिल गया है Kernel के .exit! जो .exit की तुलना में अधिक आश्चर्य की बात है क्योंकि आप SystemExit पकड़ नहीं सकता है, जबकि प्रक्रिया बंद हो रहा है है।

रेल और सक्रिय रिकॉर्ड इस प्रवृत्ति को जारी रखता है कि यह .create! जैसे अधिक 'आश्चर्यजनक' प्रभावों के लिए बैंग का उपयोग करता है जो विफलता पर त्रुटियों को उठाता है।

+0

मैं 'nil' के बारे में उल्लेख करने के लिए अपवित्र हूं। – Nakilon

0

नीचे पंक्ति: ! विधियां केवल उस ऑब्जेक्ट के मूल्य को बदलती हैं जिसे वे बुलाया जाता है, जबकि ! के बिना कोई विधि उस विधि पर लिखने के बिना एक कुशल मूल्य देता है जिस पर विधि को बुलाया गया था।

केवल ! का उपयोग करें यदि आप उस चर पर संग्रहीत मूल मूल्य की आवश्यकता पर योजना नहीं बनाते जिसे आपने विधि कहा था।

मैं की तरह कुछ करने के लिए पसंद करते हैं:

foo = "word" 
bar = foo.capitalize 
puts bar 

या

foo = "word" 
puts foo.capitalize 

के बजाय

foo = "word" 
foo.capitalize! 
puts foo 

शायद ज़रुरत पड़े मैं फिर से मूल मूल्य का उपयोग करना चाहते हैं।

+0

यह डाउनवॉटेड क्यों था !? – Charles

+1

क्योंकि आपका उत्तर किसी भी तरह से सहायक नहीं था। "नीचे पंक्ति:! विधियों को उस ऑब्जेक्ट के मान को बस बदलें जिसे वे बुलाया जाता है" यह सच नहीं है। – Darwin

+0

@ डार्विन यह _does_ ऑब्जेक्ट का मान बदलता है। एक संशोधित प्रति वापस करने के बजाय वस्तु को बदलता है। – Charles

0
! 

मुझे इस बारे में एक विस्फोटक परिवर्तन के रूप में सोचना पसंद है जो इससे पहले जो कुछ भी हो गया है उसे नष्ट कर देता है। बैंग या विस्मयादिबोधक चिह्न का अर्थ है कि आप अपने कोड में स्थायी सहेजे गए परिवर्तन कर रहे हैं।

यदि आप उदाहरण के लिए वैश्विक प्रतिस्थापन gsub! के लिए रूबी की विधि का उपयोग करते हैं तो आपके द्वारा प्रतिस्थापन स्थायी है।

एक और तरीका जिसे आप कल्पना कर सकते हैं, एक टेक्स्ट फ़ाइल खोल रहा है और सहेजने के बाद ढूंढ और प्रतिस्थापित कर रहा है। ! आपके कोड में समान है।

यदि आप बैश दुनिया से आते हैं तो एक और उपयोगी अनुस्मारक sed -i में स्थायी सहेजे गए परिवर्तन को बनाने का यह समान प्रभाव है।

1

"विनाशकारी तरीके" कहा जाता है वे उस वस्तु की मूल प्रति को बदलते हैं जिसका आप उल्लेख कर रहे हैं।

numbers=[1,0,10,5,8] 
numbers.collect{|n| puts n*2} # would multiply each number by two 
numbers #returns the same original copy 
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array 
numbers # returns [nil,nil,nil,nil,nil] 
संबंधित मुद्दे