case (অন্য ভাষায় সাধারণত যা switch নামে পরিচিত) হলো if-else-এর মতো এক ধরনের কন্ট্রোল এক্সপ্রেশন।
case দিয়ে একাধিক if-else-if স্টেটমেন্ট চেইন করা যায়, কোড আরও পাঠযোগ্য হয়ে উঠতে পারে, আর শক্তিশালী গঠন লেখার সুবিধা মেলে।
একটি case লেখা হয় case কিওয়ার্ড দিয়ে, তার পরে থাকে একটি ঐচ্ছিক এক্সপ্রেশন।
এরপর প্রতিটি ক্ষেত্রে when কিওয়ার্ড ব্যবহার করা হয়, যার পরে থাকে এমন একটি এক্সপ্রেশন যা কেস এক্সপ্রেশনের সঙ্গে তুলনা করা হয়।
when কিওয়ার্ডটি case কিওয়ার্ডের চেয়ে বেশি ইনডেন্ট করা উচিত নয়।
when কিওয়ার্ডের পরে থাকে সেই কোড, যা কেস এক্সপ্রেশনটি when এক্সপ্রেশনের সঙ্গে মিলে গেলে চালানো হয়।
কেসে একটি ঐচ্ছিক else স্টেটমেন্ট থাকতে পারে, যা অন্য কোনো কেসের সঙ্গে না মিললে চালানো হয়।
কেস এক্সপ্রেশনটি হিসাব করা হয়, তারপর প্রতিটি when এক্সপ্রেশনের সঙ্গে তুলনা করা হয়।
তুলনাটি করা হয় কেস সাবসাম্পশন অপারেটর (===) দিয়ে।
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
===)কেস সাবসাম্পশন অপারেটর (===) সাম্য অপারেটর (==) থেকে একটু আলাদা।
এই অপারেটর দেখে, ডান দিকের মানটি বাঁ দিকের বর্ণিত সেটের একটি সদস্য কি না।
এর মানে হলো, প্রতিটি অপারেন্ড কোথায় বসছে সেটি সত্যিই গুরুত্বপূর্ণ।
এটি কীভাবে কাজ করবে তা নির্ভর করে বাঁ দিকের টাইপের ওপর। যেমন একটি Range দেখে ডান দিকের মানটি রেঞ্জের ভেতরে আছে কি না, আর একটি Object দেখে ডান দিকের মানটি Object-এর একটি ইনস্ট্যান্স কি না।
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
কেসে একসঙ্গে একাধিক এক্সপ্রেশন মেলানো যায়, প্রতিটি সম্ভাব্য মান কমা দিয়ে আলাদা করে লেখা হয়। এর মধ্যে যেকোনো একটি মিলে গেলেই কোডটি চালানো হয়। একাধিক সম্ভাব্য মান আছে এমন একটি কেসের জন্য এটি কাজে লাগে।
case 1
when 1, 2
puts "One or two"
else
puts "Other"
end
কেস দিয়ে একটি মান কোনো রেঞ্জের মধ্যে আছে কি না, তাও দেখা যায়। এজন্য when এক্সপ্রেশন হিসেবে একটি রেঞ্জ লিখতে হয়।
case var
when 1..3
puts "One to three"
else
puts "Other"
end
কেস এক্সপ্রেশনের দরকার না থাকলে সেটি বাদ দেওয়া যায়। তখন প্রতিটি 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-এ এক লাইনের কেস স্টেটমেন্ট লেখা যায়।
সহজ, এক লাইনের স্টেটমেন্ট থাকলে এটি ব্যবহার করা যায়।
এক লাইনের when স্টেটমেন্ট লেখা হয় when <expression> then <statement>. হিসেবে।
আর else স্টেটমেন্টে ব্যবহার করলে লেখা হয় else <statement> হিসেবে।
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
কেস দিয়ে টাইপ মেলানোও যায়।
তুলনার সময় ভ্যারিয়েবলের টাইপ দেখতে is_a? অপারেটর ব্যবহার করা হয়।
যেমন এটি দিয়ে একটি ইউনিয়ন টাইপের প্রতিটি টাইপের জন্য আলাদা শাখা লেখা যায়।
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
কেসে একটি ইমপ্লিসিট অবজেক্ট ব্যবহার করা যায়। এতে when এক্সপ্রেশনটি কেস এক্সপ্রেশনের ওপর করা একটি মেথড কল হতে পারে। মেথডটি ট্রুথি নাকি ফলসি মান রিটার্ন করে, তার ওপর নির্ভর করে কেসটি মিলবে কি না।
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
কেস দিয়ে সম্পূর্ণ কেসও লেখা যায়, অর্থাৎ সব সম্ভাব্য মান ধরার নিশ্চয়তা দেওয়া সম্ভব।
এটি when স্টেটমেন্টের মতোই, তবে when-এর বদলে in কিওয়ার্ড ব্যবহার করা হয়।
একটি কেস সম্পূর্ণ হলে সেখানে কোনো when বা else স্টেটমেন্ট ব্যবহার করা যায় না।
সম্পূর্ণ কেস ব্যবহার করা যায় Bools, Union টাইপ, Enum এবং Tuples-এর ওপর।
শেষের দুটি নিয়ে পরে আরও কনসেপ্টে আলোচনা করা হবে।
সম্পূর্ণ কেস মানে সব সম্ভাবনা ধরতেই হবে, নাহলে একটি কম্পাইল এরর দেখানো হবে।
একটি Union টাইপকে সম্পূর্ণ কেস হিসেবে সামলানো অনেকটা সাধারণ কেসের মতোই।
var : (Int32 | String | Bool)
case var
in Int32
puts "Int32"
in String
puts "String"
in Bool
puts "Bool"
end
true আর false কিওয়ার্ড ব্যবহার করে Bools-কে সম্পূর্ণ কেস হিসেবে সামলানো যায়।
var : Bool
case var
in true
puts "True"
in false
puts "False"
end