Оценочный проект Руби Коанс. неопределенный метод `length' для nil:NilClass

Я СОВЕРШЕННО новичок в Ruby и программировании в целом. Я работаю над рубиновыми коанами. Я довел его до 176/274, прежде чем застрял.
Это «Проект подсчета очков». Мне нужно написать метод для подсчета очков при данном броске костей.
Возможно, это не самый элегантный код. вы когда-нибудь видели, но вот что я придумал:

def score(dice)
  tally = 0
  tally += (dice.sort.to_s[/[1]+/].length % 3) * 100
  if dice.sort.to_s[/[1]+/].length >= 3
    tally += 1000
  end
  tally = tally + (dice.sort.to_s[/[5]+/].length % 3) * 50
  if dice.sort.to_s[/[5]+/].length >= 3
    tally += 500
  end
  if dice.sort.to_s[/[2]+/].length >= 3
    tally += 200
  end
  if dice.sort.to_s[/[3]+/].length >= 3
    tally += 300
  end
  if dice.sort.to_s[/[4]+/].length >= 3
    tally += 400
  end
  if dice.sort.to_s[/[6]+/].length >= 3
    tally += 600
  end
  return tally
end

Первый тест: score([]) должен возвращать 0

Когда я запускаю его, я получаю «неопределенный метод `length' для nil: NilClass» (ссылка на строку является первым экземпляром .length). Это говорит мне, что «dice.sort.to_s[/[1]+/]» с « score([])" равен нулю, но когда я запускаю его в irb>>, он равен 0.

Что дает?


person bennett_an    schedule 20.09.2011    source источник
comment
что возвращает dice.sort.to_s?   -  person cam    schedule 21.09.2011


Ответы (2)


В ПОРЯДКЕ. Понятно.

Приношу огромные извинения, я сказал, что запуск "dice.sort.to_s[/[1]+/]" возвращал ноль, а не ноль, должно быть, это было потому, что у него было какое-то сохраненное значение, о котором я не знал. Когда я запустил «[].sort.to_s[/[1]+/]», он правильно вернул ноль. Поэтому я вложил каждое из своих операторов if в проверку, чтобы убедиться, что не было нулевого значения.

def score(dice)
  tally = 0
  if dice.sort.to_s[/[1]+/]
    tally += (dice.sort.to_s[/[1]+/].length % 3) * 100
    if dice.sort.to_s[/[1]+/].length >= 3
      tally += 1000
    end
  end
  if dice.sort.to_s[/[5]+/]
    tally += (dice.sort.to_s[/[5]+/].length % 3) * 50
    if dice.sort.to_s[/[5]+/].length >= 3
      tally += 500
    end
  end
  if dice.sort.to_s[/[2]+/]
    if dice.sort.to_s[/[2]+/].length >= 3
      tally += 200
    end
  end
  if dice.sort.to_s[/[3]+/]
    if dice.sort.to_s[/[3]+/].length >= 3
      tally += 300
    end
  end
  if dice.sort.to_s[/[4]+/]
    if dice.sort.to_s[/[4]+/].length >= 3
      tally += 400
    end
  end
  if dice.sort.to_s[/[6]+/]
    if dice.sort.to_s[/[6]+/].length >= 3
      tally += 600
    end
  end
  return tally
end

Все тесты пройдены.

person bennett_an    schedule 21.09.2011

Какую версию Ruby вы используете? Я использую 1.9.2, и мой IRB выдает ту же ошибку, поскольку регулярное выражение возвращает nil, если совпадений нет. Будучи dice = [] пограничным случаем, вы можете добавить проверку на это в первых строках вашего кода, чтобы затем вернуть 0.

Я сделал RubyKoans сегодня, и хотя мой код не красивее вашего, может быть, он вам немного поможет:

def score(dice)

points = 0
dice.sort!
  nmbrs = Array.new
       dice.each { |n|
               nmbrs[n] = dice.select { |nm| nm == n}
       } 

 n = 0
 nmbrs.each { |vals|
      n = n + 1
      if(vals.nil?)
              next
      end
      if(vals.count >= 3)

              points += (n-1)*100 if (n-1) != 1
              points += 1000 if (n-1) == 1

              if vals.size > 3
                      if (n-1) == 1
                              points += 100 * (vals.size - 3)
                      else
                              if (n-1) == 5
                                      points += 50 * (vals.size - 3)
                            end
                      end

              end
      else
            points += 100 * (vals.count) if (n-1) == 1
            points += 50 * (vals.count) if (n-1) == 5
      end
   }

    points

 end

Извините за дерьмовую функцию, но она работает, так что это может дать вам представление о том, как решить эту конкретную проблему.

Удачи!

person Deleteman    schedule 20.09.2011