my understanding of coerce is that it's used to produce a pair of operands -
myself and other - which can be used to perform operations.
so, in the case of Fixnum#+ we might see
def + other
x, y = other.coerce self
x + y
end
which is to say Fixnum need not know about how to add every possible class -
rather it leaves that knowledge up to those classes to export via thier coerce
method. as i understand it that method should return two new objects which
interoperate so, in the case above (which is made up) we might have
duration = Duration::new 42.0
42 + duration
here would call duration(42) and expect back an x and y which could be added
together. so, if @seconds happens to be a Fixnum the result will be another
Fixnum. if @seconds happens to a Float the result would be a Float.
i admit that i'm not crystal clear on this, but it sure seems to work:
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
def + other
x, y = coerce(other)
x + y
end
end
def Duration(*a, &b); Duration::new(*a, &b); end
p( 40 + Duration(2.0) ) # Float 42.0
p( 40 + Duration(2) ) # Fixnum 42
p( 40.0 + Duration(2.0) ) # Float 42.0
p( 40.0 + Duration(2) ) # Float 42.0
p( Duration(40) + 2 ) # Fixnum 42
p( Duration(40) + 2.0 ) # Float 42.0
p( Duration(40.0) + 2) # Float 42.0
p( Duration(40.0) + 2.0 ) # Float 42.0
harp:~ > ruby a.rb
42.0
42
42.0
42
42.0
i assume one would do something nice with the coerce method using Time, Date,
and DateTime objects too...
regards.
-a
···
On Sun, 19 Mar 2006, Trans wrote:
ara.t.howard@noaa.gov wrote:
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.
--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama