Ruby - Colorado School of Mines

Download Report

Transcript Ruby - Colorado School of Mines

and other languages…
•
•
must remember to check return value
OR, must pass label/exception handler to every function
Caller
return status
Caller
label to
subprogram
Function
Function
Fortran strategy
 Error
detection code is tedious to write
and it clutters the program
 Exception propagation allows a high
level of reuse of exception handling code
 Encourage programmers to consider all
events that could occur that might need
to be handled – especially checked
exceptions.
An exception is an unusual event
detectable by either hardware or
software
 An exception is raised/thrown when its
associated event occurs
 The exception handler code determines
what to do

 How
to bind an exception to a handler
 What information to make available
about exception
 Is it possible to continue after an
exception?
 Does the language have any built-in
exceptions?
 Are there user-defined exception types
 Is there a default exception handler?
 Can exceptions be disabled?
What decisions were made for Java?



Added to C++ in 1990
Exceptions are user- or library-defined (none in language
definition)
Exception Handlers Form (like Java):
try {
-- code that is expected to raise an exception
}
catch (formal parameter) { // only 1 parm
-- handler code
}
...
catch (formal parameter) {
-- handler code
}
•



catch is the name of all handlers--it is an overloaded
name, so the formal parameter of each must be unique
The formal parameter need not have a variable
◦ It can be simply a type name to distinguish the
handler it is in from others, e.g. catch(int) rather than
catch (int x)
The formal parameter variable can be used to transfer
information to the handler
The formal parameter can be an ellipsis (…), in which
case it handles all exceptions not yet handled
Compare to Java:
• Possible to throw/catch an int?
• Does formal parameter need a variable? (yes)
• How does the handler get information?
• What mechanism is used in place of …? How does this work?
 Exceptions
all raised explicitly by:
throw expression;
 expression may be a literal or variable
of any type
 A throw without an operand can only
appear in a handler; when it appears, it
simply re-raises the exception, which is
then handled elsewhere
Syntax to throw exception in Java?
main
main calls function a
a calls function b
exception occurs in b
call
If no try/catch in b, exception propagates to a
a
If no try/catch in a, exception propagates to main
If no try/catch in main, execution terminates
(in C++, can override default handler, named
unexpected)
call
b
Problem!
Continuation. If exception is handled, execution
continues after last catch (unless handler calls
exit of course).
Both Java and C++ propagate exceptions






http://googlestyleguide.googlecode.com/svn/trunk/cppguide.html#Exceptions
http://www.parashift.com/c++-faq/exceptions-avoid-spreading-outerror-logic.html
http://stackoverflow.com/questions/19073441/google-c-codingstyle-no-exceptions-rule-what-about-multithreading
http://stackoverflow.com/questions/1744070/why-shouldexceptions-be-used-conservatively
http://www.joelonsoftware.com/items/2003/10/13.html
https://files.ifi.uzh.ch/rerg/arvo/courses/kvse/uebungen/Dijkstra_
Goto.pdf
Put some thoughts on paper, be ready to share

The Java library includes two subclasses of Throwable:
– Error
 Thrown by the Java interpreter for events such as heap overflow
 Never handled by user programs
– Exception
 User-defined exceptions are usually subclasses of this
 Has two predefined subclasses, IOException and
RuntimeException (e.g., ArrayIndexOutOfBoundsException and
NullPointerException)



Exceptions of class Error and RunTimeException and all
of their descendants are called unchecked exceptions
All other exceptions are called checked exceptions (compiler
checks that your code handles – all exceptions occur at
runtime)
Methods containing code that can throw a checked
exception must either:
◦ List the exception(s) in a throws clause, or
◦ Handle the exception (e.g., with try/catch)
◦
Example throws clause (not the same as throwing an
exception!):
public void myFunction() throws Exception


