Ruby 3.3 เปิดตัวแล้ว
(ruby-lang.org)- YJIT ปรับปรุงประสิทธิภาพและการใช้หน่วยความจำอย่างมากเมื่อเทียบกับ Ruby 3.2 และเร็วกว่าอินเทอร์พรีเตอร์มากกว่า 3 เท่าใน Optcarrot
- Code GC ของ YJIT ถูกปิดใช้งานเป็นค่าเริ่มต้น และ
--yjit-exec-mem-sizeทำงานเป็น hard limit ที่หยุดการคอมไพล์โค้ดใหม่ - เพิ่ม
RubyVM::YJIT.enableทำให้สามารถเปิดใช้งาน YJIT ขณะรันไทม์ได้โดยไม่ต้องเปลี่ยนอาร์กิวเมนต์บรรทัดคำสั่งหรือตัวแปรสภาพแวดล้อม - เพิ่มพาร์เซอร์ Prism เป็น gem พื้นฐาน และสามารถใช้ API
Prism.parse(source),Prism.parse_comments(source),Prism.parse_success?(source)ได้ - สามารถทดลองคอมไพเลอร์ Prism ได้ด้วย
ruby --parser=prismหรือRUBYOPT="--parser=prism"แต่แฟล็กดังกล่าวมีไว้สำหรับดีบักเท่านั้น - ตัวสร้างพาร์เซอร์ถูกเปลี่ยนจาก Bison เป็น Lrama และพาร์เซอร์ภายในของ Lrama ถูกเปลี่ยนเป็น LR parser ที่สร้างโดย Racc เพื่อให้บำรุงรักษาได้ง่ายขึ้น
- คอมไพเลอร์ JIT แบบ pure-Ruby RJIT มาแทนที่ MJIT แต่รองรับเฉพาะสถาปัตยกรรม x86-64 บน Unix และจำกัดไว้เพื่อการทดลองเท่านั้น
- มีการนำ M:N thread scheduler มาใช้ โดยให้ N เธรดเนทีฟจัดการ M เธรดของ Ruby แต่อาจทำให้ความเข้ากันได้กับส่วนขยาย C เสียหาย จึงปิดใช้งานเป็นค่าเริ่มต้นใน main Ractor
- วิธีการที่
itถูกเรียกโดยไม่มีอาร์กิวเมนต์และถูกใช้ในบล็อกที่ไม่มีพารามิเตอร์ปกติจะถูกเลิกสนับสนุน (deprecation) และใน Ruby 3.4 จะกลายเป็นการอ้างอิงพารามิเตอร์ตัวแรกของบล็อก Regexp::newอนุญาตอาร์กิวเมนต์ได้สูงสุด 2 ตัวเท่านั้น แทนการเรียกแบบ 3 อาร์กิวเมนต์ที่ถูกเลิกสนับสนุนใน Ruby 3.2ext/readlineถูกปลดระวาง และต่อไปจะพึ่งพาrelineซึ่งเป็นการใช้งานแบบ pure Ruby ที่เข้ากันได้กับ API ของext/readline- หากต้องใช้
ext/readlineสามารถติดตั้งจาก rubygems.org ด้วยgem install readline-extได้ และไม่จำเป็นต้องติดตั้งไลบรารีอย่างlibreadlineหรือlibeditอีกต่อไป - RubyGems และ Bundler จะแจ้งเตือนเมื่อมีการ
requiregem บางรายการโดยไม่ได้เพิ่ม gem เหล่านั้นไว้ใน Gemfile หรือ gemspec และ gem เหล่านี้จะกลายเป็น bundled gem ใน Ruby เวอร์ชันอนาคต - เมื่อใช้ gem bootsnap คำเตือนดังกล่าวจะถูกระงับ และเนื่องจากข้อจำกัดของเวอร์ชันนี้ แนะนำให้รันแอปพลิเคชันอย่างน้อยหนึ่งครั้งพร้อมตัวแปรสภาพแวดล้อม
DISABLE_BOOTSNAP=1 - เพิ่ม
prism 0.19.0เป็น gem พื้นฐาน และracc 1.7.3ถูกยกระดับจาก default gem เป็น bundled gem
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
มองว่าใน Ruby 3.3 นั้น Ruby กลับมาอย่างยิ่งใหญ่แล้ว ภาษาที่เคยโฟกัสความสุขของนักพัฒนาแต่ถูกล้อว่าเชื่องช้า ตอนนี้ไม่ช้าอีกต่อไปแล้ว
YJIT เป็นเทคโนโลยีที่น่าทึ่ง และเมื่อรวมกับ object shape รวมถึงการปรับแต่ง garbage collection หลายอย่าง Ruby ก็กำลังเร็วขึ้นพอสมควร ผู้ใช้ Ruby รายใหญ่อย่าง Shopify ก็เปิดใช้ YJIT บนเวอร์ชัน pre-release ของ 3.3 ใน production และรายงานว่าประสิทธิภาพดีขึ้นเป็นเปอร์เซ็นต์สองหลัก
ส่วนตัวแล้วตื่นเต้นมากกับ Ruby และอนาคตของมัน และอยากลองทำงานด้วย Ruby 3.3 แล้วนำไปใช้กับไซต์ production ของลูกค้า
https://railsatscale.com/2023-09-18-ruby-3-3-s-yjit-runs-sho...
เคยใช้เป็นโค้ดกาวระหว่างที่เก็บ DNS record บน Redis กับ PowerDNS ด้วย โดยทั้งสแต็กประมวลผลคิวรี 500 ล้านครั้งต่อเดือนบน VPS เล็ก ๆ 14 เครื่อง และแทบไม่เห็นร่องรอยใน htop เลย ที่ใช้ PowerDNS ไม่ใช่เพราะเรื่องประสิทธิภาพ แต่เพราะโดยทั่วไปไม่ใช่ความคิดที่ดีที่จะ implement สิ่งอย่างการเข้ารหัส, HTTP, DNS ที่เปิดออกสู่อินเทอร์เน็ตสาธารณะด้วยตัวเอง
ความย้อนแย้งของเว็บยุคนี้คือ เว็บแอปที่สร้างด้วย Ruby ที่ “ช้า” และ server rendering กลับโหลดหน้าได้เร็วกว่า database แบบ eventual consistency ที่ช้าจริง ๆ กับ frontend web app ที่อ้วนเทอะทะ ในเว็บสมัยใหม่ เราเห็น loading spinner บ่อยเกินไปแม้แต่ตอนทำเรื่องเล็กน้อย
กดลิงก์ไปดูแล้วพบว่าเป็น การดีขึ้นระดับสิบกว่าเปอร์เซ็นต์ คิดว่าคงเปลี่ยนภาพจำที่ว่า Ruby ช้ากว่าภาษา “เร็ว” อย่าง Rust, Java, Go, C++ ประมาณ 50–200 เท่าได้ไม่มากนัก
Ruby 3.3 ดูเหมือนจะเป็นหนึ่งในรีลีส Ruby ที่สำคัญและมีฟีเจอร์มากที่สุดในรอบ 10 ปีที่ผ่านมา ไม่คิดว่าจะมี JIT ที่พร้อมใช้งานใน production ออกมาก่อน Python และยังมี Prism, Lrama, IRB ด้วย
แต่สิ่งที่ยังถูกพูดถึงไม่พอคือ Ractor, M:N thread scheduler, Fiber, Async โดยเฉพาะในบริบทของ Rails อยากฟังความคิดเห็นว่ามีใครใช้ฟีเจอร์เหล่านี้ใน production หรือไม่
ถึงอย่างนั้น Ractor ก็ควรได้รับความสนใจมากกว่านี้ เป็นฟีเจอร์ใหญ่มาก
เดาว่าภายในบริษัทต่าง ๆ คงมีโซลูชัน custom ส่วนตัวบน RabbitMQ หรือ Redis อยู่เป็นพัน ๆ แบบ
ทุกปีในวันคริสต์มาสเหมือนตั้งนาฬิกาไว้ Ruby Lang จะออกรุ่นใหม่เสมอ
ใช้งานบน Heroku ได้แล้ว: https://devcenter.heroku.com/changelog-items/2772
ดูดีนะ IRB ตัวใหม่คือ interactive Ruby interpreter ที่มี autocomplete และการดีบักดีขึ้น การเปลี่ยนแปลงส่วนใหญ่ใน Ruby 3.3 น่าจะนำไปสู่การปรับปรุงเครื่องมือสำหรับนักพัฒนา
API ของภาษายังคงสอดคล้องกับรีลีสก่อนหน้าโดยรวม ผมเขียนคู่มืออัปเดต Ruby 3.3 พร้อมโน้ตสำหรับ version manager หลายตัวไว้แล้ว: https://mac.install.guide/ruby/update.html
สงสัยอยู่ว่าควรแนะนำ version manager ตัวไหนดี ก่อนหน้านี้เคยแนะนำ asdf, frum, chruby
ตอนนี้สามารถยกเลิก name resolution อย่าง
Socket.getaddrinfoได้แล้ว และว่ากันว่าจะสร้าง worker pthread ทุกครั้งที่ต้อง resolve ชื่อ แล้วรันgetaddrinfo(3)ในนั้นสงสัยว่า runtime ของภาษาอื่นก็ทำคล้ายกันไหม การสร้าง thread ดูหนักเกินไป แต่ในทางปฏิบัติอาจไม่ใช่ปัญหาใหญ่ก็ได้ แม้ตาม benchmark ของตัวเอง overhead จะน้อยแต่ก็ไม่ใช่ศูนย์
10000.times { Addrinfo.getaddrinfo("www.ruby-lang.org", 80) }ใช้เวลา 2.3 วินาทีก่อนแพตช์ และ 3.0 วินาทีหลังแพตช์ ส่วน100.times { URI.open("https://www.ruby-lang.org").read }ใช้เวลา 3.36 วินาทีก่อนแพตช์ และ 3.40 วินาทีหลังแพตช์ไม่ได้ reimplement operation เดิมด้วย “สี” แบบ async เหมือน Python แต่รู้สึกเหมือนทุกอย่างถูกย้ายไปเป็น asynchronous โดยค่าเริ่มต้น ไม่แน่ใจว่าเข้าใจถูกไหม
หากรู้ Python กับ NodeJS อยู่แล้ว ก็สงสัยว่า Ruby ยังควรค่าแก่การเรียน หรือไม่ Ruby ดูน่าสนใจแต่ก็รู้สึกว่ายาก
ถ้าเชี่ยวชาญ Node และ Python อยู่แล้ว ก็น่าจะเรียนได้ค่อนข้างง่าย ข้อเสียคือถ้ารู้ภาษาเหล่านั้นอยู่แล้ว มันไม่ได้ให้อะไรใหม่ในเชิงพื้นฐานนัก ข้อดีส่วนใหญ่เป็นเรื่องสุนทรียะ Ruby มีและสนับสนุนวิธีแสดงโค้ดให้สวยงามจริง ๆ และการได้สัมผัสสิ่งนั้นก็สนุก
แม้จะทำงานกับโค้ดเบส TypeScript เป็นหลัก แต่เวลาจัดการข้อมูลล็อกหรือข้อความกึ่งมีโครงสร้าง หรือทำการเขียนใหม่ตาม regex ในหลายไฟล์ ก็มักหยิบ Ruby มาใช้ Ruby สนุกมาก และในบรรดาภาษาที่เคยใช้เป็นประจำ น่าจะเป็นภาษาที่สนุกที่สุด จึงเป็นรางวัลในตัวเอง
ตัวอย่างใหญ่ที่สุดคือ Ruby ชอบ บล็อก มาก มีอยู่ทั่วทั้งไลบรารีมาตรฐาน มี syntax sugar มากมาย และมี DSL ที่สร้างรอบบล็อกนับไม่ถ้วน ฟีเจอร์เชิงฟังก์ชันมาตรฐานก็อยู่ในไลบรารีมาตรฐานมานานแล้ว ทำให้เขียนสไตล์ฟังก์ชันได้ลื่นไหลและอ่านง่าย
ใน Python ส่วนใหญ่ทำได้ในทางเทคนิค แต่ดูเขียนและอ่านเก้งก้างกว่ามาก Python มี lambda แต่ให้ความรู้สึกว่าไม่ค่อยชอบให้ใช้เกินงานเล็ก ๆ น้อย ๆ และแทนที่จะเป็นเช่นนั้น ฟังก์ชันถูกใช้เป็นค่า first-class ได้ทุกที่
คนที่ไวต่อเทคโนโลยีใหม่ ๆ กำลังย้ายไปสู่การพัฒนาแบบเน้น API บน node.js และ AngularJS ซึ่งเร็วกว่าอย่างมากเมื่อเทียบกับสิ่งที่สร้างด้วย RoR ในปี 2013 วิธีมาตรฐานของ RoR ยังเป็นแบบโมโนลิทิก และดูแก่ลงเพราะปรับตัวเข้ากับพาราไดม์ใหม่ของการแยกฟรอนต์เอนด์/แบ็กเอนด์ได้ไม่ดี
เหตุผลที่พูดถึงเฟรมเวิร์กที่สร้างด้วย Ruby ยาว ๆ แทนที่จะพูดถึง Ruby เอง คือแม้ตอนนี้ก็คาดว่า 95% ของการพัฒนา Ruby น่าจะเป็นแอปพลิเคชัน Rails Ruby มีชื่อเสียงขึ้นมาส่วนใหญ่เพราะ Ruby on Rails และถ้า RoR อยู่ในขาลง Ruby ก็น่าจะเดินตามเส้นทางเดียวกันจนเหลือเป็นชุมชนเล็ก ๆ ที่มีแฟนเหนียวแน่น คล้าย Perl
ถ้ามองเฉพาะตัวภาษาเอง นึกเหตุผลไม่ออกว่าจะเลือก Ruby แทน Python หรือ TypeScript ทำไม ดูเหมือน Ruby ไม่ได้ทำอะไรได้ดีกว่าคู่แข่งที่ตั้งหลักได้มั่นคงกว่าแล้ว ไม่ว่าจะในแง่ภาษา หรือแพลตฟอร์ม
Prism น่าสนใจ สงสัยว่ามีเครื่องมือวิเคราะห์โค้ด Ruby ที่ใช้สิ่งนี้หรือไม่ กำลังมองหาวิธีวิเคราะห์โค้ดของบริษัทอยู่
ว่ากันว่าตัวแปรสภาพแวดล้อม
RUBY_MAX_CPU=nตั้งค่าสูงสุดเป็น N ตัว หรือก็คือจำนวนเนทีฟเธรดสูงสุด และค่าเริ่มต้นคือ 8รู้สึกว่าค่าเริ่มต้นควรเป็น จำนวน logical core เหมือน Rust Tokio หรือ runtime แบบ M:N อีกมากมายไม่ใช่หรือ
init()หรือmain()ใน Ruby 4.0 อยากให้อนุญาต explicit import แทนวิธีปัจจุบันที่นำ gem เข้ามาใน namespace แบบ global และ implicit
ยังมีการถกเถียงเรื่องฟีเจอร์ “namespace on read” ที่อยู่ในขั้นคาดการณ์ด้วย: https://bugs.ruby-lang.org/issues/19744
การที่ global namespace รองรับได้แค่เวอร์ชันเดียวของแต่ละ gem พอดี ยังช่วยส่งเสริมวัฒนธรรมที่ดี ซึ่งให้ความสำคัญกับ ABI ที่เสถียรและช่วงเวลาผ่อนผันก่อนเลิกใช้ เมื่อเทียบกับระบบนิเวศของบางภาษาแล้ว นี่เหมือนฝันเลย
หรือไม่ก็อาจกำลังพูดผิดไปทั้งหมดก็ได้
https://youtu.be/4MM5b2F9zrM?si=UT3aUbD6p_uBZehS&t=2347