From: "bughit (bug hit) via ruby-core" <ruby-core@...>
Date: 2024-05-21T15:05:06+00:00
Subject: [ruby-core:117956] [Ruby master Bug#20218] aset/masgn/op_asgn with keyword arguments

Issue #20218 has been updated by bughit (bug hit).



These are not arguments for removing a useful, long-standing syntactic feature, but for fixing the various edge cases with it.

Multiple assignment segfaults in 2.6 too. I didn't know about it but it did not prevent me from using the feature, but this "fix" sure will.

> It could be changed to make it similar to operator assignment, but that would be worse in terms of backwards incompatibility

As someone who's is actually using this functionality, that's a change that would be acceptable to accommodate. kwargs separation is already there so you have to deal with the fallout in multiple contexts. So no it would not be generally "worse". The feature should remain, I already illustrated its utility.  

----------------------------------------
Bug #20218: aset/masgn/op_asgn with keyword arguments
https://bugs.ruby-lang.org/issues/20218#change-108374

* 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 -- 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/postorius/lists/ruby-core.ml.ruby-lang.org/