say I have a new class Foo which provides * as a multiplicative method.
Now, given the following lines:
def some_operation_using( lft, rgt )
return "#{lft} times #{rgt}"
end
class Foo
def *( other )
# do something
res = some_operation_using( other, self )
return res
end
def to_s
return "a Foo thingy."
end
end
That given, the following lines will work
f = Foo.new
puts f * 42.0
But this won’t. Instead I get:
…/lm.rb:25:in `*’: Foo can’t be coerced into Float (TypeError)
from …/lm.rb:25
puts 42.0 * f
What would be a (or even the) Ruby Way to get the last line to work?
Some method to coerce a Foo into a Float? Or some hacking of Float
itself? Like adding that, for example:
class Float
alias old_mult *
def *( other )
if other.class == Foo
return other * self
else
return self.old_mult( other )
end
end
end
That doesn’t seem to be terribly elegant, I think.
say I have a new class Foo which provides * as a multiplicative method.
Now, given the following lines:
def some_operation_using( lft, rgt )
return “#{lft} times #{rgt}”
end
class Foo
def *( other )
# do something
res = some_operation_using( other, self )
return res
end
def to_s
return “a Foo thingy.”
end
end
That given, the following lines will work
f = Foo.new
puts f * 42.0
But this won’t. Instead I get:
…/lm.rb:25:in `*': Foo can’t be coerced into Float (TypeError)
from …/lm.rb:25
puts 42.0 * f
What would be a (or even the) Ruby Way to get the last line to work?
Some method to coerce a Foo into a Float? Or some hacking of Float
itself? Like adding that, for example:
class Float
alias old_mult *
def *( other )
if other.class == Foo
return other * self
else
return self.old_mult( other )
end
end
end
That doesn’t seem to be terribly elegant, I think.
It is maybe not a good idea to reverse the order in coerce.
It may work with * and +, but you will get a problem when
order matters, like in / (division):
#— including the above code —
class Foo
def /(other)
“divide #{self} by #{other}”
end
end
puts (f / 2)
=> “divide a Foo thingy. by 2”
puts (2 / f)
=> “divide a Foo thingy. by 2”
#— end code —
Note that some classes which use *, and don’t represent a number
just give an error:
“string” * 2
=> “stringstring”
2 * “string”
=> TypeError: String can’t be coerced into Fixnum
That behaviour is probably the best if you are not representing
a number.
Kristof
···
On Sun, 02 May 2004 20:43:20 +0900, ts wrote:
#!/usr/bin/ruby
def some_operation_using( lft, rgt )
“#{lft} times #{rgt}”
end
class Foo
def *(other)
# do something
res = some_operation_using( other, self )
res
end
def coerce(other)
case other
when Numeric
[self, other]
else
raise TypeError
end
end
def to_s
“a Foo thingy.”
end
end
f = Foo.new
puts f * 42.0
puts 42.0 * f
svg%
svg% b.rb
42.0 times a Foo thingy.
42.0 times a Foo thingy.
svg%