1 คะแนน โดย GN⁺ 21 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • เป็นการทดลองโปรเจกต์ส่วนตัวในการย้าย Rust webapp crate ไปเป็น Ruby on Rails โดยเป้าหมายคือโค้ด 14,943 บรรทัดที่สร้างบน Tera และ Axum
  • โครงสร้าง Rust เดิมมี ต้นทุนด้านการทดสอบ สูง เพราะต้องใช้ Playwright E2E, เนมสเปซฐานข้อมูลแบบแยก, mock service และแม้แต่ internal API crate
  • จากการเปรียบเทียบด้วย LLM หลายตัว Rails ได้คะแนนรวม 710 สูงกว่า Rust/Axum/Diesel ที่ 480 โดยถูกประเมินว่าเด่นด้าน ความเร็วในการพัฒนา และความง่ายของ unit test
  • การแปลงแบบ one-shot ด้วย Local Qwen3.6 ใช้เวลาราว 30 นาที และโค้ด Ruby ลดเหลือ 3,322 บรรทัด แต่ยัง ไม่ได้ตรวจสอบการรันจริง
  • จุดแข็งของ Rails คือฟังก์ชันพื้นฐานที่มีมาให้และการทดสอบที่กระชับกว่า ส่วนข้อด้อยเรื่อง type safety ของ Ruby สามารถเสริมได้ด้วย Sorbet หรือการเพิ่ม type ด้วยเอเจนต์

เบื้องหลังของการทดลองย้ายระบบ

  • Rust webapp crate ที่เป็นส่วนหนึ่งของโปรเจกต์ส่วนตัวถูกเลือกให้เป็นเป้าหมายของการย้ายไป Ruby on Rails
    • โปรเจกต์ทั้งหมดมีขนาดราว 30,000 บรรทัด และ crate ที่จะย้ายมีลักษณะใกล้เคียงเว็บแอปที่เขียนด้วย Tera และ Axum
    • โค้ด Rust ที่อยู่ในขอบเขตการย้ายมีทั้งหมด 14,943 บรรทัด และใช้เวลาคอมไพล์ราว 10 วินาที
    • แม้ตัวโค้ดจะไม่ได้ใหญ่ แต่มีโครงสร้างที่พึ่งพาสิ่งอื่นตามมาค่อนข้างมาก
  • โครงสร้าง Rust เดิมมีต้นทุนการทดสอบสูง
    • การทดสอบแบบ E2E ต้องตั้งค่า Playwright
    • การทำ mocking ทำได้ยาก จึงต้องมีเนมสเปซฐานข้อมูลแบบแยกและ mock service
    • ยังต้องมี internal API crate แยกต่างหากเพื่อให้ Playwright โต้ตอบกับแอปในโหมด headless ได้
  • Ruby และ Ruby on Rails ถูกพิจารณาในฐานะทางเลือกที่กระชับกว่า
    • Ruby ไม่มี type ในตัว จึงอาจมีความเสถียรน้อยกว่า Rust
    • หากใช้ Sorbet ก็สามารถช่วยเสริม type safety ใน Ruby ได้บางส่วน
  • เมื่อนำหลายอินสแตนซ์ของ LLM มาเปรียบเทียบความซับซ้อน ความเสถียร ความง่ายในการทดสอบ และปัจจัยอื่น ๆ ผลคือ Rails ได้คะแนนสูงกว่า
    • คะแนนรวมของ Rust/Axum/Diesel คือ 480, Rails คือ 710, และ Rails + Sorbet คือ 695
    • Rails ได้คะแนนสูงในด้านความเหมาะกับนักพัฒนาเดี่ยว 90, ความเร็วในการพัฒนา 90 และความง่ายของ unit test 90
    • Rust/Axum/Diesel ได้คะแนนสูงด้านความปลอดภัย 95 และประสิทธิภาพ 95 แต่ได้คะแนนต่ำด้านความง่ายของ unit test 20 และ integration test 30
    • จากผลรวมแบบตรงไปตรงมา จึงมองว่าแอป Rails อาจให้ผลลัพธ์ที่ดีกว่า 1.47 เท่า

