Issue #14602 has been updated by edmz (Ed Mz).
Following what @mame explained about Matz expectations, I would like to (*humbly*) suggest another option:
* `dig_expected`
(and a my +1 to `dig_strict`)
----------------------------------------
Feature #14602: Version of dig that raises error if a key is not present
https://bugs.ruby-lang.org/issues/14602#change-106033
* Author: amcaplan (Ariel Caplan)
* Status: Open
* Priority: Normal
----------------------------------------
Currently, if I have a hash like this:
~~~ ruby
{
:name => {
:first => "Ariel",
:last => "Caplan"
}
}
~~~
and I want to navigate confidently and raise a KeyError if something is missing, I can do:
~~~ ruby
hash.fetch(:name).fetch(:first)
~~~
Unfortunately, the length of the name, combined with the need to repeat the method name every time, means most programmers are more likely to do this:
~~~ ruby
hash[:name][:first]
~~~
which leads to many unexpected errors.
The Hash#dig method made it easy to access methods safely from a nested hash; I'd like to have something similar for access without error protection, and I'd think the most natural name would be Hash#dig!. It would work like this:
~~~ ruby
hash = {
:name => {
:first => "Ariel",
:last => "Caplan"
}
}
hash.dig!(:name, :first) # => Ariel
hash.dig!(:name, :middle) # raises KeyError (key not found: :middle)
hash.dig!(:name, :first, :foo) # raises TypeError (String does not have #dig! method)
~~~
--
https://bugs.ruby-lang.org/
Issue #18035 has been updated by Dan0042 (Daniel DeLorme).
I understand the advantages of immutability, but I worry about the overall direction this is taking us. So I'll just quote something @mame wrote previously, as it reflects my own opinion.
mame (Yusuke Endoh) wrote in #16153#note-6:
> I'm against making Ruby immutable by default. One of the most important properties of Ruby is dynamics. Ruby has allowed users to change almost anything in run time: dynamically (re)defining classes and methods (including core builtin ones), manipulating instance variables and local variables (via Binding) through encapsulation, etc. These features are not recommended to abuse, but they actually bring big flexibility: monkey-patching, DRY, flexible operation, etc. However, blindly freezing objects may spoil this usefulness.
>
> It is a bit arguable if this flexibility limits performance. Some people say that it is possible to make Ruby fast with the flexibility kept (TruffleRuby proves it). That being said, I admit that the flexibility actually limits performance in the current MRI, and that we have no development resource to improve MRI so much in near future. I think that my proposal #11934 was one possible way to balance the flexibility and performance. Anyway, we need to estimate how much Ruby can be faster if the flexibility is dropped. If it becomes 10 times faster, it is worth considering of course. If it becomes 10 percent faster, it does not pay (in my opinion).
----------------------------------------
Feature #18035: Introduce general model/semantic for immutability.
https://bugs.ruby-lang.org/issues/18035#change-106031
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
It would be good to establish some rules around mutability, immutability, frozen, and deep frozen in Ruby.
I see time and time again, incorrect assumptions about how this works in production code. Constants that aren't really constant, people using `#freeze` incorrectly, etc.
I don't have any particular preference but:
- We should establish consistent patterns where possible, e.g.
- Objects created by `new` are mutable.
- Objects created by literal are immutable.
We have problems with how `freeze` works on composite data types, e.g. `Hash#freeze` does not impact children keys/values, same for Array. Do we need to introduce `freeze(true)` or `#deep_freeze` or some other method?
Because of this, frozen does not necessarily correspond to immutable. This is an issue which causes real world problems.
I also propose to codify this where possible, in terms of "this class of object is immutable" should be enforced by the language/runtime, e.g.
```ruby
module Immutable
def new(...)
super.freeze
end
end
class MyImmutableObject
extend Immutable
def initialize(x)
@x = x
end
def freeze
return self if frozen?
@x.freeze
super
end
end
o = MyImmutableObject.new([1, 2, 3])
puts o.frozen?
```
Finally, this area has an impact to thread and fiber safe programming, so it is becoming more relevant and I believe that the current approach which is rather adhoc is insufficient.
I know that it's non-trivial to retrofit existing code, but maybe it can be done via magic comment, etc, which we already did for frozen string literals.
Proposed PR: https://github.com/ruby/ruby/pull/4879
--
https://bugs.ruby-lang.org/
Issue #20148 has been reported by zohaibnadeem13(a)gmail.com (Zohaib Nadeem).
----------------------------------------
Bug #20148: Sorting not working as expected on Urdu words.
https://bugs.ruby-lang.org/issues/20148
* Author: zohaibnadeem13(a)gmail.com (Zohaib Nadeem)
* Status: Open
* Priority: Normal
* ruby -v: 3.1.4
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
I was trying to sort an array of Urdu characters and found out an ambiguity in the result. Here is the script that I am using.
['ا', 'پ', 'ب', 'ت', 'ٹ'].sort
Actual Result:
["ا", "ب", "ت", "ٹ", "پ"]
Expected Result:
["ا", "ب", 'پ', "ت", "ٹ"]
--
https://bugs.ruby-lang.org/
Issue #13383 has been updated by ioquatix (Samuel Williams).
If we decided to introduce this feature, I'm against using a plain Array. Let's use a well defined interface.
----------------------------------------
Feature #13383: [PATCH] Module#source_location
https://bugs.ruby-lang.org/issues/13383#change-106016
* Author: koba789 (Hidekazu Kobayashi)
* Status: Rejected
* Priority: Normal
* Assignee: ioquatix (Samuel Williams)
----------------------------------------
# Abstract
It can inspect where the module or class is defined.
# Background
In debugging or development an application, I usually want to find out where the class definition of using library.
There is Method#source_location but I could not find **Class** easily.
# Implementation
In Github: https://github.com/ruby/ruby/pull/1562
--
https://bugs.ruby-lang.org/
Issue #19409 has been reported by luke-gru (Luke Gruber).
----------------------------------------
Bug #19409: Object's shape is reset after a ractor move
https://bugs.ruby-lang.org/issues/19409
* Author: luke-gru (Luke Gruber)
* Status: Open
* Priority: Normal
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
I believe an object should have the same shape after being moved from 1 ractor to another.
```ruby
class Obj
attr_accessor :a, :b, :c, :d
def initialize
@a = 1
@b = 2
@c = 3
end
end
r = Ractor.new do
obj = receive
#p RubyVM::Shape.of(obj)
obj.d = 4
p obj.a, obj.b, obj.c, obj.d # gets wrong values due to object shape id being reset on object
end
obj = Obj.new
#p RubyVM::Shape.of(obj)
r.send(obj, move: true)
r.take
```
--
https://bugs.ruby-lang.org/
Issue #19411 has been reported by luke-gru (Luke Gruber).
----------------------------------------
Bug #19411: GC issue with moved objects
https://bugs.ruby-lang.org/issues/19411
* Author: luke-gru (Luke Gruber)
* Status: Open
* Priority: Normal
* ruby -v: 3.2.0
* Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN
----------------------------------------
This crashes:
```ruby
class Obj
def initialize
@obj = 3
end
end
GC.stress = true
r = Ractor.new do
obj = receive
p obj
end
obj = Obj.new
r.send(obj, move: true)
r.take
```
It only crashes with nested objects, if you remove the ivar set in `initialize` it works fine. Maybe missing `RB_GC_GUARD`?
--
https://bugs.ruby-lang.org/
Issue #15927 has been updated by luke-gru (Luke Gruber).
This can be closed as I agree with the feedback given. Thanks!
----------------------------------------
Feature #15927: Allow string keys to be used for String#% and sprintf methods
https://bugs.ruby-lang.org/issues/15927#change-106008
* Author: luke-gru (Luke Gruber)
* Status: Open
* Priority: Normal
----------------------------------------
Right now, in the methods sprintf() and String#%, only symbol keys can be used for named interpolation. For example (from the example documentation):
"foo = %{foo}" % { :foo => 'bar' } #=> "foo = bar"
String keys do not work like this:
"foo = %{foo}" % { 'foo' => 'bar' } #=> raises KeyError
I think string keys should work just the same as symbol keys here.
I've created a PR on github for this, perhaps misguidedly, but if can be found here: https://github.com/ruby/ruby/pull/2238
My argument for this feature is that String#gsub() and family works with string keys if given a Hash, for example:
"chocolate ice cream".gsub(/\bc/, { 'c' => 'C' }) #=> 'Chocolate ice Cream'
Also, I don't like having to symbolize keys in strings unnecessarily, but maybe that just goes back to when
Ruby couldn't GC some symbols.
--
https://bugs.ruby-lang.org/
Issue #18035 has been updated by matheusrich (Matheus Richard).
I'm not sure this was already mentioned, but this feels related to 3.2's Data class.
If this is accepted, should Data classes all be immutable? To quote [the docs](https://docs.ruby-lang.org/en/3.2/Data.html):
> Data provides no member writers, or enumerators: it is meant to be a storage for immutable atomic values. But note that if some of data members is of a mutable class, Data does no additional immutability enforcement:
>
> ```rb
> Event = Data.define(:time, :weekdays)
> event = Event.new('18:00', %w[Tue Wed Fri])
> #=> #<data Event time="18:00", weekdays=["Tue", "Wed", "Fri"]>
>
> # There is no #time= or #weekdays= accessors, but changes are
> # still possible:
> event.weekdays << 'Sat'
> event
> #=> #<data Event time="18:00", weekdays=["Tue", "Wed", "Fri", "Sat"]>
> ```
----------------------------------------
Feature #18035: Introduce general model/semantic for immutability.
https://bugs.ruby-lang.org/issues/18035#change-106004
* Author: ioquatix (Samuel Williams)
* Status: Open
* Priority: Normal
----------------------------------------
It would be good to establish some rules around mutability, immutability, frozen, and deep frozen in Ruby.
I see time and time again, incorrect assumptions about how this works in production code. Constants that aren't really constant, people using `#freeze` incorrectly, etc.
I don't have any particular preference but:
- We should establish consistent patterns where possible, e.g.
- Objects created by `new` are mutable.
- Objects created by literal are immutable.
We have problems with how `freeze` works on composite data types, e.g. `Hash#freeze` does not impact children keys/values, same for Array. Do we need to introduce `freeze(true)` or `#deep_freeze` or some other method?
Because of this, frozen does not necessarily correspond to immutable. This is an issue which causes real world problems.
I also propose to codify this where possible, in terms of "this class of object is immutable" should be enforced by the language/runtime, e.g.
```ruby
module Immutable
def new(...)
super.freeze
end
end
class MyImmutableObject
extend Immutable
def initialize(x)
@x = x
end
def freeze
return self if frozen?
@x.freeze
super
end
end
o = MyImmutableObject.new([1, 2, 3])
puts o.frozen?
```
Finally, this area has an impact to thread and fiber safe programming, so it is becoming more relevant and I believe that the current approach which is rather adhoc is insufficient.
I know that it's non-trivial to retrofit existing code, but maybe it can be done via magic comment, etc, which we already did for frozen string literals.
Proposed PR: https://github.com/ruby/ruby/pull/4879
--
https://bugs.ruby-lang.org/
Issue #20112 has been reported by ariasdiniz (Aria Diniz).
----------------------------------------
Bug #20112: Ractors not working properly in ruby 3.3.0
https://bugs.ruby-lang.org/issues/20112
* Author: ariasdiniz (Aria Diniz)
* Status: Open
* Priority: Normal
* ruby -v: 3.3.0
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
I recently installed Ruby 3.3.0, and noticed that some of my scripts that use Ractors started to struggle with performance. After doing some benchmarks, I noticed that, while Ractors seem to be working well on Ruby 3.2.2, they're not working properly on 3.3.0.
I'm using Ubuntu 22.04.3 LTS
Here is the benchmark code:
``` ruby
# frozen_string_literal: true
require 'benchmark'
Ractor.new { :warmup } if defined?(Ractor)
Benchmark.bmbm do |x|
x.report("Thread: ") do
threads = []
8.times do |i|
threads << Thread.new do
20000000.times do |j|
((i * 20000000) + j)**2
end
end
end
threads.each(&:join)
end
x.report("Ractor: ") do
ractors = []
0..8.times do |i|
ractors << Ractor.new(i) do |k|
20000000.times do |j|
((k * 20000000) + j)**2
end
end
end
ractors.map(&:take)
end
end
```
Here is the results for Ruby 3.2.2:
Rehearsal --------------------------------------------
Thread: 7.666909 0.001091 7.668000 ( 7.675266)
Ractor: 19.318528 0.012017 19.330545 ( 2.505888)
---------------------------------- total: 26.998545sec
user system total real
Thread: 7.918141 0.004011 7.922152 ( 7.928772)
Ractor: 19.366414 0.003954 19.370368 ( 2.517993)
Here is the results for Ruby 3.3.0:
Rehearsal --------------------------------------------
Thread: 8.634152 0.010895 8.645047 ( 8.645104)
Ractor: 100.172179 0.035985 100.208164 ( 15.213245)
--------------------------------- total: 108.853211sec
user system total real
Thread: 9.451236 0.004002 9.455238 ( 9.460132)
Ractor: 118.463294 0.119942 118.583236 ( 18.462157)
--
https://bugs.ruby-lang.org/