case (که در زبانهای دیگر معمولاً switch نامیده میشود) نوعی عبارت کنترلی مانند if-else است.
case امکان زنجیرهکردن چند دستور if-else-if را میدهد، میتواند خواناتر باشد و ساختارهای قدرتمندی را ممکن میکند.
یک case با «کلیدواژه»ی case و سپس یک عبارت اختیاری تعریف میشود.
سپس برای هر حالت، کلیدواژهی when به کار میرود و پس از آن عبارتی میآید که با عبارت case مقایسه میشود.
کلیدواژهی when نباید نسبت به کلیدواژهی case تورفتگی داشته باشد.
بعد از کلیدواژهی when، کدی میآید که اگر عبارت case با عبارت when مطابقت داشته باشد باید اجرا شود.
case یک دستور else اختیاری هم دارد که اگر هیچ حالت دیگری مطابقت نداشته باشد اجرا میشود.
عبارت 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 (===)عملگر شمول case (===) با عملگر برابری (==) کمی متفاوت است.
این عملگر بررسی میکند که آیا سمت راست عضوی از مجموعهای است که سمت چپ توصیف میکند.
یعنی جای قرار گرفتن هر عملوند مهم است.
اینکه این کار چطور انجام میشود به نوع سمت چپ بستگی دارد؛ برای نمونه، یک Range بررسی میکند که آیا سمت راست درون بازه قرار دارد یا یک Object بررسی میکند که آیا سمت راست نمونهای از Object است.
(1..3) == 1 # => false
(1..3) === 1 # => true
String == "foo" # => false
String === "foo" # => true
case با چندین عبارتحالتها اجازه میدهند در یک 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 بدون عبارت case
وقتی نیازی به عبارت 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
when تکخطیCrystal دستورهای case تکخطی را ممکن میکند.
این شکل زمانی به کار میآید که یک دستور سادهی تکخطی دارید.
در حالت تکخطی، دستور به شکل when <expression> then <statement>. نوشته میشود.
و در else به شکل else <statement> نوشته میشود.
case var
when 1 then puts "One"
when 2 then puts "Two"
else puts "Other"
end
case با نوعهاcase امکان مطابقت بر اساس نوع را هم میدهد.
این مقایسه از عملگر is_a? برای بررسی نوع متغیر استفاده میکند.
برای نمونه، این کار یک شاخه برای هر نوع در یک نوع Union ممکن میکند.
case var
when Int32
puts "Int32"
when String
puts "String"
else
puts "Other"
end
case امکان استفاده از یک شیء ضمنی را فراهم میکند.
این کار مثلاً اجازه میدهد عبارت when یک فراخوانی متد روی عبارت case باشد.
بر اساس اینکه متد مقداری درست یا غلط برگرداند، آن حالت مطابقت میکند یا نه.
case 1
when .odd?
puts "Odd"
when .even?
puts "Even"
end
case جامعcase حالتهای جامع را ممکن میکند، یعنی میتوان مطمئن شد که همهی مقادیر ممکن پوشش داده شدهاند.
این شکل شبیه دستور when است، اما با کلیدواژهی in بهجای when.
وقتی یک case جامع باشد، دیگر از دستورهای when یا else پشتیبانی نمیکند.
حالتهای جامع را میتوان روی Bools، نوعهای Union، Enum و Tuples به کار برد.
دو مورد آخر در مفاهیم بعدی بررسی میشوند.
حالتهای جامع یعنی همهی حالتهای ممکن باید پوشش داده شوند، در غیر این صورت خطای کامپایل رخ میدهد.
پرداختن به نوعهای Union بهصورت یک case جامع، شبیه به حالت غیرجامع است.
var : (Int32 | String | Bool)
case var
in Int32
puts "Int32"
in String
puts "String"
in Bool
puts "Bool"
end
Bools را میتوان با استفاده از کلیدواژههای true و false بهصورت یک case جامع مدیریت کرد.
var : Bool
case var
in true
puts "True"
in false
puts "False"
end