ผลลัพธ์ของการแปลงและจุดที่ต้องพิจารณา

  • มีการแปลงโปรเจกต์ขนาดค่อนข้างเล็กแบบ one-shot ด้วย Local Qwen3.6
    • การแปลงใช้เวลาประมาณ 30 นาที
    • ยังไม่ได้ลองรันจริง จึงยังยืนยันไม่ได้ว่าใช้งานได้จริงหรือไม่
  • การเปลี่ยนแปลงที่ใหญ่ที่สุดคือจำนวนบรรทัดของโค้ดที่ลดลง
    • จำนวนบรรทัดรวมของไฟล์ Rust: 14,943 บรรทัด
    • จำนวนบรรทัดรวมของไฟล์ Ruby: 3,322 บรรทัด
    • จำนวนบรรทัดลดลง 77% และ Ruby 1 บรรทัดเทียบเท่ากับ Rust ราว 4.49 บรรทัด
  • โค้ด Ruby ที่แปลงออกมาดูสะอาดและเป็นธรรมชาติในสำนวนของภาษา เท่าที่ตรวจคร่าว ๆ
    • อย่างไรก็ดี ยังมีความเป็นไปได้ที่จะมีบั๊ก
    • หลังจากนี้จะมีการตรวจทานอย่างละเอียดมากขึ้น
  • ประเด็นที่ต้องดูต่อคือ การเสริม type, ฟังก์ชันพื้นฐานของ Rails และการทำให้การทดสอบง่ายขึ้น
    • หากใช้เอเจนต์ช่วยเพิ่ม type ก็อาจบรรเทาปัญหาเรื่อง type safety ได้
    • Ruby/Rails ถูกมองว่าใกล้เคียงกับแนวคิด “batteries + kitchen sink included” และดีกว่าการต้องแบก dependency ที่คอมไพล์แล้วขนาด 3GiB
    • คาดว่าการทดสอบจะง่ายขึ้นมาก
  • ตัวอย่างการทดสอบใน Ruby เป็นรูปแบบสั้น ๆ ที่ใช้ VCR.use_cassette("llm_call") ครอบการเรียก LLM แล้วตรวจสอบขนาดของผลลัพธ์
      VCR.use_cassette("llm_call") do
        result = LlmClient.match(entry, data_list)
        expect(result.results.size).to eq(data_list.size)
      end
    
  • ตัวอย่างการทดสอบใน Rust เป็นรูปแบบที่ยาวกว่า เพราะต้องลงมือสร้าง mock provider เอง
    • ใช้ Arc<RwLock<Vec<Response>>>, AtomicUsize, async_trait, tokio::test เป็นต้น
    • ต้องสร้าง MockProvider เพื่อจัดการรายการคำตอบและจำนวนครั้งที่ถูกเรียก จากนั้น implement match ของ trait Provider แล้วจึงตรวจสอบผลลัพธ์และจำนวนครั้งที่ถูกเรียกในเทสต์
  • เนื่องจากนี่เป็นโปรเจกต์ส่วนตัว จึงสามารถเลือกแนวทางที่กล้าได้มากกว่าเดิม และการย้ายจาก Rust ไป Ruby จะถูกพิจารณาอย่างละเอียดต่อไป

