Def +=


(KONTRA Gergely) #1

Hi!

I’ve successfully redefined the + method, the <=> method in some
classes, but when I tried the same with +=, it doesn’t work.
(I use ruby 1.6.6)

Eg.:
class Hash
def +=(other)
{} # dummy
end
end

gives:
SyntaxError: compile error
def +=(other)
^
(irb):5: parse error

Then, my Q is how to (re)define the += operator (method)).

Thx in advance

Gergo

±[Kontra, Gergely @ Budapest University of Technology and Economics]-+

    Email: kgergely@mcl.hu,  kgergely@turul.eet.bme.hu          |

URL: turul.eet.bme.hu/~kgergely Mobile: (+36 20) 356 9656 |
±------“Olyan langesz vagyok, hogy poroltoval kellene jarnom!”-------+
.
Magyar php mirror es magyar php dokumentacio: http://hu.php.net


(Dan Debertin) #2

Kontra, Gergely writes:

Hi!

I’ve successfully redefined the + method, the <=> method in some
classes, but when I tried the same with +=, it doesn’t work.
(I use ruby 1.6.6)

That’s because += isn’t really a method, it’s just a compound of + and
=. Redefine +, and it affecs +=.

Dan

···


airboss@nodewarrior.org
www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.


(Michael Neumann) #3

It’s simply not possible!

When you define a + operator, Ruby automatically “adds” a += operator
which behaves like a = a + b.

Regards,

Michael

···

On Tue, Jun 11, 2002 at 02:41:04AM +0900, Kontra, Gergely wrote:

Hi!

I’ve successfully redefined the + method, the <=> method in some
classes, but when I tried the same with +=, it doesn’t work.
(I use ruby 1.6.6)

Eg.:
class Hash
def +=(other)
{} # dummy
end
end

gives:
SyntaxError: compile error
def +=(other)
^
(irb):5: parse error

Then, my Q is how to (re)define the += operator (method)).


(Christoph) #4

“Kontra, Gergely” kgergely@mlabdial.hit.bme.hu wrote in

Then, my Q is how to (re)define the += operator (method)).

It is a C++ idiom to define an +'' operator in terms of an+=’'
operator. This could never work in Ruby since symbols (Ruby’s
variables) are always references - it’s kind of like expecting that

#include
const int five = 5;
const int seven = 7;

int main() {
const int * x = &five;
x += 2;
std::cout << (x == &seven);
}

is returning true, ehm, 1. This is the same reasoning way there are
no ++, succ! etc. operators.

/Christoph


(Jean-Hugues ROBERT) #5

Hello,

Hi!

I’ve successfully redefined the + method, the <=> method in some
classes, but when I tried the same with +=, it doesn’t work.
(I use ruby 1.6.6)

Eg.:
class Hash
def +=(other)
{} # dummy
end
end

gives:
SyntaxError: compile error
def +=(other)
^
(irb):5: parse error

Then, my Q is how to (re)define the += operator (method)).

It’s simply not possible!

When you define a + operator, Ruby automatically “adds” a += operator
which behaves like a = a + b.

Regards,

Michael

How is that += automatically generated (if at all) ?

If figured out that it could be done using a .clone() and a .replace(v)
that the user would still have to provide (I was wrong, read further).

Having += behavior automatically changed when one redefines + is cool!
I wondered why it does not also work the other way around (i.e. +()
changed when user defines +=()) ?

The result could sometimes be much more efficient:

Here is a (dense) example dealing with files:

class LargeFile # Case 1: where User redefines +()
def fname() id.to_s end
def to_s() File.open(fname,“r”){|x|x.gets} end
def replace(v) File.open(fname,“w”){|x|x.write v.to_s}; self end
def clone() LargeFile.new.replace self end
def +(a) c=clone; File.open(c.fname,“w+”){|x|x.write a.to_s}; c end

Presumably automatically generated code ?

def +=(a) replace( self + a) end
end

class LargeFile # Case 2: where User redefines +=()
def fname() id.to_s end
def to_s() File.open(name,“r”){|x|x.gets} end
def clone() LargeFile.new() += self end
def +=(a) File.open(fname,“w+”){|x|x.write a.to_s}; self end

Presumably automatically generated code

def +(a) self.clone += a end
end

The efficiency of +() is the same in both cases.

However the efficiency of +=() is better in case 2 because case 1 requires
the creation of a new object (by +()) whereas it is directly self
that gets modified in case 2.

I then wondered: Why would a language favor a scheme so obviously less
efficient ? Well… Ruby does what’s necessary.

I had a look at the mailing list archive. Turns out that:

  1. There is apparently no such thing as a “generated” += method
  2. a += b is actually 100% equivalent to a = a + b
  3. a = “a”; b = a; a += b; p a, b => “aa” “a”
  4. a = “a”; b = a; a << b; p a, b => “ab” “ab”
  5. When speed matters, use <<, not +, not +=
    However: check page 549 of Syngress’s book “RUBY Developer’s Guide”
  6. += has “value” semantic, << has “object semantic”
  7. Infering +() from +=() only… is impossible:
    a copy constructor (a la C++) or .clone() (a la Smalltalk) is needed.
  8. This is all related to Mutability I guess.
    See http://www.c2.com/cgi/wiki?ValueObjectsShouldBeImmutable

Yours,

Jean-Hugues

···

At 02:53 11/06/2002 +0900, you wrote:

On Tue, Jun 11, 2002 at 02:41:04AM +0900, Kontra, Gergely wrote:


Web: http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17


(Joel VanderWerf) #6

Jean-Hugues ROBERT wrote:

How is that += automatically generated (if at all) ?

Actaully, += is not a method. IIRC x += 1 just syntax sugar for x = x +
1.

If it were a method, what would the receiver be? Normally in Ruby the
receiver of x.foo is the object which is the value of x, but in this
case you want to replace one value with another. In other words, you
need to operate on the variable itself. In Ruby, that can only be done
with assignment, for good reasons.