[ruby-core:117904] [Ruby master Bug#20218] aset/masgn/op_asgn with keyword arguments
From:
"bughit (bug hit) via ruby-core" <ruby-core@...>
Date:
2024-05-17 15:37:37 UTC
List:
ruby-core #117904
Issue #20218 has been updated by bughit (bug hit).
In this issue there's no consideration of compatibility and utility. This is a breaking change. The ability to pass kwargs to index methods has been in ruby for a long time, probably from the inception of kwargs and I have code that uses that. Ruby doesn't have a spec so MRI behavior is effectively the spec so you can't say using kwargs in index methods was somehow "wrong". It wasn't "wrong" empirically and it's not "wrong" conceptually. kwargs just allow for more variability in store/lookup operations via index methods, it allows you to control where/how something is stored/looked up.
this is from 2.6
```ruby
module IndexTest
@store = {}
def self.store
@store
end
def self.key(name, namespace: nil)
name = "#{namespace}:#{name}" if namespace
name
end
def self.[](name, namespace: nil)
p [name, namespace]
@store[key(name, namespace: namespace)]
end
def self.[]=(name, opts = {}, val)
p [name, opts, val]
@store[key(name, namespace: opts[:namespace])] = val
end
end
IndexTest['foo'] = 1
p IndexTest['foo']
IndexTest['foo', namespace: 'bar'] = 2
p IndexTest['foo', namespace: 'bar']
p IndexTest.store
```
So kwargs in index methods should be preserved for the sake of compatibility and utility. The only reasonable breaking change here is for `[]=` to have real kwargs, rather than the middle positional kwarg collector hash in the above example.
----------------------------------------
Bug #20218: aset/masgn/op_asgn with keyword arguments
https://bugs.ruby-lang.org/issues/20218#change-108321
* Author: jeremyevans0 (Jeremy Evans)
* Status: Closed
* Backport: 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN
----------------------------------------
I found that use of keyword arguments in multiple assignment is broken in 3.3 and master:
```ruby
h = {a: 1}
o = []
def o.[]=(*args, **kw)
replace([args, kw])
end
# This segfaults as RHS argument is not a hash
o[1, a: 1], _ = [1, 2]
# This passes the RHS argument as keywords to the method, treating keyword splat as positional argument
o[1, **h], _ = [{b: 3}, 2]
o
# => [[1, {:a=>1}], {:b=>3}]
```
Before 3.3, keyword arguments were treated as positional arguments.
This is similar to #19918, but for keyword arguments instead of block arguments.
@matz indicated he wanted to prohibit block arguments in aset/masgn and presumably also op_asgn (making them SyntaxErrors). Can we also prohibit keyword arguments in aset/masgn/op_asgn?
Note that aset treats keyword arguments as regular arguments:
```ruby
o[1, a: 1] = 2
o
# => [[1, {:a=>1}, 2], {}]
o[1, **h] = {b: 3}
o
# => [[1, {:a=>2}, {:b=>3}], {}]
```
While op_asgn treats keyword arguments as keywords:
```ruby
h = {a: 2}
o = []
def o.[](*args, **kw)
concat([:[], args, kw])
x = Object.new
def x.+(v)
[:x, v]
end
x
end
def o.[]=(*args, **kw)
concat([:[]=, args, kw])
end
o[1, a: 1] += 2
o
# => [:[], [1], {:a=>1}, :[]=, [1, [:x, 2]], {:a=>1}]
o.clear
o[1, **h] += {b: 3}
o
# => [:[], [1], {:a=>2}, :[]=, [1, [:x, {:b=>3}]], {:a=>2}]
```
--
https://bugs.ruby-lang.org/
______________________________________________
ruby-core mailing list -- [email protected]
To unsubscribe send an email to [email protected]
ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/