[HN Gopher] Ruby 4.0.0
       ___________________________________________________________________
        
       Ruby 4.0.0
        
       Author : FBISurveillance
       Score  : 658 points
       Date   : 2025-12-25 04:13 UTC (18 hours ago)
        
 (HTM) web link (www.ruby-lang.org)
 (TXT) w3m dump (www.ruby-lang.org)
        
       | aaronbrethorst wrote:
       | It wouldn't be Christmas without a new version of Ruby. Thanks
       | Matz and co!
        
       | nish__ wrote:
       | Ruby::Box looks useful.
        
         | shevy-java wrote:
         | Right 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 wrote:
       | This 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 wrote:
       | My best Christmas gift <3 Love you Ruby.
        
       | ksec wrote:
       | It 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 wrote:
         | To 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 wrote:
           | I 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 naive 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.
        
         | byroot wrote:
         | > It seems Ractor is still work in progress
         | 
         | The Ractor experimental status could almost be removed. They no
         | longer have known bugs, and only one noticeable performance
         | issue left (missing Ractor local GC).
         | 
         | But the API was just recently changed, so I think it's better
         | to wait another years.
         | 
         | > I vaguely remember reading Shopify is using Fiber / Rack /
         | Async in their codebase.
         | 
         | Barely. There is indeed this management obsession for fibers
         | even when it doesn't make sense, so there is some token usage
         | there and there, but that's it.
         | 
         | There is one application that was converted from Unicorn to
         | Falcon, but falcon isn't even configured to accept concurrent
         | requests, the gain is basically 0.
         | 
         | As for Rails, there isn't much use cases for fibers there,
         | except perhaps Active Record async queries, but since most
         | users use Postgres and PG connections are extremely costly, few
         | people are using AR async queries with enough concurrency for
         | fibers to make a very noticeable difference.
        
           | ksec wrote:
           | I just search for the tweet again and it state [1] "Falcon is
           | now serving most of Shopify storefront traffic: web and
           | API.", or is that an out of context quote?
           | 
           | [1] https://x.com/igrigorik/status/1976426479333540165
        
             | byroot wrote:
             | I know that tweet, it's real, but that doesn't contradict
             | my comment.
             | 
             | They indeed replaced Unicorn by Falcon in one application,
             | but falcon is configured in "Unicorn mode" (no concurrent
             | requests). So the gain is effectively 0.
             | 
             | Also note how they don't share any performance metrics,
             | contrary to https://railsatscale.com/2023-10-23-pitchfork-
             | impact-on-shop...
        
               | ksec wrote:
               | Thanks. That makes more sense.
        
       | mikestorrent wrote:
       | Still 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 wrote:
       | It truly is Christmas.
        
       | ergocoder wrote:
       | I 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 wrote:
         | There'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/
         | 
         | 1: https://newsletters.eremin.eu/posts
        
           | adamors wrote:
           | I'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.
        
         | vmware513 wrote:
         | Unfortunately, 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.
        
           | dismalaf wrote:
           | It's literally faster than Python but ok.
        
             | morcus wrote:
             | Is being faster than Python considered to be a notable
             | feature?
        
               | gkbrk wrote:
               | Python is one the most popular programming languages.
               | Ruby fits into a similar category as Python (high level,
               | interpreted scripting language, very dynamic, has a rich
               | ecosystem with tons of existing code). Being faster than
               | Python makes it more attractive to use, or port Python
               | codebases to.
        
               | wiseowise wrote:
               | Nobody cares about Ruby outside of RoR
               | 
               | Python is one of the Lingua Franca of scientific, data,
               | and most importantly, ai communities
               | 
               | Has much bigger community than Ruby
               | 
               | Has much, much better tooling story
               | 
               | Has much better gradual typing story
               | 
               | Isn't THAT much slower than Ruby, there are far more
               | attractive targets than Ruby if you care about
               | performance
        
               | wmoxam wrote:
               | I found scrooge.
               | 
               | Bah, humbug!
        
               | dismalaf wrote:
               | > Python is one of the Lingua Franca of scientific, data,
               | and most importantly, ai communities
               | 
               | You mean it's the most used frontend for all the C and
               | C++ libraries that are used for scientific computing,
               | data and AI.
        
               | wiseowise wrote:
               | Semantics.
        
               | dismalaf wrote:
               | Literally all those libraries are usable with Ruby.
               | Libtorch, BLAS, LAPACK, Tensorflow, etc...
        
               | wiseowise wrote:
               | And with Java, and with Go, and with Rust, and with
               | pretty much any language offering some form of FFI. But
               | they're used with Python, and good luck convincing your
               | interviewer that it should be used with Ruby.
        
               | dismalaf wrote:
               | > convincing your interviewer
               | 
               | Some of us don't work for others and just program what we
               | want.
        
               | dismalaf wrote:
               | Personally I don't care about speed for this category of
               | language. I just bring it up because Python is one of the
               | most used languages, is even slower, yet that's never
               | held against it. Just seems like a lazy way to dismiss
               | Ruby. Yeah, it's not as fast as C, Go, Rust or Java.
               | Everyone knows and raw speed obviously isn't the point of
               | a dynamic scripting language...
        
             | wiseowise wrote:
             | And has no ecosystem compared to Python.
             | 
             | Speed isn't why people choose Python.
        
         | mrinterweb wrote:
         | There is [RBS](https://sorbet.org/) (part of ruby 3) and
         | [sorbet](https://sorbet.org/). To be honest, these aren't
         | widely used as far as I am aware. I don't know if it is runtime
         | overhead, ergonomics, lack of type checking interest in the
         | ruby community or something else. Type enforcement isn't a big
         | part of ruby, and doesn't seem to be gaining much momentum.
        
           | vicentereig wrote:
           | I've been leaning hard into Sorbet runtime types for
           | DSPy.rb[0] and finding real value. T::Struct at API
           | boundaries, typed props for config, runtime validation where
           | data enters the system.
           | 
           | For generating (with LLMs) API clients and CLIs it's
           | especially useful--define the shape once, get validation at
           | ingress/egress for free.
           | 
           | Maybe momentum is happening in new projects rather than
           | retrofits? [0] https://oss.vicente.services/dspy.rb
        
           | pmontra wrote:
           | > lack of type checking interest in the ruby community
           | 
           | IMHO if we wanted to write types in our programming language
           | we would not have chosen Ruby for our programming tasks. We
           | would have chosen one of the zillion of other languages.
           | There were a lot of them when Ruby got traction about 20
           | years ago and many other languages have been created after
           | then. It's not surprising that one of the main proponent of
           | typing in Ruby is Shopify, because their path away from Ruby
           | is very costly.
           | 
           | In my case one of the reasons I invested in Ruby is precisely
           | because I did not have to write types.
           | 
           | Does it make Ruby slower than Java, my main language in 2005?
           | Yes.
           | 
           | Is it fast enough for my customers? Yes. Most of them decided
           | to use Ruby, then hired me.
           | 
           | Do I have to write unit tests to check for types? I don't.
           | 
           | Occasional problems that static types would have prevented to
           | happen? Once or twice per year. Overall that's a good
           | tradeoff because pleasing the type checker for non trivial
           | types can be a time consuming task and some errors happen at
           | runtime anyway, when the real world hits with its data a
           | carefully type checked code base or a carelessly dynamic
           | typed one. Think of an API suddenly returning a bad JSON,
           | maybe an HTML 500 page. Static or dynamic typing, both won't
           | help with that.
        
         | jweir wrote:
         | We have been adding Sorbet typing to our Rails application and
         | it is a positive enhancement.
         | 
         | It's not like Ruby becomes Haskell. But it does provide a good
         | deal of additional saftey, less testing, LSP integration is
         | good, and it is gradual.
         | 
         | There is a performance hit but we found it to be quite small
         | and not an issue.
         | 
         | But there are area of our application that use Grape and it is
         | too meta for Sorbet so we don't try and use it there.
        
           | vicentereig wrote:
           | Same here. T::Struct and T::Enums at API boundaries has been
           | the sweet spot--typed request/response models, runtime
           | validation at ingress/egress.
           | 
           | I've been using this pattern for API clients[0] and CLIs[1]:
           | define the shape once with Sorbet, get automatic JSON Schema
           | generation when you need it.
           | 
           | [0] https://github.com/vicentereig/exa-ruby [1]
           | https://github.com/vicentereig/lf-cli
        
           | lgas wrote:
           | > It's not like Ruby becomes Haskell.
           | 
           | Well, maybe next time.
        
         | rsanheim wrote:
         | _low_type_ is early days still, but I think this approach is
         | clearly the future of ruby typing. If this gets baked into the
         | language for full "compile" time support and minimal
         | performance impact, it will be amazing: https://github.com/low-
         | rb/low_type
        
           | ksec wrote:
           | It is definitely better than RBS and Sorbet. But unless
           | Github / 37Signals or Shopify decide to use it, it is highly
           | unlikely Ruby Core will consider it.
           | 
           | Out of all three I think Shopify have the highest
           | possibilities. There may be additional usefulness interms of
           | ZJIT.
        
           | Alifatisk wrote:
           | Previously, RBS-inline was the closest answer to typed Ruby,
           | it was the JSDoc of Ruby. Recently, when I stumbled upon
           | low_type and tried it out in irb, it finally felt like "this
           | is it, this is the TS of Ruby" and with runtime validation.
           | 
           | I like it, it deserves attention, especially for those who
           | are seeking for typed Ruby. With this, you can finally
           | experience it, and the syntax feels more ergonomic than with
           | Sorbet.
        
           | fny wrote:
           | This is so goergeous compared to the mess that's out there
           | now.
        
         | Gigachad wrote:
         | There's projects trying to implement it. But I've never seen a
         | project using typed Ruby.
         | 
         | I think most people who cared just moved to typescript.
        
         | dajonker wrote:
         | In my honest opinion, if you can't live without static typing,
         | Ruby just isn't for you.
         | 
         | Adding static typing to a dynamic language mostly gives you the
         | disadvantages of both, without a lot of benefits. It's better
         | to stick to languages that were designed with static types from
         | the start.
         | 
         | I love programming in Ruby, having to worry about type
         | annotations and the additional constraints that come with them
         | would take a lot of the fun out of that.
        
           | networked wrote:
           | > Adding static typing to a dynamic language mostly gives you
           | the disadvantages of both, without a lot of benefits.
           | 
           | Can you elaborate? I don't share this experience, and I'm
           | interested in bringing static typing to a language without
           | static typing, so I'd like to understand. In new Python and
           | JavaScript codebases, optional typing has had clear benefits
           | for refactoring and correctness and low costs for me. Legacy
           | codebases can be different.
        
             | azuanrb wrote:
             | Part of it is because Ruby imo, have a very nice syntax.
             | With type annotation, it's becoming "ugly", a lot more
             | verbose. It's no longer English-like. I do agree type have
             | some advantages, but we need to get the DX right.
             | 
             | I've been using Ruby for more than 10 years now, and I only
             | started using LSP recently. To me it's a nice addition but
             | I can live without it. Type is just one of the tools, not
             | the only one imo. Not trying to sound negative but type is
             | becoming more like a hammer analogy nowadays.
             | 
             | And it's not limited to Ruby. Javascript, Python, all
             | similar languages. Not everyone is a fan of type. We won't
             | reach consensus imo and that's ok.
        
               | clanky wrote:
               | > _With type annotation, it 's becoming "ugly", a lot
               | more verbose. It's no longer English-like._
               | 
               | In our codebase that uses Sorbet I find this is really
               | only true at function boundaries. Within a function it is
               | pretty rare that anything needs to be spelled out with
               | inline annotations to satisfy the compiler.
        
               | codesnik wrote:
               | This is my biggest irk about Sorbet: because its
               | signatures are wordy and because it can't infer the
               | generic type of a private method, it slightly pushes you
               | towards NOT extracting helper methods if they are going
               | to be 2-5 lines. With Sorbet annotation, it'd easily
               | become 10 lines. So it pushes towards bigger methods, and
               | those are not always readable.
               | 
               | If only private methods would be allowed not having
               | typing at all (with a promise of not being used in
               | subclasses, for example), and Sorbet would be used mostly
               | on the public surface of classes, it'd be much more
               | tolerable for me.
        
             | dajonker wrote:
             | I don't have a great code example at hand unfortunately,
             | but I found that people often tend to write more
             | "nominally" typed code (expecting explicitly named classes)
             | rather than taking advantage of duck typing (interfaces,
             | structural types), meaning the code becomes more rigid,
             | harder to change and more time wasted on resolving all the
             | type checks, even if the code otherwise is perfectly
             | reasonable and free of bugs.
             | 
             | In other words, I found that the resulting code often
             | looked more like Java but with weaker guarantees about
             | types and much worse performance.
        
           | vidarh wrote:
           | I mostly agree with you, but I'd say adding typing to _low
           | level core APIs_ is helpful in adding optimization
           | opportunities.
        
           | clanky wrote:
           | > _Adding static typing to a dynamic language mostly gives
           | you the disadvantages of both, without a lot of benefits._
           | 
           | As an engineer at a firm doing heavy duty data pipelines and
           | internal tooling in a Sorbet-ified codebase, I disagree
           | pretty strongly. While Sorbet type signatures are never going
           | to win a syntax beauty contest, they are more than worth
           | their weight in the way I can rely on them to catch typing
           | and nilability goofs, and often serve as helpful
           | documentation. Meanwhile, the internal code of most functions
           | I write still looks like straight Ruby, fluent and
           | uncluttered.
           | 
           | A good CI story that leans on tapioca was crucial here for
           | us.
        
         | ufmace wrote:
         | I've come to think that adding halfway-typing to languages
         | designed from the start to be dynamic is mostly not worth the
         | bother. It may help a little bit sometimes, but there's always
         | going to be holes. If you really want strong typing, it's
         | better IMO to bite the bullet and move to a language designed
         | for it. Let Ruby be Ruby, ditto Python, Javascript etc. Pick up
         | some JVM, .NET, Rust, Go, etc if you really want strong types.
        
         | weaksauce wrote:
         | another early days project but pretty well thought out in that
         | space: https://github.com/yippee-
         | fun/empirical/blob/main/literally_...
        
         | godd2 wrote:
         | Ruby has always been typed.
        
       | maz1b wrote:
       | It'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 wrote:
         | I've been doing                 if condition1 &&
         | condition2            ...       end
         | 
         | for ages and it seems to work find, what am I missing with this
         | new syntax?!
        
           | mantas wrote:
           | Personally && 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.
        
           | Sammi wrote:
           | Less likely to cause git merge conflict as you don't change
           | the original line. You only add one.
        
             | pmontra wrote:
             | What we need is a syntax aware git diff
             | https://news.ycombinator.com/item?id=42093756
        
               | bbkane wrote:
               | I agree, but I tend to find that "git diff aware syntax"
               | also makes things simpler for humans as well
        
           | fuzzythinker wrote:
           | In 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.
        
           | AlecSchueler wrote:
           | I prefer the new way because if you want to remove one
           | condition you just delete the line rather than having to edit
           | in multiple places.
        
             | flopsamjetsam wrote:
             | I first picked up this style from the GNU C++ style guide,
             | and it's so handy I use it in every language that accepts
             | it.
        
           | zelphirkalt wrote:
           | It's funny how I have been doing this way of writing the
           | conditions in languages, where one can, like Python (if you
           | use a pair of parentheses) and linters have yelled at me for
           | ages to put the binary operator on the previous line. People
           | herald these quite subjective things like truths, just
           | because there is some tool, that they can delegate
           | responsibility to.
        
           | mathgeek wrote:
           | For folks who scan code bases based on the front of lines, it
           | makes it easier to grok. Also helps with deleting and
           | inserting lines (similar to leading or trailing commas in
           | lists).
        
         | WJW wrote:
         | I'm kinda hoping that eventually each ractor will run in it's
         | own ruby::box and that each box will get garbage collected
         | individually, so that you could have separate GCs per ractor,
         | BEAM-style. That would allow them to truly run in parallel. One
         | benefit should be to cut down p99 latency, since much fewer
         | requests would be interrupted by garbage collection.
         | 
         | I'm not actually in need of this feature at the moment, but it
         | would be cool and I think it fits very well with the idea of
         | ractors as being completely separated from each other. The
         | downside is of course that sharing objects between ractors
         | would get slower as you'd need to copy the objects instead of
         | just sharing the pointer, but I bet that for most applications
         | that would be negligible. We could even make it so that on
         | ractor creation you have to pass in a box for it to live in,
         | with the default being either a new box or the box of the
         | parent ractor.
        
           | byroot wrote:
           | They already truly run in parallel in Ruby 4.0. The
           | overwhelming majority of contention points have been removed
           | in the last yet.
           | 
           | Ruby::Box wouldn't help reducing contention further, they
           | actually make it worse because with Ruby::Box classes and
           | modules and an extra indirection to go though.
           | 
           | The one remaining contention point is indeed garbage
           | collection. There is a plan for Ractor local GC, but it
           | wasn''t sufficiently ready for Ruby 4.0.
        
             | WJW wrote:
             | I know they run truly parallel when they're doing work, but
             | GC still stops the world, right?
             | 
             | Assuming you mean "because with Ruby::Box classes and
             | modules _have_ an extra indirection to go though. " in the
             | second paragraph, I don't understand why that would be
             | necessary. Can't you just have completely separate boxes
             | with their own copies of all classes etc, or does that use
             | too much memory? (Maybe some COW scheme might work,
             | doodling project for the holidays acquired haha)
             | 
             | Anyway, very cool work and I hope it keeps improving!
             | Thanks for 4.0 byroot!
        
               | byroot wrote:
               | > GC still stops the world, right?
               | 
               | Yes, Ractor local GC is the one feature that didn't make
               | it into 4.0.
               | 
               | > Can't you just have completely separate boxes with
               | their own copies of all classes etc, or does that use too
               | much memory?
               | 
               | Ruby::Box is kinda complicated, and still need a lot of
               | work, so it's unclear how the final implementation will
               | be. Right now there is no CoW or any type of sharing for
               | most classes, except for core classes.
               | 
               | Core classes are the same object (pointer) across all
               | boxes, however they have a constant and method table for
               | each box.
               | 
               | But overall what I meant to say is that Box wouldn't make
               | GC any easier for Ractors.
        
       | RomanPushkin wrote:
       | I'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 wrote:
         | You should try Falcon too.
        
         | 0xblinq wrote:
         | Just 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 wrote:
         | Langchain? 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 wrote:
         | Used 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 wrote:
           | RubyMine is free for non-commercial usage.
        
             | nurettin wrote:
             | Ah, that must be a recent development.
        
               | michaelcampbell wrote:
               | It is; last couple months.
        
         | jurgenkesker wrote:
         | This year I also switched from Ruby to Kotlin on my hobby/light
         | commercial backends. I just can't stand the way Ruby is not
         | statically typed, and the resulting insecurity around if
         | everything is actually doing what it should do. Kotlin gives me
         | joy, and performance is actually better (trading memory
         | requirements ofcourse, but that's not a big problem anymore). I
         | still love Ruby, but only use it for simple scripts now.
        
           | blandflakes wrote:
           | This has sort of been my issue with Elixir. I've been doing
           | Scala for years but I think Phoenix is really the best web
           | story at the moment for how _I_ want to be building web apps.
           | And while I believe that the benefits of static typing
           | somewhat decrease in the web arena, it 's still frustrating
           | to have to manage type relationships in my head.
           | 
           | I'm hopeful that the incoming type system work makes me
           | happier there, though I'd also prefer a nicer editor
           | experience than is currently available.
        
             | dmux wrote:
             | > I believe that the benefits of static typing somewhat
             | decrease in the web arena
             | 
             | I've seen this sentiment expressed numerous times and have
             | never found it to be true in my own work (e-comm), do you
             | mind mentioning _what_ type of domain your web apps are in?
             | 
             | Edit: or if not domain, what do you mean by "web arena"
        
         | pansa2 wrote:
         | > _fastapi, pytorch, langchain, streamlit, and so on and on_
         | 
         | It's telling that your reasons for switching are all features
         | of Python's ecosystem, not of the language itself. A lot of
         | developers are moving to Python because of its libraries, and
         | in many cases they don't care for the language at all.
         | 
         | That's causing a problem for Python: many of these developers
         | who'd rather be using different languages seem to want to morph
         | Python _into_ their language of choice. The result is that the
         | Python language is pulled in many different directions, and
         | with each release gets increasingly bloated and strays further
         | from its foundations.
         | 
         | Ruby, on the other hand, has a community that's mostly made up
         | of people who actually like the language. That allows it to do
         | a much better job of staying true to its core philosophy.
        
           | empthought wrote:
           | None of what you say about Python is true. It's not even
           | plausible. The Python language hasn't even had any
           | significant syntax changes for four versions now; versions
           | 3.11-3.14 are basically all internals optimizations.
           | 
           | Why would you write something so clearly false?
        
             | aobdev wrote:
             | Have you worked on different types of Python projects? (Not
             | in different codebases, different _types_ of codebases)
             | 
             | I don't have any specific complaints about Python syntax
             | because I can force it to get the job done...but
             | homogeneous, it is not.
        
             | chucke wrote:
             | Both are true. Different camps meant that any significant
             | change to the language was scrutinised loudly. If my memory
             | doesn't fail me, the last significant changes from the time
             | Guido was still in charge, and he mostly abandoned the BDFL
             | because of backlash. Since then python has been on a
             | constant "analysis paralysis" state, with only efforts
             | about performance pushing through (no one complains about a
             | faster horse).
        
               | woodruffw wrote:
               | > If my memory doesn't fail me, the last significant
               | changes from the time Guido was still in charge, and he
               | mostly abandoned the BDFL because of backlash
               | 
               | I think Guido left the BDFL role in 2018, and we've
               | gotten walrus operators, structured matching, and
               | exception groups since then (just off the top of my
               | head). There's also been significant language/grammar
               | accommodations towards type annotations.
               | 
               | Overall, I'm of the opinion that Python's language
               | evolution has struck a pretty nice balance -- there's
               | always going to be something new, but I don't feel like
               | the syntax has stagnated.
        
         | firemelt wrote:
         | I get the sentiment, pandas, numpy, pytorch
         | 
         | but I still love writing full stack webapp using rails so yeah
         | 
         | thats why I really love pyCall
        
       | Bolwin wrote:
       | Have they improved tooling? I've yet to get any lsp working on
       | windows
        
         | ornornor wrote:
         | IMO 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 wrote:
           | Or wsl2
        
           | nurettin wrote:
           | To be fair, vscode and .net core on linux is pretty much like
           | having windows and visual studio at this point.
        
             | array_key_first wrote:
             | Without the debugger, unfortunately. You still need VS or
             | Rider for that.
        
               | seabrookmx wrote:
               | The 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 wrote:
           | That'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
        
             | cwyers wrote:
             | Just use WSL2 and Docker Desktop. VS Code has DevContainer
             | support so you can standardize on a Docker image for your
             | project.
        
         | Alifatisk wrote:
         | It's below expectations, and even worse on Windows.
         | 
         | Luckily people seem to be aware of this and there was a whole
         | talk about improving Ruby DX.
        
         | epolanski wrote:
         | Tried WSL2?
        
       | digitaltrees wrote:
       | Ruby 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 wrote:
         | Curious to hear more about this, do you have any examples?
        
       | matltc wrote:
       | Glad to see internal stack traces cleaned up (maybe we can get
       | relative paths some day?) and Set finally get the respect it
       | deserves!
        
         | Alifatisk wrote:
         | Relative path in stack trace would be so good!
        
       | nomilk wrote:
       | What'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 wrote:
       | Exciting 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.
        
       | pmdr wrote:
       | 3.x has been awesome, let's hope 4 will be even better!
        
       | magmostafa wrote:
       | Ruby 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.
        
         | jadbox wrote:
         | > "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 wrote:
         | from what I understand, ruby::Box has nothing to do with GIL.
         | At least, not yet.
        
       | chucke wrote:
       | Happy 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 wrote:
         | It'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 wrote:
           | Blanket 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 wrote:
           | Why? Because Python is generally slower, uses significant
           | whitespace in its syntax, and lacks the metaprogramming
           | features of Ruby.
        
           | meesles wrote:
           | In 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.
        
           | Calavar wrote:
           | Because Ruby is just a better thought out language than
           | Python is. It had a sane package management story 15 years
           | before Python. It doesn't rely on weird hacks like exception
           | throwing for iterator control flow. It doesn't have nearly as
           | many warts and footguns on basic operations (for example, in
           | Python csv.writer(file).writerows(rows) is broken unless you
           | remembered to set the newline mode on the file; in Ruby
           | file.write(rows.to_csv) just works). Thanks to a sane VM
           | design it's mainline JIT can actually run code faster than
           | interpreted code (something that CPython's JIT can't do [1])
           | 
           | Many Pythonistas are woefully ignorant of what's going on
           | outside their siloed community.
           | 
           | [1] https://fidget-spinner.github.io/posts/jit-
           | reflections.html
        
             | lern_too_spel wrote:
             | Everything being mutable by default, including strings, is
             | about as big a foot gun as you can find in a high level
             | language.
        
           | bjoli wrote:
           | Ruby is a lot less awful than Python in my opinion. That is
           | of course a very subjective opinion. The only reason I write
           | more Python than Ruby is that ruby lacks the libraries I
           | need.
           | 
           | Somewhere along the line Python got all the momentum, and
           | ruby got none and now python is better if you just want to
           | get shit done.
           | 
           | But man. I wish it was the other way around. I have one code
           | snippet that summarises what I dislike about python:
           | if input() == "dynamic scope?":             defined =
           | "happyhappy"         print(defined)
           | 
           | Seeing that I understand why I see yuck in just about every
           | corner of python.
           | 
           | Edit: in ruby it also works, but the variable is at least
           | always defined.
        
             | qezz wrote:
             | > in ruby it also works, but the variable is at least
             | always defined.
             | 
             | How is this even a pro? I agree that Python scoping rules
             | are frustrating, but tbh not sure if I would prefer Ruby's
             | behavior in this case
        
               | bjoli wrote:
               | Well. If python is a dynamically scoped language, what
               | they do is correct. If they are lexically scoped (which
               | python is described as) the variable defined in the if
               | should never have different visibility in the same scope.
               | 
               | In a lexically scoped language you don't define variables
               | conditionally. What ruby does is also icky, but obviously
               | the developers of both python and ruby wanted to save the
               | developer an extra declaration. The ruby version is at
               | least more correct from a lexical standpoint (it is set
               | to nil if left "nondefined").
        
           | BurningFrog wrote:
           | A lot of times 2-3 lines of Ruby needs 5-8 lines in Python.
        
           | voidfunc wrote:
           | Python is great and I love writing glue in it, but Ruby is
           | just a better designed language and ecosystem overall.
        
           | pansa2 wrote:
           | > _that's faster_
           | 
           | In every test I've done, Ruby has been faster than Python. In
           | my experience that's been the case since Ruby 1.9, with the
           | move to YARV.
        
             | osigurdson wrote:
             | I don't think anyone says: "I switched from Python to Ruby"
             | (of vice versa) for performance.
        
               | pansa2 wrote:
               | True. Choosing between the two languages usually comes
               | down to their library ecosystems - or more bluntly, to
               | Rails on one hand vs NumPy on the other.
               | 
               | Nonetheless, it's still common for people to talk about
               | the relative performance of the two languages, and to
               | claim that Ruby is slower than Python. As someone who's
               | actually tested this, it hasn't been true for 15 years.
        
         | rco8786 wrote:
         | Fairly hardcore rubyist here. Ruby-lsp is excellent. But in no
         | way is RBS becoming standard. Maybe it will, I don't know. But
         | adoption is very, very low as of today. Rbs-inline is just
         | someone's pet project and has very little activity (though it
         | does appear that the person who wrote it is trying to implement
         | it directly into Rbs now, which would be great)
         | 
         | Personally I can't see any comment based typing system gaining
         | real traction.
        
           | block_dagger wrote:
           | As long as Matz is firmly against, inline typing should never
           | be a part of Ruby. I started working on a large Rails
           | codebase that adopted Sorbet and it is nothing but an
           | impediment to progress.
        
             | throwaway613745 wrote:
             | DHH also doesn't like typing in Ruby at all, and Rails is
             | designed around what he likes.
        
             | rco8786 wrote:
             | I think it will need to be a strong 3rd party that
             | basically gives it the Typescript treatment.
             | 
             | Adds type annotations to the core language syntax. The
             | compiler does type checking, strips the annotations, and
             | outputs plain Ruby.
        
               | anamexis wrote:
               | Sorbet is backed by Stripe.
               | 
               | Why is it important to be a separate layer that compiles
               | to plain untyped Ruby?
        
             | __float wrote:
             | I work in a large Sorbet codebase (though it isn't a Rails
             | one) and it's a huge boon IMO. The number of tests we _don
             | 't_ need to write because of Sorbet is really nice.
             | 
             | It does occasionally require structuring your code
             | differently, but I find the type-system-encouraged approach
             | often gives a more elegant and harder-to-misuse interface
             | in the end.
        
               | prh8 wrote:
               | You work in a large Ruby codebase that _isn't_ Rails?!
               | Are you hiring??
        
               | ezekg wrote:
               | I was assuming Stripe, but would love to hear of others!
        
               | zingar wrote:
               | Very curious to hear about the specific cases where types
               | make tests unnecessary.
               | 
               | I spend my working life swapping between Ruby and
               | typescript projects and the typescript project is utter
               | garbage with poor test coverage that needs a day of human
               | QA for every build whereas the Ruby project is well
               | tested such that we know that CI passing means it's good
               | to be released.
        
             | danmaz74 wrote:
             | > adopted Sorbet and it is nothing but an impediment to
             | progress
             | 
             | How so?
             | 
             | I never really missed types in Ruby, even if I like them a
             | lot in typescript, but right now I'm doing some "vibe
             | coding" on a personal project and I was thinking about
             | trying Sorbet. I think that it could help Claude Code avoid
             | some mistakes it often makes which make it waste a lot of
             | time fixing.
        
               | zingar wrote:
               | Interesting: how is CC in your experience at writing
               | tests and then using them to avoid mistakes?
        
               | danmaz74 wrote:
               | When writing non-vibe-coded software I use CC a lot to
               | write tests, but I have a skill to tell it not to create
               | redundant tests, which otherwise it tends to do, and I
               | have to check them anyway to ensure that they cover what
               | needs to be covered, and sometimes to trim them down.
               | 
               | When vibe coding, what I noticed is that CC tends to make
               | mistakes which it does catch with tests and fix on its
               | own, but my hope is that using Sorbet this will happen
               | much less, and thus development will go faster with less
               | (slow) test cycles.
        
           | chucke wrote:
           | Maybe I wasn't clear, but until now there were 2 types of
           | type notations being debated, RBS and sorbet/RBI. Sorbet
           | adopting RBS means that's the lowest common denominator.
           | Typing is definitely not a standard, not yet. rbs-inline is
           | definitely not a pet project, it's the RBS creator response
           | to the main complaint about RbS , its the reason sorbet
           | finally adopted it, and will be part of mainline rbs gem.
        
       | zhisme wrote:
       | Am 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
        
         | codesnik wrote:
         | eh, it's just a little celebration. Let Matz have it.
        
           | prh8 wrote:
           | One 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.
        
         | Doctor_Fegg wrote:
         | Ruby doesn't follow semver.
        
         | werdnapk wrote:
         | I think the major version change is more of a celebratory thing
         | with Ruby being 30 years as of 2025.
        
       | Exuma wrote:
       | I love ruby so much
        
       | __float wrote:
       | If 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 wrote:
       | I 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 wrote:
         | What actionable things do you think IRB is missing vs ipython?
        
       | schneems wrote:
       | Now available on Heroku https://devcenter.heroku.com/changelog-
       | items/3521
        
       | bvan wrote:
       | For 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 wrote:
         | I'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
        
       | msie wrote:
       | I would like multi-line comments to make it into Ruby one day.
        
         | riffraff wrote:
         | But they have always been there? =begin/=end, perldoc style.
        
       ___________________________________________________________________
       (page generated 2025-12-25 23:01 UTC)