Issue #10570 has been updated by David MacMahon.


Thanks for your thoughtful reply!

Yukihiro Matsumoto wrote:
> `a+=b` is a short hand form of `a = a + b` by definition. It's fundamentally an assignment. Target of assignment (including += etc) is a variable, not an object. It cannot be implemented by a method.

I agree that `a = a + b` is fundamentally an assignment (and I'm not asking for an assignment operator :-)).  I'm not sure that the definition of `a += b` as a short hand form of `a = a + b` is quite so fundamental.  Definitions can be redefined.

What about `a[i] = b`?  That is (or at least looks like) a form of assignment that is already implemented as a method.

> For example, how can we define `Integer#+=`?

Immutable classes would simply not define a `+=` method.  For example, we already have `Fixnum#[]` without `Fixnum#[]=`.

Dave

----------------------------------------
Feature #10570: Allow `+=` etc. to be methods
https://bugs.ruby-lang.org/issues/10570#change-50308

* Author: David MacMahon
* Status: Rejected
* Priority: Normal
* Assignee: 
* Category: 
* Target version: 
----------------------------------------
In MRI, it is currently possible to create `#+=` methods in C extensions and even `+=` aliases for existing methods in Ruby source code.  These methods are only callable via `#send('+=', ...)` because the parser interprets `a += b` as `a = a + b` before the "operator method" is called.  Thus, `a += b` is currently equivalent to `a = a.send('+', b)` rather than `a.send('+=', b)`.  This feature request is to allow and support `<OP>=` methods, where `<OP>` is any of Ruby's operators that can be defined as methods (e.g. `#+`, `#-`, etc).

A related feature request would be to allow `#<attribute><op>=` methods in addition to the already supported`#<attribute>=` methods.  As it is now, `foo.bar += x` is equivalent to `foo.send('bar=', foo.send('bar').send('+', x))`, which requires that the return value of `foo.bar` implements `#+` and that `foo` implements `#bar=`.  If this related feature were implemented, `foo.bar += x would be equivalent to `foo.send('bar+=', x)`.

I guess this would be tricky to add in a backwards compatible way.  What happens if `#+=` is not defined for the would-be receiver?  How would that condition be detected in a way that could fall back to the old default behavior?

What other possible complications could make this request impractical?



-- 
https://bugs.ruby-lang.org/