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:
- There is apparently no such thing as a “generated” += method
- a += b is actually 100% equivalent to a = a + b
- a = “a”; b = a; a += b; p a, b => “aa” “a”
- a = “a”; b = a; a << b; p a, b => “ab” “ab”
- When speed matters, use <<, not +, not +=
However: check page 549 of Syngress’s book “RUBY Developer’s Guide”
- += has “value” semantic, << has “object semantic”
- Infering +() from +=() only… is impossible:
a copy constructor (a la C++) or .clone() (a la Smalltalk) is needed.
- 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: @jhr is virteal, virtually real
Phone: +33 (0) 4 92 27 74 17