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

Posted

技术标签:

【中文标题】Ruby - 失败语句/保护条件返回 nil【英文标题】:Ruby - Fail statement/Guard Condition returning nil 【发布时间】:2019-05-22 06:18:06 【问题描述】:

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

【问题讨论】:

您似乎没有检查 所有 自行车是否损坏,请尝试制作一种方法来检查并在防护条件下使用它 @bikes.each |bike| return bike if bike.broken? 如果自行车坏了,这将从方法中返回bike,如果没有一辆自行车坏了,它将把自行车的完整列表推到 not_working 数组中。 我想你要找的是@bikes.all?(&amp;:broken?),它将检查是否所有的自行车都坏了 @engineersmnky 谢谢,这正是我正在寻找的。我是Ruby的新手,是:坏了吗?被称为符号,因为它是一种方法? 【参考方案1】:

正如 cmets 中已经指出的那样,您正在尝试检查是否所有自行车都坏了,所以为什么不将您的方法命名为 all_bikes_broken? 。见代码中的 cmets。

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

【讨论】:

release_working_bikes 将成为一个问题,因为working_bikes 是一个集合。 select ! 通常也是 reject @engineersmnky 很好地抓住了release_working_bikes,修复了这个问题,当然.reject 更好,谢谢。

以上是关于Ruby - 失败语句/保护条件返回 nil的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ruby 中记忆一个可能返回 true、false 或 nil 的方法?

如何在 Ruby 中编写复杂的多行 if 条件?

条件“if”修饰符中的 Ruby 变量赋值

为啥将 [super init] 放在 if 语句中,因为无论返回是不是为 nil,我们还是返回它?

选项的保护语句在 swift 中为零

Shell编程之条件语句