Ruby ไม่เคยหยุดพัฒนา!
รุ่น 2.7 มาพร้อมฟีเจอร์ เมธอด และการปรับปรุงประสิทธิภาพใหม่ๆ เปิดตัวเมื่อวันที่ 25 ธันวาคม 2019
ตอนนี้ ตาม Matz...
นี่คือรุ่น 2.x สุดท้าย เพราะปีหน้าเราจะได้ Ruby 3.0!
แตก่อนที่เราจะไปถึงนั้น...
มาดูการเปลี่ยนแปลงและฟีเจอร์ใหม่ใน 2.7 บ้าง เพื่อให้คุณพร้อมสำหรับการอัปเดตรุ่น
สารบัญ
- 1 Enumerable#tally
- 2 Numbered Parameters For Blocks [Experimental]
- 3 Array#intersection
- 4 Enumerable#filter_map
- 5 Enumerator#produce
- 6 IRB ได้รับการปรับปรุง?
- 7 Ruby Pattern Matching [Experimental]
- 8 การเปลี่ยนแปลงอื่นๆ
- 9 สรุป
- 9.1 Related
Enumerable#tally
นี่คือเมธอด Ruby ใหม่ที่นับองค์ประกอบทั้งหมดในอาร์เรย์ และส่งคืนแฮชพร้อมจำนวนของพวกมัน
คุณสามารถทำได้เอง แตเมธอด tally นี้ประหยัดงานให้คุณ
ตัวอย่าง:
%w(a a a b b c).tally
ซึ่งให้ผลลัพธ์:
{"a"=>3, "b"=>2, "c"=>1}
ผมชอบมัน!
Numbered Parameters For Blocks [Experimental]
ฟีเจอร์ใหม่ที่น่าสนใจ ซึ่งผมอยากได้มานาน คือชื่อเริ่มต้นสำหรับพารามิเตอร์บล็อก
นี่คือบล็อกทั่วไป พร้อมพารามิเตอร์หนึ่งตัว:
[1,2,3].each { |n| puts n }
|n| นี้คือพารามิเตอร์ ซึ่งคุณต้องกำหนดเพื่อใช้มัน
แตถ้าเรามีชื่อเริ่มต้น?
จริงๆ แล้ว นั่นคือหนึ่งในของขวัญที่ Ruby 2.7 นำมา แม้จะเป็น ฟีเจอร์ทดลอง (experimental) มันสามารถประหยัดการพิมพ์มาก
มันมีลักษณะแบบนี้:
[1,2,3].each { puts _1 }
ที่ _1 หมายถึงพารามิเตอร์แรก คุณสามารถใช้ _2 หากมีตัวที่สอง และ _3 สำหรับตัวที่สาม เป็นต้น
น่าสนใจมาก!
ตอนนี้ บิตของข้อมูลน่าสนใจ
ฟีเจอร์นี้เสนอครั้งแรกให้เป็น @1 แตดูเหมือน instance variable มากเกินไป ดังนั้นหลังการอภิปราย จึงตัดสินใจใช้ _1 แทน
Array#intersection
นี่คือเมธอดใหม่ แตไม่ใช่ฟังก์ชันใหม่
จริงๆ แล้ว...
นี่คล้าย alias มากกว่า!
Ruby 2.6 นำเสนอเมธอด Array union และ difference เพื่อให้ตรงกับรูปแบบสั้นที่กระชับของ Array#| และ Array#-
แตการดำเนินการที่หายไปคือ intersection ซึ่งมีรูปแบบสั้นที่ยากจดจำอีกแบบ
คือ Array#& method
ตอนนี้:
เมธอดเหล่านี้ทำอะไรและทำงานอย่างไร?
ตัวอย่าง:
[1, 2, 3].intersection([2, 3, 4]) # [2, 3] [1, 2, 3] & [2, 3, 4] # [2, 3]
จริงๆ แล้ว...
ชื่อบ่งบอกแล้ว intersection หาจุดตัด (intersection) ระหว่างสองอาร์เรย์ กล่าวอีกนัยคือ หาว่าองค์ประกอบไหนเหมือนกัน
| รูปแบบสั้น | รูปแบบยาว |
|---|---|
| & | intersection |
| | | union |
| - | difference |
ผมลืมตลอดเวลาว่าสามเมธอดนี้ตัวไหนทำอะไร!
แตด้วยเมธอดใหม่เหล่านี้ มันง่ายกว่า มาก ที่จะจำ เพราะ ชื่อของพวกมันมีความหมาย
นั่นคือบทเรียนที่ดีในการเขียนโค้ดที่ดี au passage
Enumerable#filter_map
เมธอด filter_map นี้เป็นการพยายามรวมเมธอด select และ map เข้าด้วยกันเป็นอันเดียว
ทำไม?
เพราะมันเป็นการดำเนินการทั่วไป ที่กรองรายการก่อน แล้ว map องค์ประกอบที่เหลือ
คุณสามารถทำได้สองวิธี:
(1..8).select(&:even?).map { |n| n ** 2 }
# OR
(1..8).map { |n| n ** 2 if n.even? }.compact
ผมใช้ทั้งสอง แตทendance ไปที่ตัวแรก เพราะเจตนาชัดเจนกว่า
ตอนนี้:
ใน Ruby 2.7 เมธอด filter_map ทำสิ่งนี้ในหนึ่งรอบ
แบบนี้:
(1..8).filter_map { |n| n ** 2 if n.even? } # [4, 16, 36, 64]
ผมไม่ใช่แฟนใหญ่ของการมี if statement ภายในบล็อก แตบางครั้งพวกมันจำเป็นเพื่อทำให้เสร็จ
นอกจากนี้ มีสิ่งที่คุณควรรู้
การดำเนินการ filter_map ไม่ได้ทำงานเหมือน map + compact เพราะมันลบออบเจ็กต์ false ออก ในขณะที่ compact ไม่ลบ
สิ่งดีที่ควรจดจำไว้!
Enumerator#produce
นี่คือเมธอดใหม่อีกตัวที่คุณอาจสนใจ แตอาจต้องการความคิดสร้างสรรค์บ้าง เพื่อใช้ประโยชน์สูงสุด
มันคือเมธอด Enumerator#produce
มันทำอะไร?
ตามข้อเสนอฟีเจอร์:
"This method produces an infinite sequence where each next element is calculated by applying the block to the previous element."
ยัป
อีกวิธีหนึ่งในการสร้างลำดับไม่มีที่สิ้นสุด!
ตัวอย่าง:
Enumerator.produce(1, &:next).take(5) # [1, 2, 3, 4, 5]
ในตัวอย่างนี้ ไม่สำคัญว่าคุณทำ take(10) หรือ take(10_000) คุณจะได้ค่าจำนวนไม่จำกัดจากมัน
Btw, 1 คือค่าเริ่มต้น
และ &:next คือเมธอดที่เรียกบนค่านั้นเพื่อ produce องค์ประกอบถัดไปในลำดับ
IRB ได้รับการปรับปรุง?
ล่าสุด IRB ได้รับความรักและความสนใจ และ Ruby 2.7 ยังคงเพิ่มเติม
เรากำลังได้รับ:
- การแก้ไขหลายบรรทัด (Multi-line editing)
- ไฮไลท์ไวยากรณ์ (Syntax Highlighting)
- การรวม RDP ในตัว (Built-in RDoc integration)
- ประวัติคำสั่งเปิดใช้งานโดยค่าเริ่มต้น
- การเติมอัตโนมัติเปิดใช้งานโดยค่าเริ่มต้น
จริงๆ แล้ว:
นี่คือการเปลี่ยนแปลงใหญ่มาก จนคุณได้รับคำเตือนเมื่อเริ่ม irb ด้วย Ruby 2.7
หากคุณต้องการใช้ irr เวอร์ชันเก่ายังคงได้ ด้วยคำสั่ง irb --legacy ปัญหาหลักของผมกับ IRB ใหม่นี้คือการแก้ไขบรรทัด ใน IRB แบบเก่า (หรือ Pry) ผมสามารถกด ALT และลูกศรซ้ายเพื่อเลื่อนเร็วขึ้น แตไม่ทำงานใน IRB ใหม่
ลองดูว่ามันทำงานอย่างไรสำหรับคุณ
Ruby Pattern Matching [Experimental]
ฟีเจอร์ที่ขอบ่อยๆ ที่จะมาถึงใน 2.7 คือ pattern matching
มันถูกทำเครื่องหมายว่าเป็น experimental
แต pattern matching คืออะไร และมันให้ประโยชน์อย่างไร?
จริงๆ แล้ว หากผมเข้าใจถูก Pattern matching เหมือน regular expressions แตสำหรับโครงสร้างข้อมูล (Array/Hash)
ตัวอย่าง:
[1,2,3] in [a,b,c] # true [1,2,3] in [a] # false
หากมีการจับคู่ ชื่อตัวแปรเหล่านี้ (เช่น a) จะกลายเป็นตัวแปรท้องถิ่นที่คุณเข้าถึงได้
ตัวอย่างกับแฮช:
{ a: 1, b: 2, c: [] } in { a: a, b: b, c: [] } # true
p a # 1
สิ่งนี้ใช้คีย์เวิร์ด in
มันไม่ใหม่ แตไม่คุ้นเคย เพราะก่อน Ruby 2.7 in ใช้เฉพาะส่วนหนึ่งของลูป for (ซึ่งไม่แนะนำใน Ruby) ดังนั้นเราจึงนำคีย์เวิร์ดนี้กลับมาใช้ใหม่เพื่อสิ่งที่มีประโยชน์
ดีกว่านั้น...
ไม่สำคัญว่าคุณใช้ตัวแปรอะไร a,b,c ที่นี่ทำงาน แต f,g,h ก็ทำงานเช่นกัน
มันทั้งหมดเกี่ยวกับรูปแบบ (pattern)!
การเปลี่ยนแปลงอื่นๆ
การเปลี่ยนแปลงเพิ่มเติมบางอย่างที่คุ้มค่าที่จะกล่าวถึง
- New compaction GC ปรับปรุง memory fragmentation
- Method argument
**nilประกาศตอนนี้ว่าเมธอดไม่รับคีย์เวิร์ด - Method argument
...เพิ่มกลไกการส่งต่ออาร์กิวเมนต์ (parenthesis required, เช่นmake_salad(...)) - การปรับปรุง Fiber พูลออบเจ็กต์ fiber ใหม่ (ซึ่ง fiber ใหม่ถูกจัดสรรจากที่นี่) ทำให้ fiber มีประสิทธิภาพมากขึ้น
- การปรับปรุง Thread วิธีที่ดีกว่าและเพิ่มประสิทธิภาพมากขึ้นในการสร้าง thread ทำให้ multi-threading เร็วขึ้น
คุณคิดอย่างไรเกี่ยวกับเหล่านี้?
ไฟล์ NEWS สำหรับ 2.7 กล่าวถึงการปรับปรุงประสิทธิภาพ 10x สำหรับการสร้าง fiber และ thread ทั้งคู่ ผมยังไม่ได้ทดสอบเอง แตหากคุณทำ แจ้งให้ผมทราบผลลัพธ์ของคุณ
สรุป
ตอนนี้คุณทันสมัยกับการเปลี่ยนแปลงล่าสุดของภาษา Ruby แล้ว! คุณเรียนรู้เกี่ยวกับการเปลี่ยนแปลง IRB เมธอดใหม่ และฟีเจอร์ทดลองบางอย่างเช่น pattern matching
โปรดแชร์บทความนี้เพื่อเผยแพร่ข่าว!
ขอบคุณที่อ่าน 🙂