0

float (秒) を取り、それをカウントダウン タイマーに変換するクラス Float のメソッドを作成しました。次のように書くと、コードは正常に動作します。

class Float
  def to_countdown
    (self % 60) == 1 ? cd_sec = "#{(self % 60).to_i} second" : ( (self % 60).to_i == 0 ? cd_sec = "" : cd_sec = "#{(self % 60).to_i} seconds" )
    ((self/60) % 60) == 1 ? cd_min = "#{((self/60) % 60).to_i} minute" : ( ((self/60) % 60).to_i == 0 ? cd_min = "" : cd_min = "#{((self/60) % 60).to_i} minutes" )
    (self/3600) == 1 ? cd_hour = "#{(self/3600).to_i} hour" : ( (self/3600).to_i == 0 ? cd_hour = "" : cd_hour = "#{(self/3600).to_i} hours" )
    (self/(60*60*24)) == 1 ? cd_day = "#{(self/(60*60*24)).to_i} day" : ( (self/(60*60*24)).to_i == 0 ? cd_day = "" : cd_day = "#{(self/(60*60*24)).to_i} days" )
    countdown = [cd_day, cd_hour, cd_min, cd_sec].reject! {|c| c == nil}
    return countdown.to_sentence
  end
end

509330.546146.to_countdown => "x days, y hours, z minutes, and a seconds"

私はそれをリファクタリングしたかった。私の最終結果は次のとおりです。

class Float
  def to_countdown
    s,m,h,d = (self % 60),((self/60) % 60),((self/3600)%24),(self/(60*60*24))
    s == 1 ? cd_sec  = "#{s.to_i} second" : ( s.to_i == 0 ? cd_sec  = "" : cd_sec  = "#{s.to_i} seconds" )
    m == 1 ? cd_min  = "#{m.to_i} minute" : ( m.to_i == 0 ? cd_min  = "" : cd_min  = "#{m.to_i} minutes" )
    h == 1 ? cd_hour = "#{h.to_i} hour"   : ( h.to_i == 0 ? cd_hour = "" : cd_hour = "#{h.to_i} hours" )
    d == 1 ? cd_day  = "#{d.to_i} day"    : ( d.to_i == 0 ? cd_day  = "" : cd_day  = "#{d.to_i} days" )
    countdown = [cd_day, cd_hour, cd_min, cd_sec].reject! {|c| c == nil}
    return countdown.to_sentence
  end
end

リファクタリングされたバージョンを試すと、次のようになります。

509330.546146.to_countdown => **undefined method `to_sentence' for nil:NilClass>.** 

ということcountdownですnil。リファクタリングされたバージョンで何が間違っていましたか?

4

1 に答える 1

1

これを交換

countdown = [cd_day, cd_hour, cd_min, cd_sec].reject! {|c| c == nil}

これとともに

countdown = [cd_day, cd_hour, cd_min, cd_sec].compact

また、bang バージョンを使用しています。配列をその場で変更し、nil を返すことができます。継続して使いたい場合rejectは通常版(ノンバング)をご利用ください。

于 2013-05-09T16:03:35.087 に答える