case (दूसरी भाषाओं में इसे अक्सर switch कहा जाता है) if-else जैसा एक कंट्रोल एक्सप्रेशन है। case की मदद से कई if-else-if स्टेटमेंट को एक साथ जोड़ा जा सकता है, इससे कोड ज़्यादा पढ़ने-योग्य बन सकता है, और इससे शक्तिशाली चीज़ें बनाई जा सकती हैं।
case को कीवर्ड case से बनाया जाता है, और उसके बाद वैकल्पिक रूप से एक एक्सप्रेशन लिखा जाता है। फिर हर case के लिए कीवर्ड when इस्तेमाल होता है, जिसके बाद एक और एक्सप्रेशन लिखा जाता है। इस एक्सप्रेशन की तुलना case एक्सप्रेशन से की जाती है। when कीवर्ड को case कीवर्ड से अंदर की ओर इंडेंट नहीं करना चाहिए। when कीवर्ड के बाद वह कोड लिखा जाता है जो तब चलता है जब case एक्सप्रेशन किसी when एक्सप्रेशन से मेल खाता हो। case में चाहें तो एक else स्टेटमेंट भी लिखा जा सकता है, जो तब चलता है जब कोई और case मेल न खाए।
सबसे पहले case एक्सप्रेशन का मूल्यांकन किया जाता है, और फिर उसकी तुलना हर when एक्सप्रेशन से की जाती है। यह तुलना case सबसम्प्शन ऑपरेटर (===) से की जाती है।
case 1
when 1
puts "One"
when 2
puts "Two"
else
puts "Other"
end
# => One
# This is the same as:
tmp = 1
if 1 === tmp
puts "One"
elsif 2 === tmp
puts "Two"
else
puts "Other"
end
===)case सबसम्प्शन ऑपरेटर (===) समानता ऑपरेटर (==) से थोड़ा अलग है। यह ऑपरेटर जाँचता है कि दाईं ओर की वैल्यू, बाईं ओर बताए गए समूह की सदस्य है या नहीं। इसका मतलब है कि हर ऑपरेंड कहाँ रखा गया है, यह मायने रखता है। यह कैसे काम करता है, यह बाईं ओर के टाइप पर निर्भर करता है। जैसे Range जाँचेगा कि दाईं ओर की वैल्यू उस रेंज में है या नहीं, और Object जाँचेगा कि दाईं ओर की वैल्यू Object का इंस्टेंस है या नहीं।
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
एक ही case में कई एक्सप्रेशन मैच किए जा सकते हैं, बस हर संभावित वैल्यू को कॉमा से अलग कर दीजिए। इनमें से कोई भी एक्सप्रेशन मेल खाते ही कोड चल जाता है। जब एक case के लिए कई संभावित वैल्यू हों, तब यह तरीका काम आता है।
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
case यह भी जाँच सकता है कि कोई वैल्यू किसी रेंज में है या नहीं। इसके लिए when एक्सप्रेशन की जगह एक रेंज लिखी जाती है।
case var
when 1..3
puts "One to three"
else
puts "Other"
end
जब case एक्सप्रेशन की ज़रूरत न हो, तो उसे छोड़ा जा सकता है। ऐसा करने पर हर when एक्सप्रेशन को इस आधार पर जाँचा जाता है कि वह सही है या नहीं। इससे ये if-else-if स्टेटमेंट की तरह काम करने लगते हैं।
case
when 1 == 1
puts "One is equal to one"
when 1 > 2
puts "One is greater than two"
else
puts "Other"
end
Crystal में case स्टेटमेंट एक ही लाइन में लिखे जा सकते हैं। जब स्टेटमेंट छोटा हो और एक ही लाइन में आ जाए, तब इसका इस्तेमाल किया जा सकता है। एक लाइन वाला when ऐसे लिखा जाता है: when <expression> then <statement>. और else में ऐसे: else <statement>.
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
case में टाइप के आधार पर भी मेल किया जा सकता है। तुलना के लिए is_a? ऑपरेटर से वेरिएबल का टाइप जाँचा जाता है। जैसे अगर कोई यूनियन टाइप हो, तो इससे हर टाइप के लिए एक अलग ब्रांच बनाई जा सकती है।
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case में इम्प्लिसिट ऑब्जेक्ट का इस्तेमाल भी किया जा सकता है। इससे when एक्सप्रेशन को case एक्सप्रेशन पर मेथड कॉल की तरह लिखा जा सकता है। मेथड जो वैल्यू लौटाता है, उसके सही या गलत होने के आधार पर तय होता है कि case मेल खाएगा या नहीं।
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
इस अभ्यास में हम Blackjack खेल की पहली बारी का अनुकरण करेंगे।
आपको दो कार्ड मिलेंगे और आप डीलर का खुला कार्ड देख सकेंगे। सभी कार्ड एक स्ट्रिंग से दर्शाए जाते हैं, जैसे "ace", "king", "three", "two", वगैरह। हर कार्ड की वैल्यू ये हैं:
| कार्ड | वैल्यू | कार्ड | वैल्यू |
|---|---|---|---|
| ace | 11 | eight | 8 |
| two | 2 | nine | 9 |
| three | 3 | ten | 10 |
| four | 4 | jack | 10 |
| five | 5 | queen | 10 |
| six | 6 | king | 10 |
| seven | 7 | अन्य | 0 |
आम तौर पर ace की वैल्यू 1 या 11 हो सकती है, लेकिन सरलता के लिए हम मान लेंगे कि इनकी वैल्यू सिर्फ 11 ही हो सकती है।
मेथड Blackjack.parse_card लागू कीजिए, जो आर्गुमेंट के रूप में एक कार्ड स्ट्रिंग लेता है।
यह मेथड कार्ड की वैल्यू को पूर्णांक के रूप में लौटाए।
Blackjack.parse_card("ace")
# => 11
खिलाड़ी के स्कोर को वैल्यू की रेंजों में बाँटना होता है। खिलाड़ी का स्कोर उसके दोनों कार्डों की वैल्यू जोड़कर निकाला जाता है। इस्तेमाल होने वाली रेंजें ये हैं:
| रेंज | वैल्यू |
|---|---|
| low | [4, 11] |
| mid | [12, 16] |
| high | [17, 20] |
| blackjack | [21] |
मेथड Blackjack.card_range लागू कीजिए, जो आर्गुमेंट के रूप में दो कार्ड स्ट्रिंग लेता है।
यह मेथड उस रेंज का नाम लौटाए, जिसमें ये दोनों कार्ड आते हैं।
Blackjack.card_range("ten", "king")
# => "high"
आपके दोनों कार्ड और डीलर के कार्ड के आधार पर खेल की पहली बारी के लिए एक रणनीति होती है। इसमें आपके पास ये विकल्प होते हैं:
हालाँकि यह अभी सबसे अच्छी नहीं है, फिर भी आप उस रणनीति का पालन करेंगे जो आपके दोस्त Alex बना रहे हैं। वह इस प्रकार है:
मेथड Blackjack.first_turn लागू कीजिए, जो आर्गुमेंट के रूप में तीन कार्ड स्ट्रिंग लेता है।
यह मेथड आपको जो निर्णय लेना चाहिए, उसे स्ट्रिंग के रूप में लौटाए।
Blackjack.first_turn("ace", "ace", "two")
# => "P"
Exercism पर साइन अप कीजिए और Crystal को 26 कॉन्सेप्ट142 अभ्यास तथा असली इंसानों से मिलने वाली मेंटरिंग के साथ सीखिए और उसमें महारत हासिल कीजिए, वह भी बिल्कुल मुफ्त।