Ruby if 语句 - 如何避免多个 elsif 语句,包括 not

Ruby if statement - how to avoid multiple elsif statements including not

我正在创建一项功能,以根据我对属性的属性自动生成描述(在 Rails 应用程序中)。

我创建了一系列服务 classes 来处理这个问题 - 这里是

class RoomDescriptionGeneratorInternetTV <  RoomDescriptionGeneratorBase

  def generate
    if internet? && cable_tv?
      internet_and_cable_tv_sentence
    elsif internet? && tv? && !cable_tv?
      internet_and_tv_sentence
    elsif internet? && !tv? && !cable_tv?
      internet_sentence
    end
  end

  private

  def internet?
    room.internet (#refers to an active record column in the room model)
  end

  def cable_tv?
    room.cable_tv
  end

  def tv?
    room.tv
  end

  # The sentences are then held in the locales for translation purposes.
  def internet_sentence
    t("internet")
  end

  def internet_and_tv_sentence
    t("internet_and_tv")
  end

  def internet_and_cable_tv_sentence
    t("internet_and_cable_tv")
  end

如果这些 属性 具有这些属性,则此代码的目的是生成读作 "This property has [internet], and [cable TV], [TV]" 的句子。然而,这句话的使用和 class 的实例化发生在一个单独的服务对象中,使用:

class RoomDescriptionGenerator < RoomDescriptionGeneratorBase
  #Other code...

  def internet_tv
    RoomDescriptionGeneratorInternetTV.new(room,locale).generate
  end

end

use if/elsif 语句与 not(!) 相结合看起来很糟糕。我正在寻找更清晰的方法来重构它,以实现我根据属性生成正确句子的目标。

您可以使用

def generate
  return internet_and_cable_tv_sentence if internet? && cable_tv? 
  return internet_and_tv_sentence if internet? && tv? && !cable_tv? 
  return internet_sentence if internet? && !tv? && !cable_tv? 
end

我认为有些条件是无用的。例如,您在第二个条件下测试 !cable_tv?,但如果 cable_tv?true,那么第一个条件将是 truealreday。最后一个条件类似的情况。

此外,您还要检查每个条件下的 internet?。预先检查一次会更有效率。

我会将该块重写为:

def generate
  return unless internet? 

  case
  when cable_tv? then internet_and_cable_tv_sentence
  when tv?       then internet_and_tv_sentence
  else                internet_sentence
  end
end

请注意,出于可读性原因,我更喜欢 case when 块而不是 if elsif