Filip Bartuzi
Filip Bartuzi

Reputation: 5931

How does begin,rescue and => symbol work?

In the Ruby koans, 6th exercise, there is:

def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil  
  # What happens when you call a method that doesn't exist.    
  # The following begin/rescue/end code block captures the exception and  
  # make some assertions about it.  

  begin
    nil.some_method_nil_doesnt_know_about
  rescue Exception => ex
    # What exception has been caught?
    assert_equal __, ex.class

    # What message was attached to the exception?
    # (HINT: replace __ with part of the error message.)
    assert_match(/__/, ex.message)
  end
end

I have no idea what => symbol does there? begin and rescue is not clear to me.

Upvotes: 1

Views: 1077

Answers (3)

PericlesTheo
PericlesTheo

Reputation: 2469

ovhaag covered pretty much the question but let me add some more info on the begin side of the question.

When you use the pair begin/end keyword what you are essentially doing is creating an explicit wrapper around the error you may want to handle. Here's an example:

def opening_file
  print "File to open:"
  filename = gets.chomp
  fh = File.open(filename)
  yield fh
  fh.close
  rescue
    puts "Couldn't open your file"
  end

Hypothetically, a number of different errors might appear on this example code eg: the filename is the wrong format, the file for some reason cannot exists. Any error appears in the code, it will immediately fall back on your rescue clause which in this case is the output message.

The issue with this approach is that the output message is very generic and it can apply to a lot of different errors that may not be that suitable, eg: if the error was that the format of the filename is wrong, "Couldn't open your file" is not very helpful. on the other hand, a message "The format is wrong" is much more suitable.

Now if you want to pinpoint exactly the scenario where the file couldn't be opened, you use the begin/end pair.

def opening_file
  print "File to open:"
  filename = gets.chomp
  begin
    fh = File.open(filename)
  rescue
    puts "Couldn't open your file because it doesn't exists"
    return
  end
  yield fh
  fh.close
end

This way, only if an error at the time you try to open the file will fall back in your rescue clause.

Last note regarding =>, by assigning the exception object to a variable you have the ability to call the backtrace and message method, that can help you to see where the code went wrong.

Upvotes: 1

ovhaag
ovhaag

Reputation: 1278

When something goes wrong you can "raise an Exception"

def do_it
  # ..
  raise Exception.new("something went wrong !") if something_went_wrong
end

This will stop the execution of the program if something_went_wrong is true. And if you don't handle the exception.

To handle the exception you use "rescue Exception"

begin
  do_it
rescue Exception
  puts "Something went wrong, but go on anyway"
end

If you need to work with the exception you can give it a Name with "=>"

begin
  do_it
rescue Exception => ex
  # Now "ex" is the name of the Exception. And "ex.inspect" inspects it.
  puts "Something went wrong, #{ex.inspect}, .."
end

If you like ruby koans, you may also like the rubymonk online tutorial. In "Ruby Primer: Ascent" is a Lesson on exceptions.

Upvotes: 1

poseid
poseid

Reputation: 7156

When you want to stop the code execution, because there is an error, you "raise an Exception".

"Catching an exception" allows to continue code execution, and this is what this koan seems to be about. You want to see what happens after the NilClass exception occured.

You can read about the special form for catching exceptions in the Ruby manuals here.

Upvotes: 1

Related Questions