بازهها فاصلهای بین دو مقدار را نمایش میدهند.
رایجترین نوعهایی که از بازه پشتیبانی میکنند Integer و String هستند.
از آنها میتوان برای کاربردهای متعددی استفاده کرد؛ مانند ساختن سریع یک مجموعه، برش رشتهها، بررسی اینکه مقداری داخل یک بازه هست یا نه، و پیمایش.
بازهها با عملگر بازهی .. یا ... ساخته میشوند (بهترتیب شامل و غیرشامل).
1..5 # => 1..5
1...5 # => 1...5
(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
دلیل وجود دو عملگر بازه این است که بتوان بازههایی ساخت که مقدار پایانی را شامل میشوند یا نمیشوند؛ این موضوع مثلاً وقتی با اندیسهایی کار میکنیم که از صفر شروع میشوند مفید است.
بازهها را میتوان با سازندهی Range، یعنی new، هم ساخت.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
وقتی در Ruby با عملگرهای بازهی .. یا ... یک بازه میسازید و میخواهید متدی را روی آن بازه فراخوانی کنید، باید بازه را داخل پرانتز بگذارید.
دلیلش این است که در غیر این صورت، متد روی دومین آرگومانِ عملگر بازه فراخوانی میشود.
(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)
وقتی میخواهید رشتهای را برش دهید، میتوانید با عملگر بازه یک زیررشته به دست آورید. یعنی با ساختن بازهای از اندیس شروع و پایان زیررشته.
"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"
همچنین میتوانید با اندیسهای منفی، زیررشته را از انتهای رشته به دست آورید.
"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"
بازهها مجموعهای از متدها دارند که برای کار با آنها به کار میروند. برای مثال، با این متدها میتوان مجموع همهی مقادیر یک بازه را به دست آورد یا بررسی کرد که آیا بازه مقدار مشخصی را شامل میشود یا نه.
| متد | توضیح | مثال |
|---|---|---|
sum |
مجموع همهی مقادیر بازه را برمیگرداند | (1..5).sum # => 15 |
size |
اندازهی بازه را برمیگرداند | (1..5).size # => 5 |
include? |
اگر بازه مقدار دادهشده را شامل شود true و در غیر این صورت false را برمیگرداند |
(1..5).include?(3) # => true |
یک بازه میتواند بیپایان و بدون آغاز باشد.
در بازهی بیپایان یا بدون آغاز، مقدار شروع یا پایان nil است، اما هنگام تعریف بازه میتوان nil را حذف کرد.
استفاده از بازههای بدون آغاز و بیپایان وقتی مفید است که مثلاً بخواهید رشتهای را از ابتدا یا تا انتها برش دهید.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
اگر بازهی بیپایان روی یک مجموعه به کار نرود، در صورت بیاحتیاطی میتواند به دنبالهای بیپایان منجر شود.
از رشتهها نیز میتوان در بازهها استفاده کرد؛ به این ترتیب، بازهای از رشتهها میان دو رشته به دست میآید. رفتار آن با بعضی رشتههای خاص کمی غیرمنتظره است، پس با احتیاط از آن استفاده کنید.
("aa".."az").to_a # => ["aa", "ab", "ac", ..., "az"]
به عنوان یک علاقهمند به شطرنج، دوست دارید نسخهی خودتان از این بازی را بنویسید. بله، شاید همین حالا هم پیادهسازیهای زیادی از شطرنج به صورت آنلاین در دسترس باشند، اما نسخهی شما یگانه خواهد بود!
شما کار را با پیادهسازی یک سیستم حرکت پایه برای مهرهها شروع میکنید.
بازی شطرنج روی تختهای انجام میشود که ۸ خانه عرض و ۸ خانه طول دارد. هر خانه با یک حرف و یک عدد مشخص میشود.
بازی باید ردیفهای تخته را نگه دارد. ردیفها همان سطرهای تخته هستند و از ۱ تا ۸ شمارهگذاری شدهاند.
بازی همچنین باید ستونهای تخته را نگه دارد. ستونها همان ستونهای تختهاند و با حروف A تا H مشخص میشوند.
ثابتهای Chess::RANKS و Chess::FILES را تعریف کنید که به ترتیب محدودهی ردیفها و ستونها را نگه میدارند.
Chess::RANKS
# => 1..8
Chess::FILES
# => 'A'..'H'
بازی باید بررسی کند که آیا یک خانه معتبر است یا نه. یک خانه وقتی معتبر است که ردیف و ستون آن در محدودهی ردیفها و ستونها قرار داشته باشند.
متد Chess.valid_square? را تعریف کنید که آرگومانهای rank و file را میگیرد؛ rank یک عدد صحیح از ردیف را نگه میدارد و file یک کاراکتر از ستون.
این متد باید در صورتی که ردیف و ستون در محدودهی ردیفها و ستونها باشند true را برگرداند و در غیر این صورت false را.
Chess.valid_square?(1, 'A')
# => true
بازی باید اسم مستعار بازیکن را به دست آورد. اسم مستعار از ۲ کاراکتر اول اسم کوچک بازیکن و ۲ کاراکتر آخر اسم خانوادگی او تشکیل میشود. اسم مستعار باید با حروف بزرگ نوشته شود.
متد Chess.nickname را تعریف کنید که آرگومانهای first_name و last_name را میگیرد؛ first_name رشتهای از اسم کوچک بازیکن را نگه میدارد و last_name رشتهای از اسم خانوادگی او را.
این متد باید اسم مستعار بازیکن را به صورت رشتهای با حروف بزرگ برگرداند.
Chess.nickname("John", "Doe")
# => "JOOE"
بازی باید برای یک حرکت پیامی بسازد که بگوید کدام بازیکن به کدام خانه حرکت کرده است. پیام باید از اسم مستعار بازیکن و خانهای که به آن حرکت کرده است استفاده کند. بازی همچنین باید معتبر بودن حرکت را با بررسی اینکه ردیف و ستون خانه در محدودهی ستونها و ردیفها قرار دارند یا نه تعیین کند.
اگر حرکت معتبر باشد، پیام باید این باشد: "{nickname} moved to {square}"
اگر حرکت معتبر نباشد، پیام باید این باشد: "{nickname} attempted to move to {square}, but that is not a valid square"
متد Chess.move_message را تعریف کنید که آرگومانهای first_name، last_name و square را میگیرد؛ first_name رشتهای از اسم کوچک بازیکن، last_name رشتهای از اسم خانوادگی بازیکن و square رشتهای از خانهای را که بازیکن به آن حرکت کرده است نگه میدارد.
این متد باید پیام حرکت را به صورت رشتهای برگرداند.
Chess.move_message("John", "Doe", "A1")
# => "JOOE moved to A1"