[#120465] [Ruby master Bug#20998] rb_str_locktmp() changes flags of frozen strings and string literals — "Eregon (Benoit Daloze) via ruby-core" <ruby-core@...>
Issue #20998 has been reported by Eregon (Benoit Daloze).
17 messages
2025/01/03
[ruby-core:120634] [Ruby master Feature#20953] Array#fetch_values vs #values_at protocols
From:
"zverok (Victor Shepelev) via ruby-core" <ruby-core@...>
Date:
2025-01-13 15:17:55 UTC
List:
ruby-core #120634
Issue #20953 has been updated by zverok (Victor Shepelev).
> What's the expected behavior of:
For `..42` versions, I believe that `values_at` behavior gives enough affordance:
```ruby
[1, 2, 3].values_at(..6)
#=> [1, 2, 3, nil, nil, nil, nil]
```
So, I suppose:
```ruby
[1, 2, 3].fetch_values(..6)
# IndexError at 3, same as...
[1, 2, 3].fetch_values(0, 1, 2, 3, 4, 5, 6)
[1, 2, 3].fetch_values(..6) { true }
#=> [1, 2, 3, true, true, true, true]
```
For `42..` it is not that straightforward, because `values_at` behavior is somewhat confusing here.
```ruby
[1, 2, 3].values_at(6..)
#=> []
```
We might just follow it, though. I believe that it is implicitly treated as
```ruby
[1, 2, 3].values_at(*(6..2).to_a)
```
(i.e. the apper bound is `(ary.size - 1)`), and, as this range is empty, nothing is tried to be fetched from the array. So it should just be the same:
```ruby
[1, 2, 3].fetch_values(6..)
#=> []
```
It is not an immediately obvious thing, but I am not sure what would be the one; and at least this behavior is already established.
Alternatively, if the range _beginning_ is out of bounds, `fetch_values` might raise. This would be explainable, too.
----------------------------------------
Feature #20953: Array#fetch_values vs #values_at protocols
https://bugs.ruby-lang.org/issues/20953#change-111463
* Author: zverok (Victor Shepelev)
* Status: Open
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
I believe that the user might expect `#fetch_values` to be a stricter version of `#values_at`, confirming to the same protocol for arguments.
But the current implementation for `#fetch_values` is simpler:
```ruby
[1, 2, 3, 4, 5].values_at(0, 3..4) #=> [1, 4, 5]
[1, 2, 3, 4, 5].fetch_values(0, 3..4) # TypeError: in 'Array#fetch': no implicit conversion of Range into Integer
```
I believe aligning the implementations would lessen confusion (even if it makes `#fetch_values` implementation somewhat less trivial).
The practical example of usefulness:
```ruby
HEADERS = %w[Name Department]
def table_headers(rows)
HEADERS.fetch_values(...rows.map(&:size).max) { '<unknown'> }
# Or, alternatively:
# HEADERS.fetch_values(...rows.map(&:size).max) { raise ArgumentError, "No header defined for column #{it + 1}" }
end
table_headers([
['John'],
['Jane'],
]) #=> ["Name"]
table_headers([
['John'],
['Jane', 'Engineering'],
]) #=> ["Name", "Department"]
table_headers([
['John', 'Accounting', 'Feb 24'],
['Jane', 'Engineering'],
]) #=> ["Name", "Department", "<unknown>"]
# or ArgumentError No header defined for column 3
```
(Obviously, we can use `fetch_values(*(0...max_row_size))` as an argument, but it feels like an unjustified extra work when `values_at` already can do this.)
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- ruby-core@ml.ruby-lang.org
To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org
ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/