Ruby ทำ Destructuring แบบ Javascript ได้บ้างไหม
ก่อนอื่นต้องบอกว่าหลังๆ แอบเริ่มอิจฉา Javascript ที่พอใช้หลายคนเริ่มคุ้นชินกับ Destructuring แล้ว ทำให้มันลดขั้นตอนหรือโค้ดที่แต่ก่อนก็ไม่ได้คิดหรอกว่ามันเปลือง ให้มันง่ายลงได้ ยกตัวอย่างเช่น ถ้าเรากำหนด object ของ javascript ไว้ดังนี้
let x = { a:1, b:2}
แบบดั้งเดิมถ้าเราต้องการจะเอาสมาชิกมาใช้งานเราก็อาจจะใช้การ reference หรือ ตั้งตัวแปร แล้ว ค่อยๆ assign มันไปทีละตัว
console.log(x.a, x.b) // อ้างอิงจากตัวแปร x โดยตรงlet a = x.a
let b = x.b
console.log(a, b) // ดึงค่า a และ b ออกมา แล้วใช้งาน
ที่นี้ Destructuring มันช่วยให้ชีวิตในท่าหลังมันง่ายขึ้น โดยสามารถ assign ค่าในสมาชิกได้เลย และหลายตัว
let {a, b} = x
console.log(a, b) // จะได้ผลลัพธ์เหมือนด้านบน
Destructuring ยังมีท่ามากมายที่ช่วยลดความสิ้นเปลืองในการใช้งานได้เช่น ถ้าเราต้องการสลับตัวแปร แทนที่จะต้องกำหนดตัวแปรชั่วคราวแบบดั้งเดิม มันก็เปิดโอกาสให้เราสามารถสลับตัวแปรได้ภายในบรรทัดเดียว
// ท่าดั้งเดิม
let tmp = a
a = b
b = tmp// Destructuring
[a,b] = [b,a]
ทีนี้ใน Ruby เราทำอะไรได้บ้างนะ แน่นอนว่าคงไม่ได้มี Destructuring ที่ซับซ้อนเหมือน Javascript แน่นอน เดี๋ยวลองมาดูว่าอะไรที่พอจะทำได้กันบ้าง
มาที่การสลับตัวแปรก่อน อันนี้ภาษามีให้มานานและ ซึ่งก็ไม่ใช่ท่าของ Destructuring โดยทีเดียว ตรงนี้จะเรียกกว่า Parallel/Multiple Assignment
a = 1
b = 2
a, b = b, a
โดย Ruby จะสามารถอะไรในลักษณะนี้กับ Array ได้ดีมาก เช่น ถ้าเราต้องรับค่าเป็น result 2 ค่า จาก Array เราสามารถเอาตัวแปรมารับได้ทันที
x = [1,2]
a,b = x // a = 1, b = 2
แต่ถ้า Array มันมากกว่าจำนวนที่รับหล่ะ มันก็จะเอาแค่จำนวนที่มี
x = [1,2,3,4,5]
a,b = x // a=1, b=2
อย่างไรก็ตามมันยังมีท่าที่จะบอกว่า งั้นขอที่เหลืออยู่ในตัวแปรนี้หล่ะกัน โดยใช้ Splat Operator(*)
x = [1,2,3,4,5]
a, *b = x // a = 1, b = [2,3,4,5]
*a, b = x // a = [1,2,3,4], b = 5
ทีนี้ถ้ามากับ Hash หล่ะ เพราะ hash เราก็ใช้กันบ่อยอยู่ แต่โดยปกติแล้ว เรายังไม่มีท่า Destructing ผ่าน Hash กันโดยตรง แต่ก็พอจะมีท่าที่พอจะใช้ทดแทนได้บ้าง โดยใช้ method ชื่อ values_at
ซึ่งทำหน้าที่ไปอ่านค่า จาก key ต่างๆ ออกมาเป็น array ให้กับเรา แล้วเราก็ใช้ วิธี process แบบ array นั่นเอง
x = {a: 1, b: 2}
a,b = x.values_at :a, :b // a = 1, b = 2
อย่างไรก็ตาม ถ้ามาที่ Class หรือ Object ถ้าเอาตามตรงก็ถือว่า ทำไม่ได้โดยตัวมันเอง เราอาจจะต้องไปเขียน extend ขึ้นมาช่วยโดยอาจจะใช้เป็นท่าของ Array เช่นเดียวกัน
ก็หวังว่าจะพอเอาไปใช้ประโยชน์กันได้บ้างไม่มากก็น้อยครับ