can you enable coercion between types?

L

larry

I have a ruby class called Duration that represents a unit of time.
It's main attribute is a number that represents the duration in
seconds.

If I try to save it to a DB using Rails, I get a "Duration can not be
coerced into Float" error. Is there a way to modify the definition of
Duration to enable automatic coercion into a float? (I'm thinking of
something like adding a "to_float" method to the class.)

thanks in advance
larry
 
A

ara.t.howard

I have a ruby class called Duration that represents a unit of time.
It's main attribute is a number that represents the duration in
seconds.

If I try to save it to a DB using Rails, I get a "Duration can not be
coerced into Float" error. Is there a way to modify the definition of
Duration to enable automatic coercion into a float? (I'm thinking of
something like adding a "to_float" method to the class.)

thanks in advance
larry

try this:

harp:~ > cat a.rb
class Duration
def initialize seconds
@seconds = seconds
end
def coerce other
if other.class == @seconds.class
[@seconds, other]
else
[Float(@seconds), Float(other)]
end
end
end

p(40.0 + Duration::new(2.0))
p(40 + Duration::new(2))


harp:~ > ruby a.rb
42.0
42

hth.

-a
 
T

Trans

try this:

harp:~ > cat a.rb
class Duration
def initialize seconds
@seconds = seconds
end
def coerce other
if other.class == @seconds.class
[@seconds, other]
else
[Float(@seconds), Float(other)]
end
end
end

Could you explain what this is doing? I don't get the effect.

Thanks,
T.
 
M

Markus

try this:

harp:~ > cat a.rb
class Duration
def initialize seconds
@seconds = seconds
end
def coerce other
if other.class == @seconds.class
[@seconds, other]
else
[Float(@seconds), Float(other)]
end
end

There's a gottcha here. Coerce is used to implement double dispatch and
so needs to return the coerced values in the opposite order (see Pick
Axe)--(other,self), not (self,other).

The way you wrote it works fine for addition & multiplication, but
you'll pull your hair out the first time you try to subtract or divide.

--MarkusQ

P.S. And I think (as Tom noted) that "to_f" was the answer to the
original question.
 
A

ara.t.howard

try this:

harp:~ > cat a.rb
class Duration
def initialize seconds
@seconds = seconds
end
def coerce other
if other.class == @seconds.class
[@seconds, other]
else
[Float(@seconds), Float(other)]
end
end

There's a gottcha here. Coerce is used to implement double dispatch and
so needs to return the coerced values in the opposite order (see Pick
Axe)--(other,self), not (self,other).

The way you wrote it works fine for addition & multiplication, but
you'll pull your hair out the first time you try to subtract or divide.

indeed. good catch.

cheers.
-a
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,667
Latest member
DaniloB294

Latest Threads

Top