บล็อคใน Ruby
posted on 01 Apr 2009 23:38 by wonam in softdev(ไม่ใช่การบล็อคเว็บนะครับ)
มีหลายสาเหตุที่ทำให้ผมชอบภาษา Ruby ทั้ง ๆ ที่หลายคนคิดว่าไวยากรณ์มันช่างประหลาดสิ้นดี
ขอยกตัวอย่างเล่น ๆ ตัวอย่างหนึ่ง สมมติผมเขียนโปรแกรมสำหรับพิมพ์ค่าในรายการไว้ เป็นดังด้านล่าง
def print_array(a)
a.each do |x|
puts "#{x}"
end
end
อธิบาย: 1. คำสั่ง each จะเรียก block ด้านหลัง (ตั้งแต่ do ถึง end) โดยส่งสมาชิกของรายการไปให้ทีละตัว block ด้านหลังนี่จะรับตัวแปรหนึ่งตัวคือ x เขียนในกรอบขีดตั้ง
2. การใส่ #{x} ในสตริงคือการให้เอาค่าตัวแปร x ไปแทนในส่วนนั้นของสตริง
เวลาใช้ก็ไม่มีอะไรครับ เรียก print_array([1,2,3,4]) ก็จะพิมพ์ผลลัพธ์ออกมา
แต่สมมติว่าผมอยากให้เมท็อดดังกล่าวเรียกแบบนี้ได้เลย [1,2,3,4].print ผมก็เอาเมท็อดดังกล่าวนี่ไปเพิ่มในคลาส Array ได้เลยครับ ดังด้านล่าง
class Array
def print
self.each do |x|
puts "#{x}"
end
end
end
(จริง ๆ ไม่ควรเพิ่มอะไรในคลาสมาตรฐานแบบพร่ำเพรื่อแต่ว่า อันนี้แสดงให้ดูเป็นตัวอย่างนะครับ)
ทีนี้ ถ้าผมอยากจะให้เมท็อดนี้ปรับวิธีในการพิมพ์ได้ เช่นถ้าผมอยากจะพิมพ์เลขสุ่มตามหลังเลขในรายการ ใน Ruby มีวิธีในการส่งส่วนของโปรแกรม (ซึ่งเรียกว่า block) เข้าไปในเมท็อดได้ โดยจะเรียกประมาณนี้
[1,2,3,4].print do |x|
puts "#{x} #{rand(100)}"
end
ก็สามารถทำได้ โดยเมท็อดข้างต้นก็จะเปลี่ยนไปเป็น
def print
self.each do |x|
if block_given?
yield x
else
puts "#{x}"
end
end
end
เมท็อดด้านบนถ้าไม่ส่ง block มาก็จะพิมพ์ด้วยวิธีธรรมดาปกติครับ
ตัวอย่างนี้อาจจะดูเป็นของเล่นสักหน่อย แต่ว่าความสามารถในการ "จิ้ม" เอา block เป็นพารามิเตอร์ในเมท็อดได้แบบแนบเนียนสนิทนี้ ทำให้เราทำอะไรน่าสนุกใน Ruby ได้มากมาย เช่นการพัฒนา Domain Specific Language บน Ruby ครับ (จะเขียนถึงภายหลังถ้ามีเวลาครับ)
โครงสร้างก้อประหลาดๆ งงดีเหมือนกันอะคับ
#1 By xnanoob on 2009-04-02 10:22