بلوک‌ها در روبی

بلوک‌های do...end و { }، yield و کار با بلوک در روبی

بلوک چیست؟

بلوک (Block) یکی از قدرتمندترین ویژگی‌های روبی است. بلوک یک قطعه کد ناشناس است که به یک متد داده می‌شود.

دو سینتکس بلوک

۱. do...end (برای بلوک‌های چندخطی)

[1, 2, 3].each do |n|
  puts n * 2
end

۲. { } (برای بلوک‌های یک‌خطی)

[1, 2, 3].each { |n| puts n * 2 }
از { } برای بلوک‌های کوتاه و یک‌خطی، و از do...end برای بلوک‌های طولانی‌تر استفاده کنید.

پارامترهای بلوک

متغیرهای بین | | پارامترهای بلوک هستند:

[10, 20, 30].each do |number|
  puts number
end

# چند پارامتر
[[1, "علی"], [2, "مریم"]].each do |id, name|
  puts "#{id}: #{name}"
end

yield — اجرای بلوک

با yield می‌توانید بلوک داده‌شده به متد را اجرا کنید:

def run_block
  puts "قبل از بلوک"
  yield  # اجرای بلوک
  puts "بعد از بلوک"
end

run_block { puts "این بلوک است!" }
# خروجی:
# قبل از بلوک
# این بلوک است!
# بعد از بلوک

yield با پارامتر

def process
  yield("علی")
  yield("مریم")
end

process { |name| puts "سلام #{name}!" }
# => سلام علی!
# => سلام مریم!

بررسی وجود بلوک (block_given?)

def maybe_yield
  if block_given?
    yield
  else
    puts "بلوکی داده نشده!"
  end
end

maybe_yield { puts "با بلوک" }  # => با بلوک
maybe_yield                      # => بلوکی داده نشده!

yield چند بار

def three_times
  yield 1
  yield 2
  yield 3
end

three_times { |n| puts "تکرار #{n}" }

بلوک با & به عنوان متد

# تبدیل بلوک به Proc
def capture_block(&block)
  block.call
end

capture_block { puts "با &" }

# ارسال نماد به عنوان بلوک
["ali", "reza"].map(&:upcase)  # => ["ALI", "REZA"]

بلوک در متدهای پرکاربرد

# each
[1, 2, 3].each { |n| puts n }

# map
squared = [1, 2, 3].map { |n| n ** 2 }

# select
evens = [1, 2, 3, 4].select { |n| n.even? }

# times
3.times { puts "سلام" }

# File.open
File.open("file.txt", "w") { |f| f.write("سلام") }

بلوک با مقدار بازگشتی

result = [1, 2, 3, 4, 5].map do |n|
  n ** 2
end
puts result.inspect  # => [1, 4, 9, 16, 25]

ساخت متد با بلوک

def timer
  start = Time.now
  yield
  elapsed = Time.now - start
  puts "زمان اجرا: #{elapsed} ثانیه"
end

timer do
  sum = 0
  1_000_000.times { |i| sum += i }
  puts "مجموع: #{sum}"
end

خلاصه

مفهومسینتکس
بلوک چندخطیdo |x| ... end
بلوک یک‌خطی{ |x| ... }
اجرای بلوکyield
yield با پارامترyield(val)
بررسی بلوکblock_given?
دریافت به عنوان Proc&block

این مبحث بخشی از دوره آموزش کامل روبی است.

ابزارهای مرتبط