[#97678] [Ruby master Feature#16752] :private param for const_set — bughitgithub@...
Issue #16752 has been reported by bughit (bug hit).
5 messages
2020/04/02
[ruby-core:97825] [Ruby master Bug#16660] Struct#deconstruct_keys inconsistent behavior
From:
kazuki@...
Date:
2020-04-11 11:34:27 UTC
List:
ruby-core #97825
Issue #16660 has been updated by ktsj (Kazuki Tsujimoto).
Status changed from Open to Rejected
My stance is "if we really should care about consistency over performance, we should remove the `keys` argument itself from the specification.
Otherwise, we should do a thorough optimization using the `keys` argument(*)".
Since `deconstruct_keys` is supposed to be used implicitly in the context of pattern matching rather than explicitly by the user,
I don't think this inconsistency will actually cause confusion for the user.
(*) This means that the return value of `deconstruct_keys` is implementation-dependent.
---
> I believe that such optimization should be done within the pattern matching implementation, not a particular class API.
Let's compare `Struct#deconstruct_keys` to `Hash#deconstruct_keys`.
```ruby
# Struct#deconstruct_keys(palkan's version)
s.deconstruct_keys([:a, :c])
#=> {a: 1}
# Hash#deconstruct_keys(2.7's version)
h = {a: 1, b: 2}
h.deconstruct_keys([:a, :c])
#=> {a: 1, b: 2}
```
Should `h.deconstruct_keys([:a, :c])` also return `{a: 1}`?
I don't think so.
The optimal return value for each class is different.
Therefore, we should implement optimized `#deconstruct_keys` in each class.
> we can re-use the deconstruction hash for keys subsets or cache the result of the key presence check
The return value can still be cached in the current specification.
For example:
```ruby
case val
in {a:, b:, c:}
in {a:, b:}
end
```
We can compile this code as following pseudo code:
```ruby
case val
in {a:, b:} && {c:}
in {a:, b:}
end
```
----------------------------------------
Bug #16660: Struct#deconstruct_keys inconsistent behavior
https://bugs.ruby-lang.org/issues/16660#change-85047
* Author: palkan (Vladimir Dementyev)
* Status: Rejected
* Priority: Normal
* Assignee: ktsj (Kazuki Tsujimoto)
* ruby -v: ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
----------------------------------------
Here is an example of a kind of surprising (at least to me) `Struct#deconstruct_keys` behaviour:
```ruby
klass = Struct.new(:a, :b)
s = klass.new(1, 2)
```
1) When some keys are not recognized and the total number of the keys is not greater than the size of the struct:
```ruby
s.deconstruct_keys([:a, :c])
#=> {a: 1}
```
2) When some keys are not recognized but the total number of the keys is greater than the size of the struct:
```ruby
s.deconstruct_keys([:a, :b, :c])
#=> {}
```
It's not clear why the first one filters unknown keys and the latter one returns an empty Hash instead of the `{a: 1}`.
This behaviour was introduced in https://github.com/ruby/ruby/commit/2439948bcc0ec9daf91cf79301195e59bad49aff. Prior to that change an empty hash was returned in both cases.
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>