On 11/15/06, James Edward Gray II <james / grayproductions.net> wrote: > On Nov 13, 2006, at 5:56 PM, Jamie Macey wrote: > > > Rule of the day was the simplest thing that could possibly work. As > > such, I didn't feel the need to split the logic out into a separate > > Program class, but I kept two arrays of prospective programs - one for > > recurring and one for one-shot. > > When I was new from to Ruby, from Perl, I use to think those ad hoc > data structures were "the simplest thing" too. With a fair amount of > Ruby experience now, I'm not so sure though. > > For example, have a look at Dale Martenson's solution, which is very > close to your own in size. Dale used a Program class. > > In fact, Program could be as simple as: > > Program = Struct.new(:start_time, :end_time, :channel, :days) I think that there's a trade-off here. If you have a stupid (no internal logic) Program class, you can trade a very simple add method for a more complicated record? method. My position on it is that if I'm going to be leaving the brunt of the logic in the ProgramManager, I don't think there's a huge difference between nested arrays, a struct, or a class being the holder of the data. That being said, on a lark I did a bit of refactoring and tried to move as much logic out of the ProgramManager into an actual Program class - the results are below. I definitely prefer the second version. It's got 10 more lines of actual code, but there's less random logic strewn about (and the logic is simpler). There's a definite separation of responsibilities - Program just does querying, ProgramManager handles priorities. > I'm not saying anything about your solution here. Just thinking out > loud in hopes of inspiring discussion... ;) Discussion is always good - and this time it caused a better solution to the problem to spring into being :) - Jamie class Program DAYS = %w(sun mon tue wed thu fri sat) attr_reader :channel def initialize(settings) @range = settings[:start]..settings[:end] @channel = settings[:channel] @days = settings[:days] end def recurring? !@days.nil? end def include?(time) if recurring? return false unless @days.include? DAYS[time.wday] time_s = (time.hour*60 + time.min)*60 + time.sec @range.include? time_s else @range.include? time end end end class ProgramManager def initialize @programs = [] end def add(settings) program = Program.new(settings) if program.recurring? @programs << program # Recurring to end of list else @programs.unshift program # Non-recurring to front end end def record?(time) @programs.each do |program| return program.channel if program.include? time end nil end end