Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep getting errors using Raise trying to answer Rspec's to raise_error in Ruby?

Basically I'm trying to answer a series of Rspec instructions. One of those instructions is this:

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

So I learned about raise_error and how to answer it, it was me to create some sort of error/exception.

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

To be clear there is an end on the bottom but the text editor wasn't processing it. So I'm raising the error, I've tried to raise ArgumentError and all that, but I keep getting this response from the 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)>'

Any other raised errors I try just don't work, and I'm struggling to find the right direction to take this. Maybe I'm looking in the wrong place?

Sorry to ask this question again, but I've tried everything and don't want to have any errors. If you want to check the comments of the other thread here is the URL.

like image 724
Brandon Thaler Avatar asked Aug 03 '26 20:08

Brandon Thaler


1 Answers

The main problem here is that Kernel#raise does not accept a block ({...}) as parameters. It accepts an exception or a string.

The next problem you are facing are missing parentheses. While you can omit parentheses in many case, you cannot do that all the time. The reason are different operator precedences. Operator precedence may confuse developers and lead Ruby to read the code in unexpected ways. For example:

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"

In fact - most known style guides suggest to not omit parentheses in most case and allow to omit as an exception in some.

Furthermore it feels to me like you try to do to much in just one one: There is the ternary, two pop calls, a assignment and a raise. That makes the code hard to read, hard to understand and error prone. In this particular example I would suggest to use a guard clause at the beginning of the method and remove the ternary at all:

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

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

You will notice that I also explicitly tell the kind of exception: ArgumentError seems to describe the issue best. And I would name the variables differently.

Each language that its own style, best practices, naming conventions and idioms. It is worth it to understand and follow these conventions. You might want to have a look into a well known Ruby style guides like:

  • https://github.com/styleguide/ruby
  • https://github.com/bbatsov/ruby-style-guide
like image 107
spickermann Avatar answered Aug 05 '26 11:08

spickermann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!