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?(&: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 的方法?