"Paul Brannan" <pbrannan / atdesk.com> wrote in
....
> On Thu, Apr 11, 2002 at 07:01:16PM +0900, Yukihiro Matsumoto wrote:
> > Unless you overload operator +=.
>
> I can overload operator+= and still get mutability:
>
>   #include <iostream>
>
>   struct Foo {
>     Foo(int x) : x_(x) { }
>     int x_;
>   };
>
>   int operator+=(int & lhs, Foo const & rhs) {
>     lhs = lhs + rhs.x_;
>   }
>
>   main() {
>     int x(1);
>     Foo y(2);
>     x += y;
>     std::cout << x << std::endl; // 3
>   }

In addition you typically define  Foo's internal ``+'' in terms
of  ``+='' - kind of the opposite of Ruby's approach.

----
struct Foo {
    int x_;
    Foo(int x) :  x_(x) {}
    Foo & operator+=(Foo &rhs) { // allow doubling
         x_+= rhs.x_;
        return *this;
    }
    Foo & operator+=(Foo const &rhs) {
         x_+= rhs.x_;
        return *this;
    }
    Foo operator+(Foo const &rhs) {
        return Foo(x_)+= rhs;
    }
};
----

>
> The difference here is that in Ruby I can't implicitly get a reference
> to an immutable.  I can, however, write a wrapper:
>
>   # (I use succ! because I can't overload +=; note that it would not be
>   # possible to write Integer#succ!)
>   class IntegerHolder

OT: It is tempting to inherite IntegerHolder from the abstract
Integer class except that Matz has disabled  Integer.new(allocate)
- consequently (ignoring the question if disabling of sub classing
was necessary) it makes sense to explicitly withdraw Integer it's
inheritance license (this is also true for the usual candidates
Symbol, NilClass, etc.)

class << Integer
    private
    def inherited(sub_klass)
        raise TypeError.new "Cannot sub class Integer"
    end
end

>     def initialize(integer) ; @integer = integer                     end
>     def +(other)            ; return type.new(@integer + other.to_i) end
>     def to_s                ; return @integer.to_s                   end
>     def to_i                ; return @integer.to_i                   end
>     def succ!               ; @integer += 1                          end

The proposed change (I am not really sure ?) would make the above
impossible if IntegerHolder were a sub-class of Numeric.

>   end
>
>   def increment(x)
>     x.succ!
>   end
>
>   x = IntegerHolder.new(42)
>   increment(x)
>   puts x # => 43
>
> One solution to this problem would be to have macros for certain methods
> that implicitly creates an IntegerHolder whenever the method is passed
> an Integer.  This might confuse extension writers, though.
>
> Paul
>