Ruby-失败语句/保护条件返回nil

时间:2018-12-21 20:30:34

标签: arrays ruby conditional raiserror raiseerror

我正在尝试改进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

1 个答案:

答案 0 :(得分:1)

正如评论中已经指出的那样,您正在尝试检查所有自行车是否坏了,所以为什么不命名您的方法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