On Thu, Sep 13, 2012 at 1:54 PM, Matthew Kerwin <[email protected]> wrote:
> Sorry if my answer was a bit air-headed. Here's a more tangible example:
>
> class HoursMinutes
> attr_accessor :hours
> attr_reader :minutes
> def initialize h,m
> @hours = h
> self.minutes = m
> end
> def <=> o
> r = (@hours <=> o.hours)
> r = (@minutes <=> o.minutes) if r == 0
> r
> end
> def succ
> HoursMinutes.new(@hours, @minutes+1)
> end
> def minutes= m
> while m > 60
> @hours += 1
> m -= 60
> end
> while m < 0
> @hours -= 1
> m += 60
> end
> @minutes = m
> end
> def to_s
> "%d:%02d" % [@hours, @minutes]
> end
> end
>
> range = HoursMinutes.new(8,0)..HoursMinutes.new(9,0)
> p range.to_a
>
> The spaceship operator will break if `o` doesn't quack like an
> HoursMinutes object, and it's not very useful, but it might be a
> decent starting place.
Your #succ method does not overflow. I would make the class immutable
since that has some advantages. Here's a different solution which
also includes range checking and basic math.
class HoursMinute
attr_reader :hour, :minute
def initialize(hr, mn)
raise ArgumentError, "Out of range: %2d:%02d" % [hr, mn] unless
(0..23).include?(hr) && (0..59).include?(mn)
@hour = hr.to_int
@minute = mn.to_int
end
def to_s; "%2d:%02d" % [hour, minute] end
def succ; self + 1 end
def +(min)
hr, mn = (hour * 60 + minute + min.to_int).divmod 60
self.class.new(hr % 24, mn)
end
def -(min) self + -min end
def hash; hour * 60 + minute end
def eql?(o) hour == o.hour && minute == o.minute end
def <=>(o) (hour <=> o.hour).nonzero? || minute <=> o.minute end
end
Kind regards
robert
--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
-- You received this message because you are subscribed to the Google Groups
ruby-talk-google group. To post to this group, send email to
[email protected]. To unsubscribe from this group, send email
to [email protected]. For more options, visit this
group at https://groups.google.com/d/forum/ruby-talk-google?hl=en