1 ความคิดเห็น

 
ความคิดเห็นบน Hacker News
  • ฟังดูไม่น่าเชื่อเลย ประมาณว่า “มีจุดที่คันทางเทคนิคซึ่งอยากเกา และ local AI ก็ทำงานเสร็จใน 30 นาที ยังไม่แม้แต่กด Start เพื่อดูว่ามันรันได้ไหม แต่ก็เขียนบล็อกโพสต์แล้ว...”

    • การที่ตอนนี้มันขึ้นอันดับ 1 หน้าแรก หมายความว่าต่อให้โปรเจ็กต์ยังใช้งานจริงไม่ได้ก็ไม่เป็นไร ผู้อ่านก็คงไม่ได้อ่านบทความกันอย่างจริงจังอยู่แล้ว
      ถ้าไม่ใช่ว่าบอตช่วยดันขึ้นมานะ
    • ปี 2016: มาดู JavaScript library ใหม่ของฉันหน่อย!
      ปี 2026: มาดูผลงานที่ฉันไม่ได้เขียนหน่อย!
      ปี 2036: วิธีที่ฉันเขียน C ซึ่งเป็นภาษาละตินโบราณ 200 บรรทัด
    • จะว่า “ไม่น่าเชื่อ” ก็ไม่เชิง สำหรับมาตรฐานปี 2026 นี่ใกล้เคียงกับเรื่องธรรมดามากกว่า
    • แต่ก็รีวิวอยู่ 5 ชั่วโมงนะ เพราะงั้น ¯\(ツ)
  • ตอนแรกนึกว่าจะเป็นบทความที่น่าสนใจ แต่พอถึงตรงที่บอกว่าใช้ LLM ในการแปลง ความสนใจก็หายไปทันที คล้ายกับการพูดว่า “ฉันอยากทำสิ่งนี้เลยสั่งลูกน้องให้ทำ แล้วจะมาเล่าให้ฟัง”
    ไม่ได้เป็นคนลงมือแปลงเองหรือคิดลึกเองจริง ๆ เลย เลยไม่เห็นเหตุผลว่าทำไมต้องอ่าน

    • ปัญหาใหญ่ที่สุดคือผู้เขียน ไม่ได้ตรวจสอบแม้แต่ความถูกต้อง เคยเห็นเครื่องมือใหญ่ที่ผสมหลายโมเดลรันงานแปลงอยู่ 6 ชั่วโมง แล้วพอไปตรวจด้วยมือว่ามันจัดการกับการคำนวณหรือตรรกะที่ยุ่งยากอย่างไร ก็พบว่ามี stub หรือคืนค่า true แบบ hardcode อยู่
      เพราะงั้นแค่รัน smoke test ก็อาจทำให้ดูเหมือนสำเร็จได้
    • ปัญหาที่ใหญ่กว่าคืออนาคตของ การพัฒนาซอฟต์แวร์ กำลังมุ่งไปทางนี้
      ถ้าไม่นับการเขียนโปรแกรมแบบช่างฝีมือ ภาษาโปรแกรมเองก็จะสำคัญน้อยลงมาก
      ยิ่ง LLM ดีขึ้น สุดท้ายก็จะกลายเป็นเรื่องของการเลือกว่าจะสร้างสเปกออกมาเป็นภาษาแบบไหน
      เท่ากับว่าฝั่ง UML กับ RUP ได้ล้างแค้นสำเร็จ
    • ประเด็นสำคัญไม่ใช่ว่าได้เขียนโค้ดเองหรือไม่ แต่คือเขาดูความแตกต่างและตัดสินใจเลือกบางอย่างที่อาจไม่ใช่ตัวเลือกที่เหมาะที่สุด อย่างที่คอมเมนต์อื่นพูดไว้ เขารีวิวค่อนข้างกว้างขวางทีเดียว โปรเจ็กต์ก็ไม่ได้ใหญ่มาก นอกจากจุดเผ็ด ๆ บางส่วนแล้ว ส่วนใหญ่ก็เป็นเว็บแอป
      การบอกว่า “ไม่ได้คิดอะไรเลย” ถือว่าไม่ยุติธรรม ไม่ใช่กดปุ่มแล้ว YOLO อย่างเดียว
      เขาศึกษา trade-off และผลลัพธ์มาแล้ว และความต่างระหว่างโค้ด Rust บางส่วนกับ Rails ก็มีอยู่จริง รวมถึงเรื่องความสามารถในการทดสอบของแอป Rust ก็เป็นหัวข้อที่คิดมา 2 เดือนแล้ว
      อย่างที่สายคลั่ง LLM ชอบพูดกันว่า บริบทสำคัญ ;)
  • ไม่แน่ใจว่ามีภาษาและเฟรมเวิร์กไหนที่ให้ความสำคัญกับความสุขของนักพัฒนาเท่า Ruby on Rails หรือเปล่า

    • แทบไม่เคยมีช่วงไหนที่ผมไม่มีความสุขเท่าตอนทำงานกับโปรเจ็กต์ Rails เจอบั๊กบนเว็บไซต์ เลย grep หา view ที่ render ผิด เจอ method call ที่ render ส่วนนั้น แล้วพอ grep ด้วยชื่อเมธอดกลับได้ผลลัพธ์ 0 รายการ
      มันเป็นอะไรบางอย่างที่ถูกประกอบขึ้นมาจากที่ไหนสักแห่งจนไม่รู้ว่าอยู่ตรงไหน สุดท้ายเลยต้องหยุดงานที่ทำอยู่แล้วไปอ่านเอกสารเป็นชั่วโมง สำหรับคนที่ใช้ Rails ทั้งวันทุกวันก็คงโอเค แต่ convention over configuration สำหรับผมคือ anti-pattern ขนาดใหญ่
    • ผมรู้สึกคล้าย ๆ กันกับ Elixir และ Phoenix แต่ไม่มีอุปกรณ์ยิงเท้าตัวเองอย่าง method_missing
    • ถึงจะไม่ดูดึงดูดในคอมมูนิตี้รสนิยมแบบซิลิคอนแวลลีย์ ผมก็ทำงานกับ Java และเฟรมเวิร์ก .NET มาอย่างน่าพอใจไม่น้อย
      ความสุขไม่ได้แปลเป็นประสิทธิภาพเสมอไป ทำให้นึกถึงกรณีโลโก้ชื่อดังของ Twitter ก่อนที่จะย้ายไป JVM และ Scala
      แม้ Ruby on Rails จะมีชื่อเสียง แต่ก่อนหน้านั้นก็เคยมีประสบการณ์คล้ายกันใน AOLServer และ Vignette ที่ใช้ Tcl
      ที่สตาร์ตอัปในโปรตุเกสก็เคยสร้างเวอร์ชันดัดแปลงของตัวเองขึ้นมา และผู้ก่อตั้งก็ไปสร้าง OutSystems ในภายหลัง นี่คือหนึ่งในเครื่องมือ RAD แบบกราฟิกยุคแรกสำหรับการพัฒนาเว็บไซต์และระบบกระจาย โดยเป็นแนว low-code/no-code ที่เจาะโครงสร้างพื้นฐาน JVM หรือ CLR
      ถึงอย่างนั้นก็ดีใจที่ตอนนี้ได้เห็น JIT ใน CRuby มาเป็นค่าเริ่มต้นแล้ว
    • มากสุดมันก็เป็นความสุขระยะสั้น และแทบเหมือนเอาคุณลักษณะทางสถาปัตยกรรมอื่น ๆ ทั้งหมดไปแลก ทั้งการดูแลรักษา ประสิทธิภาพ ความน่าเชื่อถือ ความสามารถในการขยายระบบ ฯลฯ
  • ผมสร้างชุด gem ชื่อ propel_rails ที่ผลักโค้ด Ruby on Rails ซึ่งเดิมก็กระชับอยู่แล้วให้สุดขึ้นไปอีก มันสร้างคลาสระดับบนสุดอย่าง API controller และ concern แล้วจากตรงนั้นก็สร้าง RESTful resource ทั้งชุดให้เลย (model, controller, serializer, unit test และ E2E test) โดยแทบไม่มี boilerplate
    สุดท้าย controller จะเหลือแค่รายการคุณสมบัติที่ API อนุญาต เพราะ RESTful action ถูกสร้างให้อัตโนมัติ มันอธิบายให้ครบค่อนข้างยากนิดหน่อย แต่พลังของ metaprogramming ใน Ruby ทำให้เรื่องน่าทึ่งแบบนี้กลายเป็นเรื่องง่ายได้จริง

    • ฟังดูเหมือนรูปแบบที่ขัดเกลาแล้วของ CRUD
      ถ้ามองว่าอิงตาม domain model จะเข้าใจถูกไหม?
    • หาเจอบน rubygems แต่ลิงก์ GitHub ที่โยงไปจากตรงนั้นขึ้น 404
  • ผมก็อยู่ในสถานการณ์คล้ายกัน
    ชอบทั้ง Go และ Rust และทั้งคู่ก็เป็นภาษาที่ดีมากพร้อมข้อดีข้อเสียของตัวเอง แต่ก็น่าเสียดายที่ผมยังสร้างแอป SaaS ด้วยสองตัวนี้ไม่ได้เลย มันเหมือนเอาหมุดสี่เหลี่ยมไปยัดลงรูวงกลม
    ผมอาจจะคิดผิดอย่างแรงก็ได้ แต่เครื่องมือ SaaS มันมีของแถมและสิ่งประกอบจำนวนมาก และผมไม่อยากประดิษฐ์สิ่งเหล่านั้นขึ้นใหม่
    RoR นั้น “ดีพอ” ใส่ type เข้าไปได้เมื่ออยากใส่ สร้างได้เร็ว และเครื่องมือก็ถือว่าใช้ได้
    งานจริงชิ้นแรกของผมคือ PHP ซึ่งมีหลุมพรางเยอะเกินไป Ruby ดูจะเอนเอียงไปทางอีคอมเมิร์ซมากกว่าเลยน่าสนใจ และถ้ามันดีพอสำหรับ Shopify ก็น่าจะโอเค

  • ถ้ามีสถานการณ์ที่การย้ายจาก Rust ไป Ruby ยังสมเหตุสมผล นั่นก็แปลว่าการ เลือก Rust ตั้งแต่แรก เป็นความผิดพลาด

    • นี่สรุปบทความนี้ได้ดีมาก และก็เป็นเหตุผลที่ผมตัดสินใจแชร์มัน
  • คนที่คิดว่า Ruby ช้ากว่า Rust ถ้ารู้ว่าเดี๋ยวนี้ Ruby จริง ๆ แล้ว เร็วกว่า Python และช้ากว่า Go หรือ Rust ก็คงแปลกใจ

    • ปกติสิ่งที่สำคัญกว่าความเร็วคือ การใช้หน่วยความจำ แอป Ruby ส่วนใหญ่มักติดคอขวดที่ฐานข้อมูล ไม่ใช่ตัว Ruby เอง
      แต่พอมี worker เบื้องหลังหลายตัว และแต่ละตัวเริ่มกินหน่วยความจำเกิน 2GB มันก็สะสมเร็วมาก
      ผมเคยเขียนบริการ Rust ตัวหนึ่งขึ้น production และสิ่งที่น่าประทับใจกว่าความเร็วคือมันรันด้วย หน่วยความจำ 30MB ได้
    • ผมไม่เข้าใจว่าทำไมคนที่คิดว่า Ruby ช้ากว่า Rust ถึงควรต้องแปลกใจกับความจริงที่ว่ามันเร็วกว่า Python สองเรื่องนี้เกี่ยวกันยังไง?
  • เป็นคำพูดที่จงใจยั่วนิดหน่อย แต่ถึงจะเหมาะกับการเอาไว้โชว์ IQ 900+ ให้ชาวบ้านรอบตัวดู ก็มีนักพัฒนาฉลาดและมีพรสวรรค์จำนวนมากที่ไม่ได้ชอบ Rust เท่าไร บางคนถึงขั้นเลือกจะสร้าง ภาษาโปรแกรมกับคอมไพเลอร์ของตัวเอง แทนที่จะเขียน Rust แม้แต่บรรทัดเดียว
    ผมนึกถึง Jai ของ Jonathan Blow กับ Odin ของ Ginger Bill
    ยังมีอีกมากที่เป็นคนซึ่งพิสูจน์ความคิดสร้างสรรค์และความลึกซึ้งของตัวเองแล้วด้วยการสร้างไลบรารีและเฟรมเวิร์กสวย ๆ ที่ถูกใช้อย่างแพร่หลาย แต่ไม่อยากเปลืองพื้นที่ตรงนี้
    แค่จะบอกว่า Rust มีทั้ง ชมรมสายแมน สุดเท่และภราดรภาพที่เหนียวแน่น

    • คอมมูนิตี้ Rust นี่แทบจะไกลจากคำว่า “ชมรมสายแมน” มากที่สุดแล้ว
  • Claude ทำงานกับแอป Rails ได้ดีมาก อย่างที่ผู้เขียนบทความนี้ชี้ไว้ Ruby ช่วยให้ทำอะไรได้มากด้วยโค้ดน้อย และ Rails ก็ใช้ convention over configuration ทำให้แอป Rails ยิ่งกระชับขึ้นไปอีก
    สมมติฐานหนึ่งว่าทำไม Claude ถึงเขียนแอป Rails ได้ดี คือเรื่อง ประสิทธิภาพด้านโทเค็น
    ผมเคยเห็นโปรเจ็กต์นี้ที่พยายามวัดและเทียบประสิทธิภาพด้านโทเค็นรายโปรเจ็กต์ แล้ว Rails ก็ออกมาค่อนข้างดี
    https://felipemrvieira.github.io/SyntaxTax/dashboard/

  • บางทีก็แปลกใจกับขนาดของโปรเจ็กต์ codebase 30,000 บรรทัด นี่ถือว่าเล็กเหรอ? ผมรู้ว่าเพดานมันสูงได้มาก แต่ 30,000 บรรทัดก็สามารถบรรจุข้อมูลและความละเอียดอ่อนของพฤติกรรมไว้ได้มหาศาล
    อาจเป็นเพราะพื้นเพของผมเน้นงานฝั่ง backend/network ที่ใช้ Go ก็ได้ พอเกิน 10,000~15,000 บรรทัดไปแล้ว ปกติก็เริ่มยากที่จะเก็บโมเดลของ codebase ทั้งหมดไว้ในหัว เลยรู้สึกว่ามันหนักพอสมควร

    • มันขึ้นอยู่กับว่าคุณกำลังสร้างอะไร ถ้าเป็นแอป SaaS ที่มี frontend หลายชุด ก็ไปถึง 30,000 บรรทัดได้ไม่ยาก