- เปิดตัว Ruby 4.0.0 โดยเพิ่ม Ruby Box และ ZJIT พร้อมการปรับปรุงด้านประสิทธิภาพและตัวภาษาอีกจำนวนมาก
- Ruby Box เป็นฟีเจอร์ทดลองที่สามารถ รันแบบแยกขอบเขต สำหรับคลาส โมดูล ตัวแปรโกลบอล และการประกาศไลบรารีทั้งแบบ native/Ruby
- ZJIT คือ คอมไพเลอร์ JIT รุ่นถัดไปที่พัฒนาด้วย Rust ซึ่งขยายโครงสร้างได้ดีกว่า YJIT เดิม และเอื้อต่อการมีส่วนร่วมจากภายนอก
- โมเดลการรันขนาน Ractor ได้รับการปรับปรุงทั้งด้านเสถียรภาพและประสิทธิภาพ และมีแผนจะยกเลิกสถานะ experimental ในอนาคต
- อัปเดตครอบคลุมคลาสหลัก มาตรฐานไลบรารี C API, GC, JIT และส่วนอื่น ๆ เพื่อเสริม ประสิทธิภาพและความสามารถในการขยายตัวของ ecosystem ของ Ruby
ภาพรวม Ruby 4.0
- Ruby 4.0.0 เป็นอัปเดตครั้งใหญ่ที่มี Ruby Box และ ZJIT เป็นแกนหลัก
- มีการปรับปรุงในหลายด้าน เช่น การรันขนาน ไวยากรณ์ของภาษา มาตรฐานไลบรารี GC และ JIT
- ดาวน์โหลดได้ในรูปแบบ
.tar.gz, .tar.xz, .zip
Ruby Box
- Ruby Box เป็น ฟีเจอร์ทดลอง ที่ให้การแยกขอบเขตของการประกาศต่าง ๆ
- เปิดใช้งานด้วยการตั้งค่า environment variable
RUBY_BOX=1 และใช้คลาส Ruby::Box
- การประกาศที่โหลดภายใน box จะถูกแยกจากภายนอก ทำให้ monkey patch, ตัวแปรโกลบอล/ตัวแปรคลาส, การประกาศคลาส/โมดูล และการเปลี่ยนแปลงไลบรารีไม่ส่งผลต่อ box อื่น
- ตัวอย่างการใช้งานหลัก
- รันแบบแยกขอบเขต ระหว่าง test case
- รันเว็บแอปแบบขนานสำหรับ blue-green deployment
- รันแบบขนานเพื่อตรวจสอบการอัปเดต dependency
- มีแผนจะใช้เป็น API พื้นฐานสำหรับ “package API” ระดับสูงในอนาคต
ZJIT
- ZJIT คือ คอมไพเลอร์ JIT ใหม่ ที่พัฒนาขึ้นในฐานะรุ่นถัดไปของ YJIT
- ต้องใช้ Rust 1.85.0 ขึ้นไป และเปิดใช้งานด้วยออปชัน
--zjit
- รองรับหน่วยคอมไพล์ขนาดใหญ่ขึ้นบนพื้นฐาน SSA IR และมีโครงสร้างที่เอื้อต่อการมีส่วนร่วมจากภายนอก
- ปัจจุบันเร็วกว่าตัว interpreter แต่ยังช้ากว่า YJIT
- ยังไม่แนะนำให้ใช้ใน production และมีแผนปรับปรุงประสิทธิภาพใน Ruby 4.1
การปรับปรุง Ractor
- เพิ่มคลาส Ractor::Port เพื่อแก้ปัญหาการส่งและรับข้อความ
Ractor.shareable_proc ช่วยให้แชร์อ็อบเจ็กต์ Proc ระหว่าง Ractor ได้ง่ายขึ้น
- ปรับปรุงโครงสร้างข้อมูลภายในเพื่อลด การแย่งกันใช้ global lock และเพิ่มความขนาน
- มีแผนจะ ยกเลิกสถานะ experimental ของ Ractor ในปีหน้า
การเปลี่ยนแปลงของภาษา
*nil จะไม่เรียก nil.to_a อีกต่อไป (ทำงานเหมือน **nil)
- ตัวดำเนินการตรรกะ (
||, &&, and, or) รองรับไวยากรณ์ line continuation (dot chaining)
- เพิ่มความอ่านง่ายและความสอดคล้องของโค้ด
อัปเดตคลาสหลัก
- Array: เพิ่ม
Array#rfind, Array#find เพื่อรองรับการค้นหาอย่างมีประสิทธิภาพ
- Binding: ยกเว้น numbered parameter และเพิ่มเมธอดที่เกี่ยวข้องกับ
implicit_parameters
- Enumerator: เพิ่ม keyword argument
size: ให้กับ produce
- ErrorHighlight: เมื่อเกิด
ArgumentError จะแสดงโค้ด snippet ของตำแหน่งเรียกและตำแหน่งประกาศ
- Fiber/Fiber::Scheduler: เพิ่ม
raise(cause:), fiber_interrupt, yield เป็นต้น
- File: รองรับ
File::Stat#birthtime บน Linux
- IO: อนุญาต timeout แบบ
Float::INFINITY และยกเลิกการสร้างโปรเซสแบบอิง pipe
- Kernel: ปรับแต่ง
#inspect ได้ และยกเลิกการสร้าง pipe ผ่าน Kernel#open
- Math: เพิ่ม
log1p, expm1
- Pathname: เลื่อนจาก default gem เป็น core class
- Proc: ทำให้รูปแบบการแสดงผลของ anonymous parameter เป็นมาตรฐานเดียวกัน
- Ractor: เปลี่ยนโครงสร้างการสื่อสารเป็นแบบ
Ractor::Port และลบ Ractor.yield เป็นต้น
- Set: เลื่อนเป็น core class และทำให้รูปแบบ
inspect เรียบง่ายขึ้น
- Socket: เพิ่มอาร์กิวเมนต์
open_timeout และทำให้ข้อยกเว้น timeout เป็นรูปแบบเดียวกัน
- String: รองรับ Unicode 17.0.0 และ Emoji 17.0 พร้อมขยายเมธอดตระกูล
strip
- Thread: รองรับอาร์กิวเมนต์
raise(cause:)
อัปเดตมาตรฐานไลบรารี (Stdlib)
- เลื่อนเป็น default gem:
ostruct, pstore, benchmark, logger, rdoc, win32ole, irb, reline, fiddle เป็นต้น
- เพิ่ม default gem:
win32-registry 0.1.2
- อัปเดต default gem:
RubyGems 4.0.3, bundler 4.0.3, openssl 4.0.0, json 2.18.0 เป็นต้น
- อัปเดต bundled gem:
minitest 6.0.0, rake 13.3.1, rbs 3.10.0, debug 1.11.1 เป็นต้น
- รวม RubyGems/Bundler 4 มาด้วย
การรองรับแพลตฟอร์ม
- Windows: เลิกซัพพอร์ตเวอร์ชันต่ำกว่า MSVC 14.0 (ต้องใช้ Visual Studio 2015 ขึ้นไป)
การเปลี่ยนแปลงด้านความเข้ากันได้
- ลบ
Ractor.yield, Ractor#take, Ractor#close_incoming, Ractor#close_outgoing
- เลิกใช้
ObjectSpace._id2ref
- ลบ
Process::Status#&, #>>
- ทำให้การแสดงผล internal frame (backtrace) เรียบง่ายขึ้น
- ใน backtrace ของ
ArgumentError จะแสดง ชื่อคลาส/โมดูลของ receiver
ความเข้ากันได้ของมาตรฐานไลบรารี
- ลบไลบรารี CGI โดยคงไว้เฉพาะ
cgi/escape
- เมื่อ
Set ถูกเลื่อนเป็น core class, SortedSet จะต้องติดตั้งเป็น gem แยกต่างหาก
- ยกเลิกการตั้งค่า header
Content-Type อัตโนมัติของ Net::HTTP
อัปเดต C API
- ปิดใช้งาน
rb_thread_fd_close และแนะนำให้ใช้ rb_io_close
rb_thread_call_with_gvl ทำงานได้ไม่ว่าจะมี GVL หรือไม่
- เพิ่ม C API สำหรับ Set (
rb_set_new, rb_set_add, rb_set_delete เป็นต้น)
การปรับปรุง implementation และประสิทธิภาพ
- เพิ่มความเร็วในการเรียก
Class#new โดยเฉพาะเมื่อใช้ keyword argument
- ลดการใช้หน่วยความจำด้วยการเติบโตแบบอิสระของ GC heap pool
- เพิ่มความเร็วในการ sweep อ็อบเจ็กต์ขนาดใหญ่
- ปรับแต่งการคำนวณ
object_id, hash และการเข้าถึง instance variable
- ปรับปรุงประสิทธิภาพของ Ractor
- โครงสร้าง hash แบบไร้ lock, ลดการแย่ง cache และปรับแต่งการจัดสรรอ็อบเจ็กต์
- แก้บั๊กที่เกี่ยวข้องกับ deadlock, encoding และ GC
เกี่ยวกับ JIT
- ZJIT: JIT แบบอิงเมธอด ต้องใช้ Rust 1.85.0 ขึ้นไป เปิดใช้งานด้วย
--zjit หรือ RubyVM::ZJIT.enable
- YJIT: เปลี่ยนออปชันสถิติ และเพิ่ม
mem_size: กับ call_threshold:
- RJIT: ลบ
--rjit และย้ายไปยัง repository แยก
ขนาดของการเปลี่ยนแปลง
- เมื่อเทียบกับ Ruby 3.4.0 มี การเปลี่ยนแปลง 3,889 ไฟล์, เพิ่ม 230,769 บรรทัด, ลบ 297,003 บรรทัด
- Ruby 4.0 เป็นเมเจอร์รีลีสที่ยกระดับ ประสิทธิภาพ ความขนาน และความสอดคล้องของภาษา อย่างมาก
ดาวน์โหลด
- มีให้ในรูปแบบ
ruby-4.0.0.tar.gz, ruby-4.0.0.tar.xz, ruby-4.0.0.zip
- ระบุ ค่าแฮช SHA1, SHA256, SHA512 ของแต่ละไฟล์
เกี่ยวกับ Ruby
- Ruby เป็นภาษาโอเพนซอร์สที่ Yukihiro Matsumoto (Matz) พัฒนาขึ้นในปี 1993
- ทำงานได้บนหลายแพลตฟอร์ม และถูกใช้อย่างแพร่หลายทั่วโลก โดยเฉพาะในด้าน การพัฒนาเว็บ
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
สุขสันต์วันเกิด Ruby!
คนมักพูดกันว่า “เลิกใช้ Ruby เพราะมันไม่มี type” แต่ตอนนี้ RBS กำลังค่อย ๆ กลายเป็นมาตรฐานแล้ว Sorbet ก็รองรับมัน และยังมี inline notation ที่เขียน type ไว้ข้าง ๆ โค้ดได้เลย
อีกอย่าง คำพูดที่ว่า “Ruby มี LSP ที่อ่อน” ก็เป็นเรื่องอดีตไปแล้ว ตอนนี้ ruby-lsp กลายเป็นมาตรฐาน และรองรับ “go to definition” ด้วย สถาปัตยกรรมปลั๊กอินทำให้หลายเครื่องมือสามารถใช้ AST เดียวกันซ้ำได้
เรื่องการทำงานขนานก็พัฒนาขึ้นมากเพราะ Ractor และตอนนี้ถ้าปรับแต่ง GC อีกหน่อยก็น่าจะพ้นจากขั้นทดลองแบบเต็มตัวได้แล้ว
ยังมีฟีเจอร์ใหม่อย่าง ZJIT และ Box ด้วย แต่ตอนนี้ก็ยังไม่แนะนำให้ใช้ในโปรดักชัน ถึงอย่างนั้นมันก็ค่อย ๆ ดีขึ้นเรื่อย ๆ
ผมคิดว่าการที่ไวยากรณ์ไม่เปลี่ยนแบบหักโหมก็เป็นข้อดีเหมือนกัน
คริสต์มาสต้องมี Ruby เวอร์ชันใหม่ออกมาเสมอ
รอบนี้ ruby::box ดูน่าสนใจ มันช่วยให้ rollout ฟีเจอร์โดยรันสองเวอร์ชันพร้อมกันได้
และการที่ตอนนี้สามารถเขียน
if condition1 && condition2ข้ามหลายบรรทัดได้ก็เจ๋งดีเหมือนกันif condition1 && condition2ข้ามหลายบรรทัดมานานแล้วและมันก็ทำงานได้ปกติ ไม่แน่ใจว่าไวยากรณ์ใหม่นี้ต่างจากเดิมยังไงดีใจที่ Ruby 4.0 ออกแล้ว แต่ในปี 2025 ผมเปลี่ยนไปใช้ Python แบบเต็มตัว แล้ว
Claude Code แปลงโปรเจกต์ Ruby ของผมเป็น Python 100% ให้อัตโนมัติ และหลังจากนั้นก็ไม่เหลือเหตุผลให้ใช้ Ruby อีก
ผมรัก Ruby มานานกว่าสิบปีและยังเคยเขียนหนังสือเกี่ยวกับมัน แต่ตอนนี้ fastapi, pytorch, langchain, streamlit และ ecosystem ต่าง ๆ ทำให้ Python ชนะไปแล้ว ถึงอย่างนั้นผมก็ยังคิดว่าไวยากรณ์ของ Ruby สวยที่สุดอยู่ดี
คริสต์มาสจะขาด Ruby เวอร์ชันใหม่ไปไม่ได้จริง ๆ ขอบคุณ Matz และทีม
ถ้าอยากเรียน Ruby ในช่วงปี 2025~26 มีแหล่งข้อมูลใหม่ ๆ ที่น่าแนะนำไหม? นอกจากเอกสารทางการแล้วก็อยากรู้ว่ามีหนังสือดี ๆ อะไรบ้าง
คอร์ส Ruby on Rails ของ Pragmatic Studio
Ruby เป็นภาษาที่น่าทึ่งจริง ๆ ไม่นานมานี้ผมสร้าง เลเยอร์บน Rails ที่ใช้ไฟล์ Markdown แค่ไฟล์เดียวเพื่อสร้าง API ขึ้นมา ถ้าจะทำแบบเดียวกันใน Python คงซับซ้อนกว่านี้มาก ถ้าเป็น JavaScript ก็น่าจะยิ่งเลวร้ายกว่าอีก ความสามารถด้าน metaprogramming ของ Ruby นี่โดดเด่นจริง ๆ
ดีใจที่ stack trace ภายในถูกจัดระเบียบแล้ว สักวันหนึ่งถ้ารองรับ relative path ด้วยก็คงดี และก็ดีใจที่ Set ได้รับการปฏิบัติอย่างสมศักดิ์ศรีเสียที
ตอนนี้ผมทำงานที่บริษัทที่ไม่ได้ใช้ Ruby แล้ว แต่ก็ยังรัก Ruby อย่างลึกซึ้งอยู่ ขอบคุณสำหรับรีลีสนี้ และหวังว่าจะมีโอกาสได้กลับมาใช้อีก
เคยได้ยินมาก่อนว่าฟีเจอร์ Ruby::Box (namespace) ทำให้เกิด performance regression รุนแรง ไม่รู้ว่าครั้งนี้มีการปรับปรุงแล้วหรือยัง
อยากรู้ว่า tooling ดีขึ้นไหม ผมยังไม่เคยทำให้ LSP รันบน Windows ได้อย่างสมบูรณ์เลย