2013-05-09 6 views
0

Я написал метод в классе Float, который принимает поплавок (в секундах) и преобразует его в таймер обратного отсчета. Код работает отлично, когда я пишу его вот так:Почему этот реорганизованный метод ruby ​​возвращает nil?

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 

Когда я пытаюсь refactorized версию, я получаю:

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

, что означает, что countdown является nil. Что я сделал неправильно в обновленной версии?

+0

Вы также можете реорганизовать эти строки следующим образом: 'cd_sec = s == 1? "# {s.to_i} second": (s.to_i == 0? "": "# {s.to_i} seconds") ' –

+0

Не указывайте код и попробуйте читателя угадать. Скорее дайте то, что вводят и ожидаемые результаты. – sawa

+0

Извините, отредактируйте мой код, чтобы показать оба! –

ответ

1

Заменить этот

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

с этим

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

Кроме того, вы используете версию взрыва. Он мутирует массив на месте и can return nil. Если вы хотите продолжать использовать reject, используйте обычную версию (non-bang).

+0

Спасибо вам большое! Это решило мою проблему. Был ли такой очевидный ответ, что я спустился - проголосовал за него? –

+1

@SeanLarkin: Наверное, кто-то так думал. Вы возвращаете результат «reject!», Поэтому большинство людей думали о том, чтобы посмотреть документы для 'reject!', В котором говорится, что он возвращает 'nil', если массив не был изменен. Но не позволяй ему сбить тебя. Когда вы новичок, вы новичок. – Chuck

+1

Справедливо! Я ценю понимание. Я просто верю, что если вы собираетесь проголосовать, объясните, почему люди, которые делают ошибки, могут исправить и извлечь уроки из них, и поэтому не могли не спросить. –

Смежные вопросы