我正在尝试改进release_bike
方法。我已经进入了 irb,第一个保护条件有效,release_working_bikes工作,但第二个保护条件在 irb 中保持返回 nil,即使我运行功能测试并且知道只有一辆坏掉的自行车可用。
条失败线的方式有问题,还是broken_bikes
有缺陷?
release_bike
方法应按如下方式工作;如果扩展坞中没有自行车,那么应该有一个警告说 - No bikes available
如果扩展坞中有自行车,但它们都坏了,那么应该有一个警告说 - No working bikes available
如果有一些工作自行车,那么release_bike
应该释放其中一辆工作自行车。
以下是涉及的两个类;
require_relative 'bike'
class DockingStation
DEFAULT_CAPACITY = 20
attr_reader :capacity, :bikes
def initialize(capacity = DEFAULT_CAPACITY)
@bikes = []
@capacity = capacity
end
def release_bike
fail 'No bikes available' if empty?
fail 'No working bikes available' unless broken_bikes
release_working_bikes
end
def dock(bike)
fail 'Docking Station Full' if full?
@bikes << bike
end
private
def working_bikes
@bikes.each { |bike| return bike unless bike.broken? }
end
def broken_bikes
not_working = []
not_working << @bikes.each { |bike| return bike if bike.broken? }
not_working.empty?
end
def release_working_bikes
bike = working_bikes
@bikes.delete(bike)
end
def full?
@bikes.count >= @capacity
end
def empty?
@bikes.empty?
end
end
class Bike
attr_accessor :broken
def initialize
@broken = false
end
def working?
@working
end
def report_broken
@broken = true
end
def broken?
@broken
end
end
正如评论中已经指出的那样,您正在尝试检查是否所有自行车都坏了,那么为什么不将您的方法命名为 all_bikes_broken?
.请参阅代码中的注释。
require_relative 'bike'
class DockingStation
DEFAULT_CAPACITY = 20
attr_reader :capacity, :bikes
def initialize(capacity = DEFAULT_CAPACITY)
@bikes = []
@capacity = capacity
end
def release_bike
fail 'No bikes available' if empty?
fail 'No working bikes available' unless all_bikes_broken?
release_working_bikes
end
def dock(bike)
fail 'Docking Station Full' if full?
@bikes << bike
end
private
def working_bikes
#this will select only bikes which are NOT broken
@bikes.reject{ |bike| bike.broken? }
end
def all_bikes_broken?
#this is shorthand for @bikes.all?{ |bike| bike.broken? }
#it says send :broken? method to each instance of bike.
#.all? returns true only if all instances return true, otherwise false.
@bikes.all?(&:broken?)
end
def release_working_bikes
bike = working_bikes
@bikes.delete(working_bikes.first)
#or you could do .last but order probably doesn't matter here.
end
def full?
@bikes.count >= @capacity
end
def empty?
@bikes.empty?
end
end
class Bike
attr_accessor :broken
def initialize
@broken = false
end
def working?
@working
end
def report_broken
@broken = true
end
def broken?
@broken
end
end