# Binary operators, coerce, and non numeric types

**URL:** <https://www.ruby-forum.com/t/binary-operators-coerce-and-non-numeric-types/63976>\
**Category:** Ruby\
**Created:** [June 20, 2006, 10:38pm UTC](https://www.ruby-forum.com/t/binary-operators-coerce-and-non-numeric-types/63976 "2006-06-20T22:38:15Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![polypus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/b5ac83/32.png) [@polypus](https://www.ruby-forum.com/u/polypus)\
**Post date:** [June 20, 2006, 10:38pm UTC](https://www.ruby-forum.com/t/binary-operators-coerce-and-non-numeric-types/63976/1 "2006-06-20T22:38:15Z")

</div>

okay, i understand how to define a coerce method, but i don’t think it  
can do what i want, in fact i think the only way to do what i want is  
rather ugly unless i drill down and actually patch the interpreter.

class X  
def + other  
BinOp.new(self,other,:+)  
end  
end

class BinOp  
def initialize x,y,op  
@x,@y,@op=x,y,op  
end  
end

x = X.new

x + x # -\> BinOp, the behaviour i want  
x + 3 # -\> BinOp, the behaviour i want  
3 + 3 # -\> 6, the behaviour i want  
3 + x # is of courses an error, but i want it to return a BinOp

the only way i can find that ruby will support this, is by writing

class Fixnum  
alias old\_add +  
def + other  
if other.kind\_of? X  
BinOp.new self, other, :+  
else  
self.old\_add other  
end  
end  
end

which is pretty ugly considering i have many operators to support, as  
well as several numeric types. of course i could automate it with some  
metaprogramming, but i’d like to know if anyone has any better ideas?

---

<div class="post-metadata">

**Author:** ![polypus](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/b5ac83/32.png) [@polypus](https://www.ruby-forum.com/u/polypus)\
**Post date:** [June 20, 2006, 11:32pm UTC](https://www.ruby-forum.com/t/binary-operators-coerce-and-non-numeric-types/63976/2 "2006-06-20T23:32:29Z")

</div>

ok i hadn’t fully grokked coerce, and have found a solution. just incase  
anybody is interested:

class X

def + other  
bin\_op other, :+  
end  
def \*\* other  
bin\_op other, :\*\*  
end  
def - other  
bin\_op other, :-  
end  
def / other  
bin\_op other, 😕  
end

def bin\_op other, op  
if @coerced  
@coerced = false  
BinOp.new other, self, op  
else  
BinOp.new self, other, op  
end  
end

def coerce other  
@coerced = true  
[self,other]  
end

end

class BinOp  
def initialize x,y,op  
@x, @y, @op = x, y, op  
end  
def to\_s  
“BinOp #@x #@op #@y”  
end  
end

x = X.new

puts x + 3  
puts 3.0 + x  
puts 2 - x  
puts x - 10  
puts 23 \*\* x  
puts 2.99 / x  
puts x / -1

cheers,  
\_c
