Issue #14701 has been updated by mame (Yusuke Endoh).


I agree with matz and eregon.

Honestly, I first thought that it was a good idea to split `+` and `+=`.  But by investigating Python, I now think that it easily leads to strange behavior.  One example is what eregon and sonots said:

```
>>> a = []
>>> b = a
>>> a += [1,2,3]
>>> b
[1, 2, 3]
```

Most Rubyists know and expect that `Array#+` is non-destructive, so I think that it is unacceptable to allow this.

Another example is the following that is Python's actual result.  I don't want to see this in Ruby.

```
>>> a = []
>>> a += "foo"
>>> a
['f', 'o', 'o']
```

```
>>> a = []
>>> a + "foo"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list
```

If I explain this behavior in Ruby terminology, `Array#+=` accepts any Enumerable, but `Array#+` does not.  Note that this spec design itself is somewhat reasonable.  `Array#+` accepts only an Array because, is it accepts an Enumerator, it is ambiguous what it should return, Array or Enumerator.  On the other hand, this does not matter for `Array#+=` because an assignment returns no value in Python.

So, I think that these Python's behavior is indeed intentional.  But actually strange.  IMO, the fundamental flaw is to split `+` and `+=`.


sonots (Naotoshi Seo) wrote:
> ANOTHER IDEA:
> How about allowing to redefine `+!` instead of `+=` although it looks not intuitive for me, but it would be a ruby way.

Do you mean introducing another set of destructive operators, like `a +! 1` instead of `a += 1`?  It is not very cool, but it seems more reasonable to me.

----------------------------------------
Feature #14701: If the object is not frozen, I want to be able to redefine the compound assignment operator.
https://bugs.ruby-lang.org/issues/14701#change-71650

* Author: naitoh (Jun NAITOH)
* Status: Rejected
* Priority: Normal
* Assignee: 
* Target version: 
----------------------------------------
If the object is not frozen, I want to be able to redefine the compound assignment operator (e.g. +=, -=, *=, /=, ..etc ).

https://docs.ruby-lang.org/ja/latest/doc/spec=2foperator.html

* Redefinable operator (method) 

~~~
    |  ^  &  <=>  ==  ===  =~  >   >=  <   <=   <<  >>
    +  -  *  /    %   **   ~   +@  -@  []  []=  ` ! != !~
~~~

* use case

~~~
> require 'numo/narray'
> a = Numo::Int32[5, 6]
=> Numo::Int32#shape=[2]
[5, 6]
> a.object_id
=> 70326927544920
> a += 1
=> Numo::Int32#shape=[2]
[6, 7]
> a.object_id
=> 70326927530540
> a.inplace + 1
=> Numo::Int32(view)#shape=[2]
[7, 8]
> a.object_id
=> 70326927530540
~~~

With Numo::NArray, using "inplace" instead of "+=" will update the same object so it will be faster.

I want to write "a += 1" instead of "a.inplace + 1".
However, Ruby can not redefine "+=".



-- 
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>