Продолжаете получать сообщения об ошибках, используя Raise, пытаясь ответить на Rspec на lift_error в Ruby?

В основном я пытаюсь ответить на ряд инструкций Rspec. Одна из этих инструкций такова:

it "fails informatively when there's not enough values stacked away" do
  expect {
     calculator.plus
  }.to raise_error("calculator is empty")
end

Таким образом, я узнал о Raise_error и о том, как на него ответить, я сам создал какую-то ошибку / исключение.

def plus
  @array_nums.length >= 2 ? @array_nums << @array_nums.pop + @array_nums.pop : raise {"calculator is empty"}
  @value = @array_nums[-1]

Чтобы было ясно, в конце есть конец, но текстовый редактор его не обрабатывал. Итак, я поднимаю ошибку, я пытался вызвать ArgumentError и все такое, но я продолжаю получать этот ответ от rspec:

Failure/Error:
   expect {
     calculator.plus
   }.to raise_error("calculator is empty")

   expected Exception with "calculator is empty", got RuntimeError with backtrace:
     # ./lib/12_rpn_calculator.rb:16:in `plus'
     # ./spec/12_rpn_calculator_spec.rb:119:in `block (3 levels) in <top (required)>'
     # ./spec/12_rpn_calculator_spec.rb:118:in `block (2 levels) in <top (required)>'
 # ./spec/12_rpn_calculator_spec.rb:118:in `block (2 levels) in <top (required)>'

Любые другие ошибки, которые я пробую, просто не работают, и я изо всех сил пытаюсь найти правильное направление для этого. Может я смотрю не в том месте?

Извините, что задаю этот вопрос еще раз, но я перепробовал все и не хочу иметь никаких ошибок. Если вы хотите проверить комментарии другой ветки, вот URL.

2 ответа

Основная проблема здесь в том, что Kernel#raise не принимает блок ({...}) в качестве параметров. Он принимает исключение или строку.

Следующая проблема, с которой вы столкнулись, - это отсутствие скобок. Хотя во многих случаях вы можете опустить скобки, вы не можете делать это постоянно. Причиной являются разные операторские приоритеты. Приоритет оператора может сбить разработчиков с толку и заставить Ruby читать код неожиданным образом. Например:

condition ? operation : raise "calculator is empty"

# what the devs thinks Ruby would understand:
condition ? operation : raise("calculator is empty")

# what Ruby really understands:
(condition ? operation : raise) "calculator is empty"

На самом деле - большинство известных руководств по стилю предлагают в большинстве случаев не пропускать скобки, а в некоторых позволяют исключать их.

Кроме того, мне кажется, что вы пытаетесь сделать многое только в одном: есть троица, два pop звонки, назначение и raise, Это делает код трудным для чтения, сложным для понимания и подверженным ошибкам. В этом конкретном примере я бы предложил использовать выражение guard в начале метода и вообще удалить троичный:

def plus
  raise(ArgumentError, 'calculator is empty') if @numbers.length < 3

  @numbers << @numbers.pop + @numbers.pop
  # ...

Вы заметите, что я также явно говорю вид исключения: ArgumentError кажется, лучше всего описывает проблему. И я бы назвал переменные по-другому.

У каждого языка свой стиль, лучшие практики, соглашения об именах и идиомы. Это стоит того, чтобы понять и следовать этим соглашениям. Возможно, вы захотите взглянуть на хорошо известные руководства по стилю Ruby, такие как:

Менять raise {"calculator is empty"} в raise("calculator is empty"), raise может принимать строковый аргумент, а не блок.

Другие вопросы по тегам