酒店预订系统Ruby的重叠方法

时间:2017-09-29 22:24:57

标签: ruby

我正在为酒店预订系统重构代码,特别是列出酒店所有职位空缺的方法。我们的导师提供了他的解决方案,不幸的是他和我们学校的其余部分一直休息到星期一(当我们的重构任务到期时)。 StackOverflow,我可以利用你的帮助。

基本上,我的问题归结为为什么bang(!)在以下代码中使用。

def overlap?(other)
  return !(other.checkout <= @checkin || other.checkin >= @checkout)
end

此代码是Module Hotel和DateRange类中的方法。在另一个班级调用它来检查给定日期范围的空缺,见下文。

overlap_reservations = @reservations.select do |res|
    res.overlaps(dates)
end

在我看来,我没有利用爆炸。但我是新手,对这里的相互作用视而不见。您可以提供的任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

这段代码遇到了几个严重的代码异味/故障,这些代码气味/毛刺应该永远不会出现在好的ruby代码中。

def overlap?(other)
  return !(other.checkout <= @checkin || other.checkin >= @checkout)
end
  1. 永远不要在ruby方法的最后一行使用显式return。 Ruby将返回值,最后一行被自动计算。
  2. 应尽量简化条件,因为人类的大脑很容易受到双重/三重条件的影响而无法接受。
  3. 不应将!否定与分离混合,因为它会扩展为连词。
  4. 如果我们谈论常用的“签到”和“结帐”,我怀疑上面的代码是否正确。
  5. 总结:

    def overlap?(other)
      # boolean for whether other checkout overlaps
      co = other.checkout >= @checkin && other.checkout <= @checkout
      # boolean for whether other checkin overlaps
      ci = other.checkin >= @checkin && other.checkin <= @checkout
      # return a result
      ci || co
    end
    

    或者,使用红宝石的全部力量:

    def overlap?(other)
      ci_co_range = @checkin..@checkout
      ci_co_range.cover?(other.checkout) || ci_co_range.cover?(other.checkin)
    end
    

    或(从即将到来的圣诞节课程开始:)

    def overlap?(other)
      [other.checkout, other.checkin].any? do |co_ci|
        (@checkin..@checkout).cover?(co_ci)
      end
    end
    

    文档:RangeEnumerable#any?