9 ms·
Ruby 4.0.0
- aaronbrethorst 9mo agoIt wouldn't be Christmas without a new version of Ruby. Thanks Matz and co!
- nish__ 9mo agoRuby::Box looks useful.
- shevy-java 9mo agoRight now it is just the foundation I guess. That is, more work to be put on top of it. byroot kind of pointed that out that the proposal reminds him of containers and I think this is the long-term goal eventually, e. g. namespaced isolated containers. At a later time, I think, the syntax for refinements may be simplified and also be integrated into Ruby::Box, since Ruby::Box is kind of a stronger refinement in the long run. But that's my take; ultimately one has to ask matz about the changes. What he did say on the bugtracker was that this is to be considered a low-level API e. g. a foundation work. So things will be put on top of that eventually.
- desireco42 9mo agoThis really makes Christmas festive. I don't think I need new features, but sure love simplicity of 4.0. I am installing it now. Thank you Matz and team.
- ekvintroj 9mo agoMy best Christmas gift <3 Love you Ruby.
- ksec 9mo agoIt seems Ractor is still work in progress while Fiber has matured a lot in the last few releases. I vaguely remember reading Shopify is using Fiber / Rack / Async in their codebase. I am wondering if Rails will get more Fiber usage by default.
- shevy-java 9mo agoTo me it seems very few people use ractors. A bit more use fibers though. It's a bit of a mess IMO. I'd much prefer everything be simplified aggressively in regards to threads + GIL; and Ractors integrated on top of Ruby::Box to provide not only namespaced container-like entities but also thread-support as a first-class citizen at all times. The API of ractors is weird and really not fun to use.
- Lammy 9mo agoI really enjoyed using them for my Ruby file-matching library where I wanted to read `shared-mime-info` XML source package files directly and on the fly as opposed to using the pre-processed secondary files that the upstream `update-mime-database` tool spits out. The problem is that a type definition can be spread out over multiple XML packages in both system and user paths, so the naïve implementation of reading them all at once wastes a massive amount of memory and a massive number of object allocations (slow) when most people use maybe 5% of the full set of supported types (the JPEGs and HTMLs and ZIPs of the world). I wanted to read the source package files directly because I always found `shared-mime-info`'s usual two-step process for adding or editing any of the XML type data to be annoyingly difficult and fragile. One must run `update-mime-database` to decompose arbitrarily-many XML packages into a set of secondary files, one all-file-extensions, one all-magic-sequences, one all-aliases, etc. System package managers usually script that step when installing software that come with their own type data. I've accidentally nuked my entire MATE session with `update-mime-database` before when I wanted to pick up a manual addition and regenerated the secondary files while accidentally excluding the system path that had most of the data. I ended up doing it with four Ractors: - a Ractor matching inputs (MIME Type strings, file extensions, String or Pathname or URL paths for sniffing) against its loaded fully-formed type definition objects. - a Ractor for parsing MIME Type strings (e.g. "application/xml") into Hash-keying Structs, a task for which the raw String is unsuitable since it may be overloaded with extra syntax like "+encoding_name" or fragment ";key=value" pairs. - a fast XML-parser Ractor that takes in the key Structs (multiple at once to minimize necessary number of passes) and figures out whether or not any of those types are defined at all, and if so in which XML packages. - a slow XML-parser Ractor that takes the same set of multiple key Structs and loads their full definition into a complete type object, then passes the loaded objects back to the matcher Ractor. The cool part of doing it this way is that it frees up the matcher Ractor to continue servicing other callers off its already-loaded data when it gets a request for a novel type and needs to have its loader Ractors do their comparatively-slow work. The matcher sets the unmatched inputs aside until the loaders get back to it with either a loaded type object or `nil` for each key Struct, and it remembers `nil`s for a while to avoid having to re-run the loading process for inputs that would be a waste of time. The last pre-Ractorized version allocated around 200k objects in 7MiB memory and retained 17k objects in 2MiB of memory for a benchmark run on a single input, with a complete data load. The Ractorized version was twice as fast in the same synthetic benchmark and allocated 20k objects in 2MiB of memory and retained 2.5k objects in 260KiB of memory for its initial minimal data load. I have it explicitly load `application/xml` and `application/zip` since those combined are the parent types for like a third of all the other types, and a few other very common types of my choosing. I think a lot of the barrier to entry for Ractors isn't the API for the Ractors themselves but in figuring out how to interact with Ractorized code from code that hasn't been explicitly Ractorized (i.e. is running in the invisible “main” Ractor). To that end I found it easiest to emulate my traditional library API by providing synchronous entry-point methods that make it feel no different to use than any other library despite all the stuff that goes on behind the scenes. The entry methods compose a message to the matcher Ractor then block waiting for a result or a timeout. I also use Ractors in a more lightweight way in my UUID/GUID library where there's a Ractor serving the incrementing sequence value that serves as a disambiguator for time-based UUIDs in case multiple other Ractors (including invisible “main”) generate two UUIDs with the same timestamp. Speaking of which, I'm going to have to work on this one for Ruby 4.0, because it uses the removed `Ractor.take` method.
- mikestorrent 9mo agoStill love Ruby deeply even though I now work somewhere where it's not in use. Thanks for the release, I hope I find a reason to use it!
- andrewinardeer 9mo agoIt truly is Christmas.
- ergocoder 9mo agoI haven't looked at Ruby for a long time. I've moved away due to the lack of typing. Any degree of typing would be helpful. Does it support typing yet?
- riffraff 9mo agoThere's an official format for defining types in separate files (RBS) and some tooling to type check them (matz doesn't like types next to the source code). There's a pretty battle tested tool to define inline types as ruby syntax and type check both statically and at runtime[0]. It's still not a particularly nice situation imvho compared to typescript or python, but there's been some movement, and there's a newsletter that follows static typing developments [1] which may give you some insights. 0: https://sorbet.org/ https://sorbet.org/ 1: https://newsletters.eremin.eu/posts https://newsletters.eremin.eu/posts
- adamors 9mo agoI’ve used Sorbet on a project for 2 years recently and it honestly was the final nail in the coffin for Ruby for me. Really rough around the edges, lots of stubs have to be added because support for gems is lackluster but whatever Sorbet generates are hit or miss etc. So you end up writing a lot of hard to understand annotations and/or people get frustrated and try to skip them etc. Overall a very bad DX, compared to even typed Python. Don’t even want to compare it to TS because then it becomes really unfair.
- Kerrick 9mo agoSorbet is a third-party add-on, not a part of Ruby. It's like if CoffeeScript was your final nail in the coffin for JavaScript.
- vmware513 9mo agoUnfortunately, the type support is still useless. I abandoned Ruby for the same reason, and it is still relatively slow and eats a lot of memory.
- maz1b 9mo agoIt's never Christmas without a new ruby version. The ruby::box thing looks pretty interesting, from a cursory glance you can run two simultaneous versions of something like a feature or rollout much more conveniently. Also being able to do if condition1 && condition2 ... end on multiple lines rather than one - this is pretty nifty too!
- tebbers 9mo agoI've been doing if condition1 && condition2 ... end for ages and it seems to work find, what am I missing with this new syntax?!
- Sammi 9mo agoLess likely to cause git merge conflict as you don't change the original line. You only add one.
- mantas 9mo agoPersonally && in the new line seems to be much better readability. Can’t wait to use some smart cop to convert all existing multiline ifs in my codebase.
- fuzzythinker 9mo agoIn languages where placement don't matter, like c/js, I prefer leading booleans. It makes it much easier to see the logic, especially with layers of booleans.
- RomanPushkin 9mo agoI'm happy to see v4.0, but 2025 was the year I switched from Ruby to Python after gradually drifting back to it more and more. The tipping point was when I had Claude Code automatically convert one of my Ruby projects to 100% Python - and after that, I just had no Ruby left. I spent over a decade enjoying Ruby and even wrote a book about it. At this point, though, Python has won for me: fastapi, pytorch, langchain, streamlit, and so on and on. It's a bit sad, but I'll always remember the Christmas gifts, and the syntax that is always so much better than Python.
- lcnmrn 9mo agoYou should try Falcon too.
- 0xblinq 9mo agoJust by how much better the editor/IDE support is with Python it is a change worth to do. I just can’t stand the excessive dynamism of Ruby. I understand some people prefer/enjoy it, it’s just not for me.
- Bayko 9mo agoLangchain? I tried using/learning langchain then I found out that it was evolving so fast that even the latest ai models didn't have even remotely up to date information on it! Not to mention the hundreds of Google search results for ---- why do langchain docs suck? I finally switched to haystack and I have been really happy. (Don't work on corporate ai software this is just for personal use)
- nurettin 9mo agoUsed Ruby for a decade, knew about it for more than that. I still sometimes use ruby syntax to communicate ideas with friends and colleagues. For me, the killer feature of Python was the typing module and the intellij pycharm community edition being free and RubyMine having a subscription fee.
- nix-zarathustra 9mo agoRubyMine is free for non-commercial usage.
- Bolwin 9mo agoHave they improved tooling? I've yet to get any lsp working on windows
- ornornor 9mo agoIMO programming on windows is just asking for punishment. Unless it’s a Microsoft language, you’re so much better off on Linux or macOS.
- nchmy 9mo agoOr wsl2
- nurettin 9mo agoTo be fair, vscode and .net core on linux is pretty much like having windows and visual studio at this point.
- array_key_first 9mo agoWithout the debugger, unfortunately. You still need VS or Rider for that.
- nurettin 9mo agoWhat problem have you had with the debugger?
- seabrookmx 9mo agoThe debugger works fine on Linux? The only thing missing are some profiling tools. If you really need those you're better off with Rider which is integrated with DotTrace.
- koshersalt 9mo agoThat’s cool if you can, but the majority of business desktops/laptops runs Windows. Hard to gain enterprise traction when it’s hard to run tools on your local machine
- digitaltrees 9mo agoRuby is amazing. I recently built a layer on top of Rails that can generate an API from a single markdown file. I did the same thing in python but it was much harder and JavaScript would have been a beast. Ruby can meta program like nothing else.
- mierz00 9mo agoCurious to hear more about this, do you have any examples?
- digitaltrees 9mo agoWe might release it as a framework of gems. We created an Abstract controller that handles all of the typical behavior for a resource, auth, filtering, pagination, tenancy, import/export, serialization etc. Then we expanded rails generators to cover ALL typical behavior. And the markdown file calls the generators. It was a bit complicated to model polymorphic behavior but we got it working thanks to Ruby/Rails. But the basic premise that made this work is: Use only restful actions; don’t turn it into RPC. Recognize that most RPC/graphql functions are state changes that could have been a patch request. So instead of /clients/activate its /clients with a status attribute for “activate” or “archive”. Then most nested routes aren’t needed, use accepts nested attributes for and return child ids in the show action. There’s more to it that this but by strictly following conventions and modeling the data for rest, the api ends up Super simple. Our standard controller only whitelists strong params. All other behavior is automatic.
- mierz00 9mo agoWhat do the markdown files look like?
- digitaltrees 9mo agoDefines the resources, attributes and relationships. That’s it. Client first_name last_name organization:references Organization name tax_number has_many:Clients
- matltc 9mo agoGlad to see internal stack traces cleaned up (maybe we can get relative paths some day?) and Set finally get the respect it deserves!
- Alifatisk 9mo agoRelative path in stack trace would be so good!
- deleted 9mo ago[deleted]
- pmdr 9mo ago3.x has been awesome, let's hope 4 will be even better!
- nomilk 9mo agoWhat's the relevance of ractors to the average web dev? Will ractors be useful directly in controllers/models/tasks? Or is it more that ractors will be useful to those working on the ruby language (and perhaps some gems - lower level stuff, perhaps), and therefore to the average ruby(/rails) programmer things 'just work', but faster?
- magmostafa 9mo agoExciting to see Ruby 4.0.0 released! The new conditional syntax improvements (if condition1 && condition2) are really elegant. The Ruby::Box feature for true parallelism looks particularly promising for CPU-bound workloads. This could significantly improve performance in scenarios where we've historically had to resort to external services or other languages. Looking forward to seeing real-world benchmarks and adoption patterns emerge.
- magmostafa 9mo agoRuby 4.0's parallel execution improvements are a game-changer for the ecosystem. The ruby::Box feature addresses one of the biggest pain points - GIL limitations - while maintaining Ruby's elegance. What's particularly exciting is how this positions Ruby for modern workloads. With proper parallelism, Ruby apps can finally compete with Go and Node.js in concurrent scenarios without sacrificing developer happiness. The typing improvements also can't be understated. Gradual typing strikes the right balance - it helps teams scale codebases without forcing the verbosity of Java or the complexity of TypeScript's type gymnastics. Looking forward to seeing how the Rails ecosystem adopts these features. This could spark a Ruby renaissance in 2025.
- deleted 9mo ago[deleted]
- jadbox 9mo ago> "With proper parallelism, Ruby apps can finally compete with Go and Node.js in concurrent scenarios without sacrificing developer happiness" In theory, maybie. Parallelism support isn't a boolean though as there's a lot of additional factors at play. Just as one example, late stage Visual Basic also got parallelism support, but it really didn't help the overall positioning of the the language among its peers.
- codesnik 9mo agofrom what I understand, ruby::Box has nothing to do with GIL. At least, not yet.
- chucke 9mo agoHappy bday ruby! For the usual doomsdaysayers saying "ruby can't X so I left it for Y", when X is typing, RBS is becoming the accepted standard (now that sorbet supports it),and RBS inline notation next to signature/code too (for peeps complaining about separate files); when X is LSP, ruby-lsp is the standard and already supports "go to definition" (its major hole for a long time), and its plugin architecture allows other other features to reuse the same code AST/index (So that each linter/formatter/type checker doesn't have to parse their own); when X is parallelism, ractors are have actually become performant in a lot of common cases, and it's only missing some GC improvements to be truly non-experimental. There are new shiny things like ZJIT or Box, but even the core team recommends against using them in production for now. But they'll get better, as its been happening with the things listed above. No wildly new syntax changes is also a good thing. Should help alternative implementations catch up.
- screenothethird 9mo agoIt’s just inferior to Python, nobody is making a more complex argument than that. Why ever use Ruby when there’s a virtually identical system that’s faster with a bigger community.
- amazingman 9mo agoBlanket statements like this are unhelpfully tribal. Ruby has its uses, and underpins one of the most successful (and cloned) MVC frameworks of all time. But yeah, Python received the attention of data scientists early on and now it's a lingua franca of sorts in that domain. Since AI is so hot right now that makes Python seem superior, but really that's just contingency. If you're going to make claims, support them.
- block_dagger 9mo agoWhy? Because Python is generally slower, uses significant whitespace in its syntax, and lacks the metaprogramming features of Ruby.
- BowBun 9mo agoIn what ways is it inferior? Neither Ruby or Python are 'fast', so if that is one of your qualifiers you've already made a suboptimal choice. As for a bigger community, what does that serve? The large python community adds misdirection and more voices to a language that lacks some basic features still. Async/sync code models are still being finalized whereas Ruby has been stable in this regard for 10+ years. Same with tooling - the Ruby side is more consistent and stable: Sidekiq for background jobs (Celery is barely coming to maturity), Bundler for dependencies (pip? poetry? uv?). Mature auth + other frameworks like Devise. Having worked in both languages professionally, I strongly disagree with your take.
- zhisme 9mo agoAm I the only one who expected something bigger in a major release? With Ruby 3 we had the whole “3x3” story and significant performance improvements. This release feels more like a minor version, something closer to 3.5. I don’t want to downplay the work done by the maintainers on the contrary, huge thanks to them. But I do feel the version number is a bit misleading. That said, the work on the ZJIT[1] compiler is massive. It’s serious, professional engineering, and definitely deserves respect. [1]: https://rubykaigi.org/2025/presentations/maximecb.html https://rubykaigi.org/2025/presentations/maximecb.html
- codesnik 9mo agoeh, it's just a little celebration. Let Matz have it.
- prh8 9mo agoOne issue is gems which are locked `ruby < 4.0` which will now require updating, and releasing 4.0 instead of 3.5 was only done very recently. For a more concrete example, the grpc gem locks Ruby versions (< 3.5), and they refuse to change it. So until they support the next Ruby version, we could test ruby-next by testing with a preview release. This worked for 3.4 and 3.5, but now doesn't work with 4.0 (bundler resolves 4.0-preview2 > 3.5, whereas we are able to do 3.5-preview1). So unless I feel like doing a lot of grunt work (which I don't), I can't even test Ruby 4 in our app until they release a new version. And while I recognize this is an issue with the gem, it is a consequence of choosing to do 4.0.
- prh8 9mo agoFor future readers, I mistakenly referenced the grpc gem; I was thinking of the gem `gruf` which is a grpc framework
- Doctor_Fegg 9mo agoRuby doesn’t follow semver.
- werdnapk 9mo ago
- Exuma 9mo agoI love ruby so much
- __float 9mo agoIf I remember correctly, the namespaces feature (now released as Ruby::Box) had some pretty severe performance penalties (possibly even for code that doesn't use it?). Does anyone know if that's been improved?
- auraham 9mo agoI gave it a try a few months ago. The first thing that I searched for was the REPL. Comparing it with Python, I prefer ipython over irb. It would be nice to see some improvement on DX on the REPL side
- Lio 9mo agoWhat actionable things do you think IRB is missing vs ipython?
- schneems 9mo agoNow available on Heroku https://devcenter.heroku.com/changelog-items/3521 https://devcenter.heroku.com/changelog-items/3521
- bvan 9mo agoFor someone wanting to learn Ruby in 2025/26, what are some good up-to-date references, outside of the official documentation? Are there any recently-published books which stand-out?
- dueyfinster 9mo agoI've done the pragmatic studio elixir and erlang courses and they are high quality. They do the same for Ruby and Rails[1] [1]: https://pragmaticstudio.com/rails https://pragmaticstudio.com/rails
- Kerrick 9mo agoThe PickAxe is still amazing. You can buy the fifth edition (for Ruby 3.3) in paper now, or the sixth edition (for Ruby 4.0) as a beta ebook now. 5th: https://pragprog.com/titles/ruby5/programming-ruby-3-3-5th-edition/ https://pragprog.com/titles/ruby5/programming-ruby-3-3-5th-e... 6th: https://pragprog.com/titles/ruby6/programming-ruby-4-6th-edition/ https://pragprog.com/titles/ruby6/programming-ruby-4-6th-edi... For a timeline-oriented reference of changes, check out https://rubyreferences.github.io/rubychanges/ https://rubyreferences.github.io/rubychanges/ and its individual pages.
- msie 9mo agoI would like multi-line comments to make it into Ruby one day.
- riffraff 9mo agoBut they have always been there? =begin/=end, perldoc style.
- h14h 9mo agoIt's not overstating it to say I owe my entire SE career to Ruby. Without it's accessible syntax, I don't know that I would have ever managed to overcome the initial "I have no idea what's going on" barrier. For whatever reason when I started out I found excess boilerplate & ceremony very overwhelming, and Ruby was the first language where I felt the joy of discovery more often than the frustration of cluelessness. Although I've found myself gravitating away from object-orientation and towards languages that lean into functional principles, I will always hold a lot of fondness and respect for Ruby. For my brain and learning style, it's hard to imagine a better first language. It's very cool to see how far it's come since 2.x!