- Ruby không phải ngôn ngữ nhanh nhất hay thịnh hành nhất, nhưng sau hơn 15 năm đi qua nhiều ngôn ngữ khác nhau, nó vẫn là ngôn ngữ được chọn lại khi muốn thực sự tận hưởng công việc
- refinements, Forwardable, SimpleDelegator,
Object#then, Kernel#tap, và tham số đánh số mang lại những tiện ích cú pháp nhỏ cùng luồng đọc dễ theo dõi
Thread::Queue, json, csv trong thư viện chuẩn, cùng với RuboCop và Ruby LSP, giúp duy trì một môi trường phát triển thực dụng mà không cần nhiều gem nhỏ hay cấu hình phức tạp
- YJIT của Ruby 3.x và ZJIT của 4.x đang thu hẹp khoảng cách ở các tác vụ nặng CPU; trong một phép so sánh Fibonacci đơn giản, Ruby với ZJIT chỉ chậm hơn Go khoảng 2–3 lần
- Dù có những lĩnh vực mà Rust·Go·Python phù hợp hơn, trong web app, xử lý nền và công cụ nội bộ, niềm vui của lập trình viên cùng tốc độ lặp nhanh vẫn là thế mạnh của Ruby
Những lý do về mặt ngôn ngữ khiến Ruby đem lại cảm giác dễ chịu
- Ruby không phải ngôn ngữ nhanh nhất hay thịnh hành nhất, nhưng sau hơn 15 năm qua lại giữa nhiều ngôn ngữ, nó vẫn là ngôn ngữ mà người ta quay về chọn khi muốn thực sự tận hưởng việc viết phần mềm
- refinements cho phép mở class chỉ trong phạm vi giới hạn, nhờ đó có thể thêm những tiện ích cú pháp nhỏ trong file hoặc block mà không làm ô nhiễm toàn bộ namespace
- Rất hợp với test helper hoặc DSL nội bộ trong codebase lớn
- Chỉ tại nơi gọi
using QuotingRefinement mới có thể dùng các method như "hello".quote
- Forwardable và
SimpleDelegator trong thư viện chuẩn cho phép ủy quyền gọn gàng mà không phải tự viết wrapper method hay kéo thêm gem vào
- Nếu đã dùng Rails thì
delegate của Active Support có thể tiện hơn, nhưng phiên bản Ruby thuần giúp các script thông thường vẫn nhẹ nhàng
Object#then và Kernel#tap cho phép nối các thao tác thành chuỗi đọc từ trên xuống mà không cần tạo biến trung gian
- Có thể viết liền mạch luồng tạo, ghi log, chuẩn hóa và lưu như
User.new(params).tap { ... }.then { ... }.save
- Tham số đánh số từ Ruby 2.7 trở đi giúp giảm nhiễu trong các callback ngắn
- Không cần khai báo tường minh tham số block như trong
items.map { _1.price * 1.1 }
- fiber scheduler giúp viết mã đồng thời nhưng trông như mã tuần tự khi đã gắn với event loop
- Có thể biểu đạt mã phối hợp với các fiber khác dưới dạng
Fiber.schedule do ... end
Bức tranh hiện tại của công cụ, hiệu năng và hệ sinh thái
- Ruby LSP của Shopify cung cấp tích hợp editor với cấu hình tối thiểu, đồng thời hoạt động tốt cùng Steep hoặc RBS cho việc áp dụng kiểu dữ liệu dần dần
- RuboCop giúp giữ style nhất quán mà không cần những quy trình mang tính nghi thức như ở một số hệ sinh thái khác
- Thư viện chuẩn vẫn là một lợi thế âm thầm vì không cần thêm hàng loạt gem nhỏ cho những tác vụ phổ biến
- Nếu cần queue, có thể dùng
Thread::Queue
- Với phân tích JSON hay CSV,
json và csv xử lý được phần lớn tình huống thực tế mà không cần thủ tục rườm rà
- Sau YJIT của Ruby 3.x, dòng 4.x đang đón ZJIT
- ZJIT là một JIT hoạt động quyết liệt hơn trên cùng nền tảng, biên dịch hiệu quả hơn các đường chạy nóng hơn
- Các con số ban đầu cho thấy khoảng cách với những ngôn ngữ từng vượt Ruby rất xa ở tác vụ nặng CPU đã được thu hẹp đáng kể
- CRuby ZJIT đang được phát triển trong kho mã chính của Ruby
- Trong một benchmark đơn giản so sánh cài đặt Fibonacci đệ quy trên cùng máy, Ruby với ZJIT chỉ chậm hơn Go trong khoảng 2–3 lần, cũng không kém quá xa Rust đã tối ưu trong trường hợp đó, còn Python với pypy thì tụt lại phía sau
- Dù microbenchmark có giới hạn, các đường chạy mã đã đủ “ấm” để JIT tối ưu trong ứng dụng thực tế có thể còn hưởng lợi nhiều hơn
- So với Rust, Ruby mạnh ở tốc độ lặp của business logic
- Trong Rust, có thể mất thời gian vật lộn với borrow checker cho những việc vốn rất rõ ràng ở thời điểm chạy
- Go có các primitive cho đồng thời rất tốt, nhưng cho đến gần đây còn chưa có generics và cách xử lý lỗi hơi cứng có thể khiến script đơn giản trở nên nặng nề hơn mức cần thiết
- Python là người họ hàng gần nhất về mặt tinh thần, nhưng để biểu đạt cùng một ý tưởng cấp cao thường cần nhiều boilerplate hơn, đặc biệt quanh class và decorator
- Khi đưa mã vào mô hình, hiệu quả token cũng trở thành một lợi thế thực tế của Ruby
- Có thể biểu diễn block bằng
do/end hoặc dấu ngoặc nhọn, và hầu như không cần ngoặc cho lời gọi method nếu khả năng đọc vẫn cho phép
- Hash và keyword argument là tính năng hạng nhất và rất ngắn gọn, nên có thể nhét nhiều logic thực sự hơn vào cùng một cửa sổ ngữ cảnh so với các ngôn ngữ nhiều nhiễu cấu trúc
- Các tiện ích metaprogramming của Ruby rất phù hợp để tạo API nhỏ gọn, dễ đọc
- Những tính năng như
define_method, class_eval, hay chặn missing method cho phép tạo API giàu biểu đạt mà không cần bước sinh mã riêng
- Các thư viện như
dry-rb hay aasm dùng các khả năng này một cách tiết chế để cung cấp state machine và tầng kiểm tra hợp lệ gọn gàng
- Công cụ cộng đồng và quy trình triển khai cũng đã trưởng thành
- byebug và
pry cho cảm giác linh hoạt hơn nhiều debugger từng dùng ở nơi khác
- Với tác vụ nền,
solid_queue và good_job đủ đơn giản để có thể hiểu toàn bộ cách triển khai chỉ trong một buổi chiều
- Kamal đã thay thế quy trình kiểu capistrano cũ đối với nhiều người, và thực sự cho cảm giác như một công cụ được làm bởi những người đang vận hành các nhóm nhỏ
- Điều đó không có nghĩa Ruby đánh bại Rust hay Go trong mọi việc; vẫn có những lĩnh vực mà Rust hoặc Go phù hợp hơn
- Nhưng ở vùng trung gian rộng lớn gồm ứng dụng web, xử lý nền và công cụ nội bộ, Ruby vẫn tiếp tục mang lại niềm vui cho lập trình viên mà không đòi hỏi quá nhiều nghi thức hay chuyển ngữ cảnh liên tục
- Những tiện ích nhỏ và cảm giác tổng thể của ngôn ngữ vẫn là thứ khiến người ta muốn với tay đến nó trước tiên ngay cả sau hơn một thập kỷ, và các nỗ lực JIT mới cùng những cải tiến ngôn ngữ bền bỉ càng củng cố thêm điều đó
1 bình luận
Ý kiến trên Lobste.rs
Khó mà đồng ý với cách diễn đạt “RuboCop không cần nghi thức rườm rà”
Với RuboCop, vẫn có khá nhiều tranh luận quanh việc chọn và tinh chỉnh cop nào, rồi có nên bật các cop mới được thêm vào trong các bản cập nhật gần đây hay không
StandardRB gần với một cách tiếp cận ít tính nghi thức hơn nhiều, nhưng rốt cuộc cũng vẫn là phải chọn một thứ
Những ngôn ngữ có lint tích hợp sẵn trong ngôn ngữ thì ít phiền phức hơn Ruby rất nhiều, và cũng ít tranh cãi vụn vặt về style hơn
Ràng buộc lại mang đến tự do
Tôi nhìn chung phản đối việc cấu hình linter, và muốn những quyết định kiểu này được giao cho mặc định của cộng đồng
Một mặt, tôi nghĩ mặc định của RuboCop đã đủ ổn, nên tốt hơn là cứ theo nó và cùng nhau cải thiện thay vì chia nhỏ style code hơn nữa
Mặt khác, đôi khi nó quá nặng tính áp đặt, nên lại thấy cần thứ gì đó như standard.rb
Tôi viết từ góc nhìn rằng người muốn học Ruby hoặc quay lại với nó không nên phải đối mặt với hàng đống gem chỉ để có thể viết code thoải mái
Khi Go ra mắt, tôi đã thấy việc nó cung cấp một hệ thống format chính thức duy nhất là một quyết định rất đúng đắn
Bộ não là một cỗ máy nhận diện mẫu, nên khi đã quen thì ta cứ thế lướt qua, nhưng nếu có lựa chọn thì sẽ thấy khó chịu và ai cũng bị kéo qua kéo lại
Vấn đề là cả RuboCop lẫn Standard đều không thể có được thứ quyền uy đó trong Ruby
Quyền uy ấy phải đến từ core team, nhưng điều đó có lẽ sẽ không xảy ra vì đi ngược lại triết lý của Ruby
Trong dự án của tôi, tôi tắt toàn bộ cop của RuboCop rồi chỉ bật một số cái
Dấu nháy đơn là đỉnh nhất 😀
Có vẻ một bài khác cũng chỉ ra đúng điểm này: https://caio.ca/blog/coding/my-complicated-relationship - “The Wild West of Code Formatting”
Đại ý là: “Đó không phải một giải pháp tích hợp đơn giản. Có hàng trăm cop có thể cấu hình, dẫn đến những cuộc tranh cãi bất tận về việc nên bật quy tắc nào”
Nhìn chung tôi đồng ý, nhưng hơi tiếc vì refinements lại là ví dụ đầu tiên
Tôi hiểu vì sao người ta thích nó, nhưng nó gần với kiểu tốt hơn là đừng biết xúc xích được làm ra như thế nào
Ngữ nghĩa của nó quá rắc rối, đến mức sau 10 năm kể từ khi được đưa vào, người ta vẫn tiếp tục tìm ra các bug đau đầu trong MRI
Ví dụ, chỉ trong 2 tuần gần đây đã có https://bugs.ruby-lang.org/issues/22071 và https://bugs.ruby-lang.org/issues/22058
Về mặt hiệu năng, nó cũng khiến nhiều tối ưu hóa trở nên khó khăn hơn, và giờ điều tương tự lại đang xảy ra với boxes
Ở cấp độ triển khai chắc vẫn còn nhiều bug ẩn, và phía thư viện có lẽ cũng vậy
Giờ tôi không còn dùng Ruby nhiều nữa, nhưng vẫn tò mò không biết nó sẽ ổn định ra sao
Trông khá thú vị
Bài này cũng trùng khớp khá nhiều với trải nghiệm của tôi trong bài “Returning to Rails”[1]
Có thể chỉ là thiên kiến xác nhận, nhưng có vẻ ngày càng nhiều người đang tái khám phá hoặc nhìn nhận lại vẻ đẹp của code Rails
Tuy vậy, nó cũng khiến tôi nghĩ đến hiện tượng gu âm nhạc hay nghệ thuật thường được cố định từ cuối tuổi teen đến tuổi 20
Có lẽ những người gặp Ruby lần đầu vào “thời hoàng kim” của Rails đang nhìn lại thời Rails 3 và Capistrano qua lăng kính màu hồng
Khi đó tôi đã chìm rất sâu trong “shop” Ruby, và xung quanh cũng toàn là lập trình viên Rails, nên cảm giác như Ruby ở khắp mọi nơi
Nhưng rồi tôi thấy trong một chủ đề trên lobste.rs[2] có ý kiến rằng thật ra Ruby từ trước đến nay vẫn luôn là một ngôn ngữ khá ngách, nên có lẽ điều đó cũng có ảnh hưởng
Dù vậy, Ruby vẫn mang lại cảm giác như ở nhà, và dường như vận hành đúng theo cách đầu óc tôi hoạt động
Hầu như không cần khâu chuyển dịch nào, không có gì gây bất ngờ, và cảm giác giống như đang trò chuyện với bạn bè hơn là viết một bài luận trang trọng
Tôi vẫn chưa tìm được ngôn ngữ nào hợp đến thế, và tôi không nghĩ tất cả chỉ là kiểu suy nghĩ “đám trẻ bây giờ”
Dù sao thì tôi vẫn mừng vì nó đã tồn tại được lâu đến vậy
Và cảm ơn vì đã chỉ cho tôi chuỗi “tap / new”
Cấu trúc đó đẹp và hữu ích đến mức khiến tôi phải dừng lại ngắm một chút, và chắc chắn tôi sẽ thử dùng
PS - Không trực tiếp liên quan đến chủ đề, nhưng avatar AI trên trang chủ hơi rờn rợn
Nó tạo cảm giác rất mạnh kiểu thung lũng kỳ lạ như “bài này có phải bot viết không?”
Mỗi lần thấy kiểu đó là tôi lại phải thoáng tự hỏi không biết mình có đang nói chuyện với con người thật hay không
[1]=https://www.markround.com/blog/2026/03/05/returning-to-rails-in-2026/
[2]=https://lobste.rs/s/jreqtw/returning_rails_2026
Chỉ là tôi không muốn công khai ảnh thật, còn avatar đó thì thực ra đủ giống để những người quen tôi ngoài đời có thể nhận ra
Ruby 3.4 đã thêm tham số khối
it, có thể dùng thay cho_1trong ví dụhttps://rubyreferences.github.io/rubychanges/3.4.html/…
itCó lẽ vì đây là tính năng tương đối mới, nên tôi vẫn chưa thể hình thành thói quen gõ
ittrong iteratorTôi thực sự từng rất thích viết code bằng Ruby, nhưng gánh nặng kiểm thử đã trở nên quá lớn
Tôi từng nghĩ thêm một mức độ an toàn kiểu dữ liệu nào đó vào ngôn ngữ sẽ có ích, nhưng ở
#{last_job}, khi đưa Sorbet vào codebase thì động lực và niềm vui viết code đã chết hẳnCó thể đây là ý kiến không phổ biến, nhưng tôi thấy việc một thứ như Sorbet tồn tại tự nó đã gần giống một mùi hôi không lành về Ruby
Bản thân Ruby là một ngôn ngữ mạnh mẽ và thú vị, nhưng rồi người ta bắt đầu dùng nó cho những công việc mà ban đầu nó không được thiết kế cho, và trong quá trình đó họ bắt đầu chồng thêm công cụ để bù đắp cho những phản tính năng của ngôn ngữ
Giờ đây, mọi dòng code đều như một cực hình buồn tẻ, và tôi dành nhiều thời gian chờ đủ loại công cụ build, test, lint hơn là thực sự viết code
Cộng thêm quy trình build và triển khai bị thiết kế quá đà, ngay cả những việc cơ bản cũng mất rất lâu và khiến công việc trở nên khổ sở
Tôi rất nhớ thế giới Ruby khoảng năm 2012
Nghĩ lại thì đó thật sự là những ngày rất đẹp
Tôi hiểu cụm “những công việc mà ban đầu nó không được thiết kế cho” là đang chỉ các ứng dụng Rails lớn
Sau 10 năm tôi quay lại Ruby, và trong thời đại “AI”, việc có thể thực sự hiểu được đoạn code lướt qua trước mắt rồi điều khiển hoặc chặn LLM lại là một điều hữu ích
Với những ngôn ngữ dài dòng hơn thì việc này khó hơn nhiều
Tôi nhớ Ruby, và hơn thế nữa, tôi nhớ cả việc một ngôn ngữ như thế từng có thể tồn tại trong môi trường production thường nhật
Đó là hy vọng, hay đúng hơn là bản thân hy vọng
Ít nhất với tôi, trong một thời gian dài là như vậy
Đọc như một bài viết do AI làm qua loa
Mấy bài blog gần đây khác cũng vậy
Điều gì khiến anh nghĩ như vậy?
Việc chỉ ra các bài viết chất lượng thấp do AI tạo trên trang này là điều tốt, nhưng cần tránh báo động nhầm và nói rõ chính xác vì sao anh lại nghĩ thế
Vì sao anh lại thấy vậy?
Những cảnh báo kiểu này là tốt, nhưng tôi thích có kèm lý do hơn nhiều
Tôi có ký ức đẹp về quãng đầu sự nghiệp làm việc với Ruby
Ruby thực sự có một điều gì đó rất dễ chịu
Nhưng có lẽ khi tôi dùng lại Ruby một chút gần đây, vào khoảng năm ngoái, tôi cảm thấy khó điều hướng tài liệu standard library trên web
Có phải chỉ mình tôi thấy vậy không? Có lựa chọn nào thay thế tài liệu trên ruby-lang.org không?
[1] https://rubyapi.org
[2] https://devdocs.io/ruby/
Bài này mang lại cảm giác hơi kỳ lạ
Tôi từng có cơ hội viết một dự án và một SDK bằng Ruby, và từ đó về sau hoàn toàn không còn muốn dùng Ruby nữa