A method cannot declare more
exceptions in its throws clause
than the method it overrides.
Example: If you override run in a
Thread class, you cannot add a
throws clause.
A method that calls a method with a
checked exception in its throws
clause has three alternatives:
1. Catch and handle the
exception
2. Catch the exception and throw
an exception that is listed in its
own throws clause
3. Declare that exception in its
throws clause and do not
handle it
public void A() throws BadException
{ … }
public void B() {
…
try {
A()
} catch (BadException e) {
… }
}
public void C() throws AnException{
…
try {
A()
} catch (BadException e) {
throw (AnException) }
}
public void D() throws BadException
{ … A() … }


Can appear at the end of a try construct
Form:
finally {
...
}


Purpose: To specify code that is to be
executed, regardless of what happens in the
try construct (e.g., to close file or database
connection).
Finally is executed even if there is a return
statement in the block.
try {
for (index = 0; index < 100; index++) {
…
if (…) {
return;
} //** end of if
} //** end of try clause
finally {
…
} //** end of try construct
* Java exercise has examples to play with
 Exceptions
are raised using the raise
method of Kernel
 The rescue clause is used to handle
exceptions
 Exceptions are instances of the Exception
class (or a subclass)
 Subclasses do not add methods or behavior,
but allow exceptions to be categorized
 Most exceptions extend StandardError
 Other exceptions are low-level, typically not
handled by programs
* Exception info directly from The Ruby Programming Language
method returns a string – more
suitable for programmers than end users
 backtrace returns the call stack
 message
• array of strings
• filename : linenumber in methodname
is synonym (use if expect program
to end)
 Several ways to invoke raise:
 fail
• with no arguments. If inside rescue, re-raises
same exception, otherwise raises RuntimeError
• with single Exception object. Not common.
• with single String argument. Creates
RuntimeError with that string as message. Very
common.
• with exception object, string (for message) and
array of strings (for backtrace).
def factorial(n)
raise "bad argument" if n < 1
# raise ArgumentError if n < 1
# raise ArgumentError, "Expected argument >= 1, got #{n}" if n < 1
return 1 if n == 1
n * factorial(n-1)
end
Can provide a custom stack trace
def factorial4(n)
if n < 1
raise ArgumentError, "Expected argument >= 1, got #{n}", caller
end
return 1 if n == 1
n * factorial(n-1)
end

 rescue
is part of Ruby language (not a
Kernel method)
 clause that can be attached to other Ruby
statements
 typically attached to begin
begin
# statements, possible exceptions
rescue
# code to deal with exceptions
end
# if no exception, code continues here, code in rescue
is not executed
 rescue
handles any StandardError
 global variable $! refers to raised
exception
 better to specify variable in rescue
begin
x = factorial(0)
rescue => ex
puts "#{ex.class}: #{ex.message}"
end
def factorial5(n)
raise TypeError, “Need integer" if not n.is_a? Integer
raise ArgumentError, “Need argument >= 1, got #{n}" if n < 1
return 1 if n == 1
n * factorial(n-1)
end
begin
x = factorial5("a")
rescue ArgumentError => ex
puts "Try again with argument > 1"
rescue TypeError => ex
puts "Try again with an integer"
end
Does the order matter?
def explode
raise "bam!" if rand(10) == 0
end
def risky
begin
10.times do
explode
end
rescue TypeError
puts $!
end
"hello"
end
#raises error ~10% of time
# won't catch RuntimeError
# RuntimeError not handled, will propagate
# if no exception
def defuse
begin
puts risky
rescue RuntimeError => e # handle propagated error
puts e.message
end
end
defuse
QUICK EX: Trace code
 retry
– with rescue, reruns block of code that
rescue is attached to. Useful for transient
failures such as overloaded server. Be sure
to limit number of retries.
 ensure – code that always runs, for
housekeeping like disconnecting from
database, closing files, etc.
 not covered: subtle details for ensure
 rescue can be used as a statement modifier
(y = factorial(x) rescue 0 #returns 0 if error)
 similar
to a labeled break, but can break
out of multiple levels
 not used for exception handling
 used infrequently, details not covered
 C++
 Topic
 Java
Exploration