Jamie Macey
11/15/2006 6:35:00 PM
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