如何缩短链式if / elsif语句?

时间:2011-07-04 17:33:38

标签: ruby

我想缩短以下方法。有没有聪明的方法可以通过使用迭代器,case语句等在Ruby中执行此操作?

# Returns true iff this is a later date than the input date.
def later_than?(date)
    if(@year < date.year)
        return false
    elsif(@year > date.year)
        return true
    end
    if(@month < date.month)
        return false
    elsif(@month > date.month)
        return true
    end
    if(@day <= date.day)
        return false
    elsif(@day > date.day)
        return true
    end
end

我可以补充一点,该方法属于一个名为Date的类,还有三个类成员:年,月和日。

我知道通过排除返回false的特定if语句可以在一定程度上缩短代码,但我想知道是否有更好的方法?建议非常感谢。

6 个答案:

答案 0 :(得分:6)

如果你把它添加到你的班级:

include Comparable
def <=>(other)
  [@year, @month, @day] <=> [other.year, other.month, other.day]
end

您的自定义日期类突然获得了这些比较方法:&lt ;,&lt; =,==,&gt;,&gt; = 之间? 但正如其他人所说,只需使用ruby的日期类。

答案 1 :(得分:4)

真的,你应该使用Date。您也无需比较yearmonthday等属性,因为Date实现了Comparable。这是使用您创建的任何自定义类的样子:

require 'date'

...

  def later_than?(date)
    Date.new(@year, @month, @day) > Date.new(date.year, date.month, date.day)
  end

但请注意那里的冗余。我们只是构建对象并进行比较。您可能只想构造那些Date对象或者有一些方法将返回Date对象(如果您在日期上再执行任何操作,则需要这些对象),然后使用简单的{{1}运算符而不是创建>方法。如果你想在irb中查看:

later_than?

另外,如果您真的希望require 'date' the_fourth = Date.new(2011, 7, 4) christmas = Date.new(2011, 12, 25) the_fourth > christmas # returns false christmas > the_fourth # returns true 具有语义价值,那么您可以执行类似

的操作
later_than?

答案 2 :(得分:2)

我认为这应该得到更大的重构,因为当你只有一个时间对象并执行以下操作时,存储三个不同的类变量毫无意义:

def later_than?(date)
    @time >= date
end

如果没有一个全局时间变量,您可以这样做:

def later_than?(date)
    Time.new(@year, @month, @day) >= date
end

答案 3 :(得分:1)

这也可以:

def later_than?(date)
   @year*10000+@month*100+@day > date.year*10000+date.month*100+date.day
end

我更喜欢的是这个版本:

def to_s
  (@year*10000+@month*100+@day).to_s
end

def later_than?(date)
  to_s > date.to_s
end

答案 4 :(得分:1)

我同意使用Ruby的Date对象的其他建议。它非常适合您想要的东西,并且可以为您节省大量代码,重新发明特定的轮子。

作为使用if/elsif逻辑的建议:

if(@year < date.year)
    return false
elsif(@year > date.year)
    return true
end
if(@month < date.month)
    return false
elsif(@month > date.month)
    return true
end
if(@day <= date.day)
    return false
elsif(@day > date.day)
    return true
end

不必要地复杂化。考虑一下:

return false if ( @year  < date.year  )
return true  if ( @year  > date.year  )

return false if ( @month < date.month )
return true  if ( @month > date.month )

return true  if ( @day   > date.day   )
return false 

我不是说这适用于所有情况,或者这是你在这种特殊情况下应该使用的。相反,我想要展示的是格式化如何使重复,类似的文本行更容易看到变化。

在编写代码时,请查看如何编写代码并使其清晰简洁。写下来好像是通过电话向某人发出指示;您的代码是否像在普通语音中说的那样流动?

编写代码并记住维护,因为如果您以后需要再回到它,您会希望它易于理解。

答案 5 :(得分:1)

我建议使用其他方法,但不是使用if和elsif,而是可以使用case

# Returns true iff this is a later date than the input date.
def later_than?(date)
  case
    when @year < date.year then false
    when @year > date.year then true
    when @month < date.month then false
    when @month > date.month then true
    when @day <= date.day then false
    when @day > date.day then true
    else raise "Shouldn't get here"
  end
end