+=
for free.class Tester1
def initialize x
@x = x
end
def +(y)
@x + y
end
end
a = Tester1.new 5
puts(a + 3)
# => 8
a += 7
puts a
# => 12
The definition is not commutative, i.e., trying to do
3 + a
would fail. To get that to work you would need to override the addition method in Integer - and I think that would be a bad idea.The next example shows how to override comparison operators. Note that by overriding the equality operator, you get the inequality operator for free. Also note that you are not restricted to returning a boolean; in this example
<=
returns a string.class Tester2
def initialize ary
@ary = ary
end
attr_reader :ary
def ==(y)
@ary.length == y.ary.length
end
def <(y)
@ary.length < y.ary.length
end
def <=(y)
'@ary.length < y.ary.length'
end
end
b = Tester2.new %w(zero one two three)
puts b == Tester2.new([1, 2, 3, 4, 5])
# => false
puts b != Tester2.new([1, 2, 3, 4, 5])
# => true
puts b < Tester2.new([1, 2, 3, 4, 5])
# => true
puts b <= Tester2.new([1, 2, 3, 4, 5])
# => "@ary.length < y.ary.length"
You need to be careful when overriding operators, as it has the potential to make your code unfathomable. One time I think it is particular useful, however, is to add array-like properties to a class, for example to access an underlying array, as in this example. Note how the
+=
operator has to be defined via the + operator. Also, the index operator needs two methods if you want to be able to both read from and write to it.class Tester3
def initialize ary
@ary = ary
end
def [](y)
@ary[y]
end
def []=(y, value)
@ary[y] = value
end
def <<(y)
@ary << y
end
def +(y)
@ary << y
end
end
c = Tester3.new %w(zero one two three)
puts c[3]
# => three
c << 'four'
puts c[4]
# => four
c += 'five'
puts c[5]
# => five
As an aside, be aware that
<<
and +=
are not the same for an Array object (though they are for Tester3). The +=
operator requires an array, the members of which are added to the existing array. The <<
operator appends the new object to the array; if the new object is an array, you have the new array nested inside the existing array.You cannot override keywords, such as "or", nor can you override:
&& & || | () {} :: . ~ .. ...
Struggling with Ruby: Contents Page