Blocks สำคัญมากใน Ruby ยากที่จะจินตนาการภาษานี้โดยไม่มีมัน แต่ lambdas? ใครรัก lambdas? อาจใช้ไม่ได้นานปีๆ มันดู像 relic จากยุคเก่า
...แต่นั่นไม่จริงทั้งหมด Lambdas มีทริคน่าสนใจเวลาขุดลึกดู
บทความนี้เริ่มจาก basics ของ lambda usage แล้วไป advanced usages ถ้าใช้ lambdas ทุกวันรู้หมดแล้ว scroll ลงไปเลย
สำคัญที่สุด: Lambdas พฤติกรรมเหมือน functions Blocks และ Procs มีประโยชน์ แต่ไม่ behave 100% เหมือน function จริง Lambdas ทำได้ มาดูรายการ
Lambdas บังคับจำนวน arguments ให้ถูกต้อง
ต่างจาก Procs lambdas enforce correct number of arguments
Lambdas รองรับ Default Arguments
ตัวอย่างสร้าง lambda function พร้อม default argument "hello world"
Lambdas รองรับ default arguments
Keyword return ทำงานตรงตามที่คาดหวัง
อาจดูเล็กน้อย แต่ใครเคยพยายาม return ใน proc รู้ว่าไม่ง่าย
ตัวอย่างด้านล่าง method something เรียก Proc ที่มี return statement แต่ return นี้ tricky แทนที่จะ return จาก proc มัน return จาก something method
แต่วันทำกับ lambda return statement แค่ return จาก lambda เหมือน function อื่นๆ
เวลาใช้ return keyword ภายใน lambda มัน return จาก lambda
Lambdas เป็น Closures
อ้าง stack overflow post ยอดเยี่ยม:
คิด closure ง่ายที่สุดคือ **function ที่เก็บเป็น variable ได้** (first-class function) ที่มีความสามารถพิเศษ access variables อื่นๆ local to scope ที่มันถูกสร้างขึ้น
Access variables local to scope ที่ lambda ถูกสร้าง หมายถึงอะไร? ดูตัวอย่าง สร้าง local variable marco ใช้ได้ใน lambda ถ้าเปลี่ยนค่า lambda เห็นค่าใหม่
Ruby lambdas เป็น closures
Lambdas เป็น Chameleons (สลับรูปแบบได้)
สิ่งแปลกของ lambdas คือหลายวิธี invoke ตัวอย่างแสดง 3 วิธี equivalent
มีอย่างน้อย 3 วิธี invoke lambda ใน Ruby
อาจดูแปลก ผมแรกก็แปลก และ老实说 syntax l.(arg) ยังปวดหัว แต่ l[arg] น่าสนใจ แปลว่าใช้ lambdas แทน array/hash ได้บ้าง
ใช้ Lambdas เป็น Computed Hashes และ Arrays
สมมติ test suite ต้องสร้าง fake Person records สร้าง FakePerson record ส่ง first/last name
แต่อยาก "fuzz test" ด้วย first/last names ต่างๆ ทุกครั้งที่รัน test?
วิธีหนึ่งส่ง lambda function แทน hash ตัวอย่างใช้ lambda generate fake names ด้วย Faker gem
Lambda แทน hash ได้
Lambdas มี Built-in Currying
Currying เทคนิค cool ใน functional programming สร้าง functions ใหม่จาก functions เดิม เข้าใจง่ายตอนเห็นใน code
โค้ดด้านล่าง lambda function บวก 2 ตัวเลข เรียกว่า add ใช้ currying สร้าง function เฉพาะเจาะจง increment บวก 1 เข้าเลขไหนก็ได้
Curry proc ใดๆ ใน Ruby ได้
Lambdas เป็น Proc พิเศษ
สังเกตไหมว่า define lambda ได้ Proc กลับมา? เพราะ Ruby implement lambdas เป็น Proc ชนิดหนึ่ง ดังนั้นหลายอย่างในบทความทำได้กับ Procs ด้วย
Stabby Lambdas
บทความนี้ใช้ lambda keyword เพื่อความชัดเจน แต่มี syntax รวดเร็วกว่าใน Ruby 1.9 เรียกว่า "stabby lambda" ทำงานแบบนี้:
Ruby stabby lambda syntax introduced in version 1.9