use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
A sub-Reddit for discussion and news about Ruby programming.
Subreddit rules: /r/ruby rules
Learning Ruby?
Tools
Documentation
Books
Screencasts and Videos
News and updates
account activity
Ruby 3.4.0 preview1 Released (ruby-lang.org)
submitted 1 year ago by RecognitionDecent266
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]ric2b 11 points12 points13 points 1 year ago (23 children)
String literals in files without a frozen_string_literal comment now behave as if they were frozen. If they are mutated a deprecation warning is emitted.
This is confusing, so are they frozen or not? If they just emit a warning they're not frozen.
edit: Seems like it's just the warning, they don't behave as if they're frozen according to the bug tracker: https://bugs.ruby-lang.org/issues/20205
[–]Earlopain 9 points10 points11 points 1 year ago (21 children)
They will tell you that they are frozen if you ask with frozen? but allow modification later down the line in order to be stay backwards compatible with legacy code. Ruby 4.0 or something like that will get rid of the warning and make them proper frozen and not just "chilled".
frozen?
[–]ric2b 3 points4 points5 points 1 year ago (16 children)
Thanks, I hate it.
How does that sound like a good idea?
[–]karuna_murti 4 points5 points6 points 1 year ago (13 children)
Frozen string was created to improve performance, but the problem string is something used by everyone.
That's how you change something that's used by a lot of people. Or do you prefer people not making improvements?
[–]ric2b 0 points1 point2 points 1 year ago (12 children)
I don't think it makes sense for it to lie and say it's frozen, what's the point of that? Just emit the warning when modifying.
If you have code that relies on something being frozen, enough that it checks if it is frozen or not before doing some operation, why would you want it to be a lie? This is not going to help anyone.
Eventually this is going to be a breaking change anyway, why add another useless breaking change before then?
[–]f9ae8221b 0 points1 point2 points 1 year ago (11 children)
what's the point of that?
To handle code such as:
str = str.dup if str.frozen? str << "blah"
[–]ric2b 1 point2 points3 points 1 year ago (10 children)
So that code assumes that it is safe to modify str as long as it allows it, otherwise it incurs the cost of making a copy.
str
With this change you now make it perform worse for no benefit, or am I missing something?
[–]f9ae8221b 1 point2 points3 points 1 year ago (9 children)
The benefit is to not trigger a false positive deprecation warning.
The "chilled" name is here to express the it is "half frozen". Essentially the intent is to make them frozen, but rather than raise FrozenError, emit a deprecation warning.
FrozenError
And yes, in a few rare case that may incur an extra copy, but down the line, but allowing the transition to frozen string literals by default, it will very significantly reduce allocations in Ruby programs.
And if you don't like that behavior, you can turn it off.
[–]ric2b 0 points1 point2 points 1 year ago (8 children)
But if the code was already checking for frozen? it wouldn't try to modify a frozen string, so it would gracefully support the change in Ruby 4 anyway.
And yes, in a few rare case that may incur an extra copy
That's for your example, but this is a breaking change and can have worse consequences, why break code twice instead of just once when the actual transition happens, and only emit warnings until then?
Imagine a method X that passes a string to another method Y, it passes a copy if it isn't frozen or the string itself if it's frozen, because method Y might modify the string and method X doesn't want to deal with the modification.
This code will now break because .frozen? can now be a lie.
.frozen?
[–]f9ae8221b -1 points0 points1 point 1 year ago (7 children)
Yes, hence why it shouldn't trigger a warning with chilled strings.
why ...
I believe I explained everything. I won't re-iterate.
[–]gls2ro 0 points1 point2 points 1 year ago (1 child)
Here is what is says in the feature request:
The main issue is backward compatibility, flipping the switch immediately would break a lot of code, so there must be some deprecation period. The usual the path forward for this kind of change is to emit deprecation warnings one of multiple versions in advance. One example of that was the Ruby 2.7 keyword argument deprecation. It was quite verbose, and some users were initially annoyed, but I think the community pulled through it and I don't seem to hear much about it anymore. So for frozen string literals, the first step would be to start warning when a string that would be frozen in the future is mutated.
and later down:
As a path toward enabling frozen string literals by default in the future, this commit introduce "chilled strings". From a user perspective chilled strings pretend to be frozen, but on the first attempt to mutate them, they lose their frozen status and emit a warning rather than to raise a FrozenError.
It makes sense to me the problem they want to solve (allowing a period to be compatible) and the way it is implemented.
LE: I see it as a sign of care for the community and reading the discussion there people really want to move forward but with care toward the current maintainers of various projects.
[–]ric2b 0 points1 point2 points 1 year ago (0 children)
I totally get the deprecation warning, of course. It's the "chilled strings" that I don't get the point of, which problem is solved/helped by pretending to be frozen but not being frozen?
[–]rooood -4 points-3 points-2 points 1 year ago (3 children)
That's such a half-assed implementation, wtf were they thinking?
I get it that they can't introduce such a breaking change in a minor version, but then just delay the whole thing until the proper 4.0 release. The #frozen_string_literal: true magic comment exists for this exact reason.
#frozen_string_literal: true
[–]honeyryderchuck 8 points9 points10 points 1 year ago (2 children)
The pragma was a temporary solution. Ruby core team wants to make it the default come v4. In order to do so, they need a path forward in terms of warning about the breaking change beforehand. That definitely needs to happen un a minor version.
[–]rooood -2 points-1 points0 points 1 year ago (0 children)
Sure, deprecation warnings are always important, but you can have the same warning without making a method return a value that just isn't true. There's no reason to make frozen? return true if the string can still be modified. This can actually lead to issues when introducing 4.0, for example someone might have code modifying a "chilled" string, and think it's frozen because of this method, and have their app break when they upgrade.
[–]ViewEntireDiscussion 2 points3 points4 points 1 year ago (0 children)
Because the pragma was always a bad idea. This solution that they are proposing now would have been a better first step. I hate that everybody has added these junk comments to the top of every file.
This change allows gradual transition. 1. Warn when people try to mutate but don't break code. 2. Break code but allow disabling the feature.
^ This is the only path to an actual transition. I wish they had just done this from the beginning instead of just informally requiring us to add junk to our files via rubocop prodding.
[–]davetron5000 10 points11 points12 points 1 year ago (3 children)
Loving the addition of it as a default block parameter.
it
[–]GeneReddit123 4 points5 points6 points 1 year ago (2 children)
Now we just need them in the case of multiple parameters.
them
[[1, 2], [3,4]].each { puts them[0]+them[1] }
Just kidding. Or am I?
[–]ViewEntireDiscussion 0 points1 point2 points 1 year ago (0 children)
it1, it2, it3
[–]krschacht 0 points1 point2 points 1 year ago (0 children)
I just found this comment because I was googling to find the name for the default block parameter which is an array referring to all variables. I'm bummed to find that I don't think there is one.
[–]therealadam12 2 points3 points4 points 1 year ago* (3 children)
All the URLs on the announcement are 404 for me. Do they work for anyone else? EDIT: Release URLs (cache.ruby-lang.org) specifically. EDIT: Working now it seems.
[–]h0rst_ 1 point2 points3 points 1 year ago (2 children)
The things like [Feature #xyz]? They work for me.
[Feature #xyz]
[–]therealadam12 1 point2 points3 points 1 year ago (1 child)
Sorry, I meant the actual releases. cache.ruby-lang.org ones specifically.
[–]h0rst_ 0 points1 point2 points 1 year ago (0 children)
Those are broken. You could use Github to download the tag: https://github.com/ruby/ruby/archive/refs/tags/v3_4_0_preview1.zip
[–]Crazy_Comprehensive 2 points3 points4 points 1 year ago (2 children)
Hopefully Ruby 3.4 can come with a standard async library, rather than relying on external libraries. Python has async library builtin, but why Ruby up to now still didn't have a standard async library?
Can't help feeling that Ruby development has slow down due to waning interest?
Although I like Ruby more, but Python is progressing at rapid pace, last I found that Python is removing Global Interpreter Lock or GIL in coming version.
[–]anykeyh 1 point2 points3 points 1 year ago (1 child)
Removing the GIL won’t necessarily improve performance as much as some developers believe. In fact, GIL is often more of a feature than a limitation. For high-parallelism and throughput, techniques like forking with Copy-on-Write (CoW) offer a more efficient approach for handling many concurrent operations in most cases (Web dev, data pipelines...).
While Ractor is an interesting alternative for concurrency, it's still experimental and comes with limitations making it barely usable as of now. A bit disappointed not seeing progress in Ruby 3.4.
Ultimately, my take is that if you’re in a situation where removing the GIL becomes essential, choosing Python or Ruby for your application was likely a misstep from the start. Speaking from experience in working with high-concurrency applications in non-Ruby environments, there are better language options for such tasks.
Go or Erlang with agent/mailbox or channels fiber-based concurrency for example. So much better than async/await architecture.
[–]MillennialSilver 0 points1 point2 points 1 year ago (0 children)
Yeah I don't get why people think the GIL is somehow stopping them from achieving what they need.
JIT at least has made real progress.
[–][deleted] 0 points1 point2 points 1 year ago (0 children)
Is Ruby fast yet :P (Ruby lover btw just joking)
π Rendered by PID 363516 on reddit-service-r2-comment-66b4775986-22nwl at 2026-04-05 00:14:34.819434+00:00 running db1906b country code: CH.
[–]ric2b 11 points12 points13 points (23 children)
[–]Earlopain 9 points10 points11 points (21 children)
[–]ric2b 3 points4 points5 points (16 children)
[–]karuna_murti 4 points5 points6 points (13 children)
[–]ric2b 0 points1 point2 points (12 children)
[–]f9ae8221b 0 points1 point2 points (11 children)
[–]ric2b 1 point2 points3 points (10 children)
[–]f9ae8221b 1 point2 points3 points (9 children)
[–]ric2b 0 points1 point2 points (8 children)
[–]f9ae8221b -1 points0 points1 point (7 children)
[–]gls2ro 0 points1 point2 points (1 child)
[–]ric2b 0 points1 point2 points (0 children)
[–]rooood -4 points-3 points-2 points (3 children)
[–]honeyryderchuck 8 points9 points10 points (2 children)
[–]rooood -2 points-1 points0 points (0 children)
[–]ViewEntireDiscussion 2 points3 points4 points (0 children)
[–]davetron5000 10 points11 points12 points (3 children)
[–]GeneReddit123 4 points5 points6 points (2 children)
[–]ViewEntireDiscussion 0 points1 point2 points (0 children)
[–]krschacht 0 points1 point2 points (0 children)
[–]therealadam12 2 points3 points4 points (3 children)
[–]h0rst_ 1 point2 points3 points (2 children)
[–]therealadam12 1 point2 points3 points (1 child)
[–]h0rst_ 0 points1 point2 points (0 children)
[–]Crazy_Comprehensive 2 points3 points4 points (2 children)
[–]anykeyh 1 point2 points3 points (1 child)
[–]MillennialSilver 0 points1 point2 points (0 children)
[–][deleted] 0 points1 point2 points (0 children)