diff options
-rw-r--r-- | doc/exceptions.md | 184 | ||||
-rw-r--r-- | error.c | 390 | ||||
-rw-r--r-- | eval.c | 111 |
3 files changed, 490 insertions, 195 deletions
diff --git a/doc/exceptions.md b/doc/exceptions.md index 4db2f26c18..47176141ad 100644 --- a/doc/exceptions.md +++ b/doc/exceptions.md @@ -84,15 +84,15 @@ A rescue clause: - Ends with the first following `rescue`, `else`, `ensure`, or `end` statement. +##### Rescued Exceptions + A `rescue` statement may include one or more classes that are to be rescued; if none is given, StandardError is assumed. The rescue clause rescues both the specified class (or StandardError if none given) or any of its subclasses; -(see [Built-In Exception Classes](rdoc-ref:Exception@Built-In+Exception+Classes) -for the hierarchy of Ruby built-in exception classes): - +see [Built-In Exception Class Hierarchy](rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy). ``` begin @@ -133,6 +133,8 @@ rescue FloatDomainError, ZeroDivisionError end ``` +##### Multiple Rescue Clauses + An exception handler may contain multiple rescue clauses; in that case, the first clause that rescues the exception does so, and those before and after are ignored: @@ -153,6 +155,8 @@ Output: Rescued Errno::ENOENT ``` +##### Capturing the Rescued \Exception + A `rescue` statement may specify a variable whose value becomes the rescued exception (an instance of Exception or one of its subclasses: @@ -173,10 +177,66 @@ ZeroDivisionError divided by 0 ``` -In the rescue clause, these global variables are defined: +##### Global Variables + +Two read-only global variables always have `nil` value +except in a rescue clause; +there: + +- `$!`: contains the rescued exception. +- `$@`: contains its backtrace. + +Example: + +``` +begin + 1 / 0 +rescue + p $! + p $@ +end +``` + +Output: + +``` +#<ZeroDivisionError: divided by 0> +["t.rb:2:in `/'", "t.rb:2:in `<main>'"] +``` + +##### Cause + +In a rescue clause, the method Exception#cause returns the previous value of `$!`, +which may be `nil`; +elsewhere, the method returns `nil`. + +Example: + +``` +begin + raise('Boom 0') +rescue => x0 + puts "Exception: #{x0.inspect}; $!: #{$!.inspect}; cause: #{x0.cause.inspect}." + begin + raise('Boom 1') + rescue => x1 + puts "Exception: #{x1.inspect}; $!: #{$!.inspect}; cause: #{x1.cause.inspect}." + begin + raise('Boom 2') + rescue => x2 + puts "Exception: #{x2.inspect}; $!: #{$!.inspect}; cause: #{x2.cause.inspect}." + end + end +end +``` + +Output: -- `$!`": the current exception instance. -- `$@`: its backtrace. +``` +Exception: #<RuntimeError: Boom 0>; $!: #<RuntimeError: Boom 0>; cause: nil. +Exception: #<RuntimeError: Boom 1>; $!: #<RuntimeError: Boom 1>; cause: #<RuntimeError: Boom 0>. +Exception: #<RuntimeError: Boom 2>; $!: #<RuntimeError: Boom 2>; cause: #<RuntimeError: Boom 1>. +``` #### Else Clause @@ -349,14 +409,120 @@ not just the part after the point of failure. ## Raising an \Exception -Raise an exception with method Kernel#raise. +\Method Kernel#raise raises an exception. ## Custom Exceptions To provide additional or alternate information, -you may create custom exception classes; -each should be a subclass of one of the built-in exception classes: +you may create custom exception classes. +Each should be a subclass of one of the built-in exception classes +(commonly StandardError or RuntimeError); +see [Built-In Exception Class Hierarchy](rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy). ``` class MyException < StandardError; end ``` + +## Messages + +Every `Exception` object has a message, +which is a string that is set at the time the object is created; +see Exception.new. + +The message cannot be changed, but you can create a similar object with a different message; +see Exception#exception. + +This method returns the message as defined: + +- Exception#message. + +Two other methods return enhanced versions of the message: + +- Exception#detailed_message: adds exception class name, with optional highlighting. +- Exception#full_message: adds exception class name and backtrace, with optional highlighting. + +Each of the two methods above accepts keyword argument `highlight`; +if the value of keyword `highlight` is `true`, +the returned string includes bolding and underlining ANSI codes (see below) +to enhance the appearance of the message. + +Any exception class (Ruby or custom) may choose to override either of these methods, +and may choose to interpret keyword argument <tt>highlight: true</tt> +to mean that the returned message should contain +[ANSI codes](https://en.wikipedia.org/wiki/ANSI_escape_code) +that specify color, bolding, and underlining. + +Because the enhanced message may be written to a non-terminal device +(e.g., into an HTML page), +it is best to limit the ANSI codes to these widely-supported codes: + +- Begin font color: + + | Color | ANSI Code | + |---------|------------------| + | Red | <tt>\\e[31m</tt> | + | Green | <tt>\\e[32m</tt> | + | Yellow | <tt>\\e[33m</tt> | + | Blue | <tt>\\e[34m</tt> | + | Magenta | <tt>\\e[35m</tt> | + | Cyan | <tt>\\e[36m</tt> | + +<br> + +- Begin font attribute: + + | Attribute | ANSI Code | + |-----------|-----------------| + | Bold | <tt>\\e[1m</tt> | + | Underline | <tt>\\e[4m</tt> | + +<br> + +- End all of the above: + + | Color | ANSI Code | + |-------|-----------------| + | Reset | <tt>\\e[0m</tt> | + +It's also best to craft a message that is conveniently human-readable, +even if the ANSI codes are included "as-is" +(rather than interpreted as font directives). + +## Backtraces + +A _backtrace_ is a record of the methods currently +in the [call stack](https://en.wikipedia.org/wiki/Call_stack); +each such method has been called, but has not yet returned. + +These methods return backtrace information: + +- Exception#backtrace: returns the backtrace as an array of strings or `nil`. +- Exception#backtrace_locations: returns the backtrace as an array + of Thread::Backtrace::Location objects or `nil`. + Each Thread::Backtrace::Location object gives detailed information about a called method. + +An `Exception` object stores its backtrace value as one of: + +- An array of Thread::Backtrace::Location objects; + this is the common case: the exception was raised by the Ruby core or the Ruby standard library. + In this case: + + - Exception#backtrace_locations returns the array of Thread::Backtrace::Location objects. + - Exception#backtrace returns the array of their string values + (`Exception#backtrace_locations.map {|loc| loc.to_s }`). + +- An array of strings; + this is an uncommon case: the user manually set the backtrace to an array of strings; + In this case: + + - Exception#backtrace returns the array of strings. + - Exception#backtrace_locations returns `nil`. + +- `nil`, in which case both methods return `nil`. + +These methods set the backtrace value: + +- Exception#set_backtrace: sets the backtrace value to an array of strings, or to `nil`. +- Kernel#raise: sets the backtrace value to an array of Thread::Backtrace::Location objects, + or to an array of strings. + @@ -1469,12 +1469,23 @@ exc_init(VALUE exc, VALUE mesg) } /* - * call-seq: - * Exception.new(msg = nil) -> exception - * Exception.exception(msg = nil) -> exception + * call-seq: + * Exception.new(message = nil) -> exception + * + * Returns a new exception object. + * + * The given +message+ should be + * a {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects]; + * see method #message; + * if not given, the message is the class name of the new instance + * (which may be the name of a subclass): + * + * Examples: + * + * Exception.new # => #<Exception: Exception> + * LoadError.new # => #<LoadError: LoadError> # Subclass of Exception. + * Exception.new('Boom') # => #<Exception: Boom> * - * Construct a new Exception object, optionally passing in - * a message. */ static VALUE @@ -1490,12 +1501,24 @@ exc_initialize(int argc, VALUE *argv, VALUE exc) * Document-method: exception * * call-seq: - * exc.exception([string]) -> an_exception or exc + * exception(message = nil) -> self or new_exception + * + * Returns an exception object of the same class as +self+; + * useful for creating a similar exception, but with a different message. + * + * With +message+ +nil+, returns +self+: + * + * x0 = StandardError.new('Boom') # => #<StandardError: Boom> + * x1 = x0.exception # => #<StandardError: Boom> + * x0.__id__ == x1.__id__ # => true * - * With no argument, or if the argument is the same as the receiver, - * return the receiver. Otherwise, create a new - * exception object of the same class as the receiver, but with a - * message equal to <code>string.to_str</code>. + * With {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects] + * +message+ (even the same as the original message), + * returns a new exception object whose class is the same as +self+, + * and whose message is the given +message+: + * + * x1 = x0.exception('Boom') # => #<StandardError: Boom> + * x0..equal?(x1) # => false * */ @@ -1514,10 +1537,15 @@ exc_exception(int argc, VALUE *argv, VALUE self) /* * call-seq: - * exception.to_s -> string + * to_s -> string + * + * Returns a string representation of +self+: + * + * x = RuntimeError.new('Boom') + * x.to_s # => "Boom" + * x = RuntimeError.new + * x.to_s # => "RuntimeError" * - * Returns exception's message (or the name of the exception if - * no message is set). */ static VALUE @@ -1557,10 +1585,10 @@ rb_get_detailed_message(VALUE exc, VALUE opt) } /* - * call-seq: - * Exception.to_tty? -> true or false + * call-seq: + * Exception.to_tty? -> true or false * - * Returns +true+ if exception messages will be sent to a tty. + * Returns +true+ if exception messages will be sent to a terminal device. */ static VALUE exc_s_to_tty_p(VALUE self) @@ -1620,20 +1648,51 @@ check_order_keyword(VALUE opt) /* * call-seq: - * exception.full_message(highlight: bool, order: [:top or :bottom]) -> string + * full_message(highlight: true, order: :top) -> string + * + * Returns an enhanced message string: + * + * - Includes the exception class name. + * - If the value of keyword +highlight+ is true (not +nil+ or +false+), + * includes bolding ANSI codes (see below) to enhance the appearance of the message. + * - Includes the {backtrace}[rdoc-ref:exceptions.md@Backtraces]: + * + * - If the value of keyword +order+ is +:top+ (the default), + * lists the error message and the innermost backtrace entry first. + * - If the value of keyword +order+ is +:bottom+, + * lists the error message the the innermost entry last. + * + * Example: * - * Returns formatted string of _exception_. - * The returned string is formatted using the same format that Ruby uses - * when printing an uncaught exceptions to stderr. + * def baz + * begin + * 1 / 0 + * rescue => x + * pp x.message + * pp x.full_message(highlight: false).split("\n") + * pp x.full_message.split("\n") + * end + * end + * def bar; baz; end + * def foo; bar; end + * foo * - * If _highlight_ is +true+ the default error handler will send the - * messages to a tty. + * Output: * - * _order_ must be either of +:top+ or +:bottom+, and places the error - * message and the innermost backtrace come at the top or the bottom. + * "divided by 0" + * ["t.rb:3:in `/': divided by 0 (ZeroDivisionError)", + * "\tfrom t.rb:3:in `baz'", + * "\tfrom t.rb:10:in `bar'", + * "\tfrom t.rb:11:in `foo'", + * "\tfrom t.rb:12:in `<main>'"] + * ["t.rb:3:in `/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m", + * "\tfrom t.rb:3:in `baz'", + * "\tfrom t.rb:10:in `bar'", + * "\tfrom t.rb:11:in `foo'", + * "\tfrom t.rb:12:in `<main>'"] * - * The default values of these options depend on <code>$stderr</code> - * and its +tty?+ at the timing of a call. + * An overrriding method should be careful with ANSI code enhancements; + * see {Messages}[rdoc-ref:exceptions.md@Messages]. */ static VALUE @@ -1662,10 +1721,11 @@ exc_full_message(int argc, VALUE *argv, VALUE exc) /* * call-seq: - * exception.message -> string + * message -> string + * + * Returns #to_s. * - * Returns the result of invoking <code>exception.to_s</code>. - * Normally this returns the exception's message or name. + * See {Messages}[rdoc-ref:exceptions.md@Messages]. */ static VALUE @@ -1676,42 +1736,47 @@ exc_message(VALUE exc) /* * call-seq: - * exception.detailed_message(highlight: bool, **opt) -> string + * detailed_message(highlight: false, **kwargs) -> string + * + * Returns the message string with enhancements: + * + * - Includes the exception class name in the first line. + * - If the value of keyword +highlight+ is +true+, + * includes bolding and underlining ANSI codes (see below) + * to enhance the appearance of the message. * - * Processes a string returned by #message. + * Examples: * - * It may add the class name of the exception to the end of the first line. - * Also, when +highlight+ keyword is true, it adds ANSI escape sequences to - * make the message bold. + * begin + * 1 / 0 + * rescue => x + * p x.message + * p x.detailed_message # Class name added. + * p x.detailed_message(highlight: true) # Class name, bolding, and underlining added. + * end * - * If you override this method, it must be tolerant for unknown keyword - * arguments. All keyword arguments passed to #full_message are delegated - * to this method. + * Output: * - * This method is overridden by did_you_mean and error_highlight to add - * their information. + * "divided by 0" + * "divided by 0 (ZeroDivisionError)" + * "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m" * - * A user-defined exception class can also define their own - * +detailed_message+ method to add supplemental information. - * When +highlight+ is true, it can return a string containing escape - * sequences, but use widely-supported ones. It is recommended to limit - * the following codes: + * This method is overridden by some gems in the Ruby standard library to add information: * - * - Reset (+\e[0m+) - * - Bold (+\e[1m+) - * - Underline (+\e[4m+) - * - Foreground color except white and black - * - Red (+\e[31m+) - * - Green (+\e[32m+) - * - Yellow (+\e[33m+) - * - Blue (+\e[34m+) - * - Magenta (+\e[35m+) - * - Cyan (+\e[36m+) + * - DidYouMean::Correctable#detailed_message. + * - ErrorHighlight::CoreExt#detailed_message. + * - SyntaxSuggest#detailed_message. * - * Use escape sequences carefully even if +highlight+ is true. - * Do not use escape sequences to express essential information; - * the message should be readable even if all escape sequences are - * ignored. + * An overriding method must be tolerant of passed keyword arguments, + * which may include (but may not be limited to): + * + * - +:highlight+. + * - +:did_you_mean+. + * - +:error_highlight+. + * - +:syntax_suggest+. + * + * An overrriding method should also be careful with ANSI code enhancements; + * see {Messages}[rdoc-ref:exceptions.md@Messages]. */ static VALUE @@ -1730,9 +1795,15 @@ exc_detailed_message(int argc, VALUE *argv, VALUE exc) /* * call-seq: - * exception.inspect -> string + * inspect -> string + * + * Returns a string representation of +self+: + * + * x = RuntimeError.new('Boom') + * x.inspect # => "#<RuntimeError: Boom>" + * x = RuntimeError.new + * x.inspect # => "#<RuntimeError: RuntimeError>" * - * Return this exception's class name and message. */ static VALUE @@ -1765,38 +1836,31 @@ exc_inspect(VALUE exc) /* * call-seq: - * exception.backtrace -> array or nil + * backtrace -> array or nil * - * Returns any backtrace associated with the exception. The backtrace - * is an array of strings, each containing either ``filename:lineNo: in - * `method''' or ``filename:lineNo.'' + * Returns a backtrace value for +self+; + * the returned value depends on the form of the stored backtrace value: * - * def a - * raise "boom" - * end - * - * def b - * a() - * end + * - \Array of Thread::Backtrace::Location objects: + * returns the array of strings given by + * <tt>Exception#backtrace_locations.map {|loc| loc.to_s }</tt>. + * This is the normal case, where the backtrace value was stored by Kernel#raise. + * - \Array of strings: returns that array. + * This is the unusual case, where the backtrace value was explicitly + * stored as an array of strings. + * - +nil+: returns +nil+. * - * begin - * b() - * rescue => detail - * print detail.backtrace.join("\n") - * end - * - * <em>produces:</em> - * - * prog.rb:2:in `a' - * prog.rb:6:in `b' - * prog.rb:10 + * Example: * - * In the case no backtrace has been set, +nil+ is returned + * begin + * 1 / 0 + * rescue => x + * x.backtrace.take(2) + * end + * # => ["(irb):132:in `/'", "(irb):132:in `<top (required)>'"] * - * ex = StandardError.new - * ex.backtrace - * #=> nil -*/ + * see {Backtraces}[rdoc-ref:exceptions.md@Backtraces]. + */ static VALUE exc_backtrace(VALUE exc) @@ -1838,13 +1902,24 @@ rb_get_backtrace(VALUE exc) /* * call-seq: - * exception.backtrace_locations -> array or nil + * backtrace_locations -> array or nil + * + * Returns a backtrace value for +self+; + * the returned value depends on the form of the stored backtrace value: * - * Returns any backtrace associated with the exception. This method is - * similar to Exception#backtrace, but the backtrace is an array of - * Thread::Backtrace::Location. + * - \Array of Thread::Backtrace::Location objects: returns that array. + * - \Array of strings or +nil+: returns +nil+. + * + * Example: * - * This method is not affected by Exception#set_backtrace(). + * begin + * 1 / 0 + * rescue => x + * x.backtrace_locations.take(2) + * end + * # => ["(irb):150:in `/'", "(irb):150:in `<top (required)>'"] + * + * See {Backtraces}[rdoc-ref:exceptions.md@Backtraces]. */ static VALUE exc_backtrace_locations(VALUE exc) @@ -1882,12 +1957,19 @@ rb_check_backtrace(VALUE bt) /* * call-seq: - * exc.set_backtrace(backtrace) -> array + * set_backtrace(value) -> value + * + * Sets the backtrace value for +self+; returns the given +value: + * + * x = RuntimeError.new('Boom') + * x.set_backtrace(%w[foo bar baz]) # => ["foo", "bar", "baz"] + * x.backtrace # => ["foo", "bar", "baz"] * - * Sets the backtrace information associated with +exc+. The +backtrace+ must - * be an array of Thread::Backtrace::Location objects or an array of String objects - * or a single String in the format described in Exception#backtrace. + * The given +value+ must be an array of strings, a single string, or +nil+. * + * Does not affect the value returned by #backtrace_locations. + * + * See {Backtraces}[rdoc-ref:exceptions.md@Backtraces]. */ static VALUE @@ -1911,12 +1993,35 @@ rb_exc_set_backtrace(VALUE exc, VALUE bt) } /* - * call-seq: - * exception.cause -> an_exception or nil + * call-seq: + * cause -> exception or nil + * + * Returns the previous value of global variable <tt>$!</tt>, + * which may be +nil+ + * (see {Global Variables}[rdoc-ref:exceptions.md@Global+Variables]): + * + * begin + * raise('Boom 0') + * rescue => x0 + * puts "Exception: #{x0}; $!: #{$!}; cause: #{x0.cause.inspect}." + * begin + * raise('Boom 1') + * rescue => x1 + * puts "Exception: #{x1}; $!: #{$!}; cause: #{x1.cause}." + * begin + * raise('Boom 2') + * rescue => x2 + * puts "Exception: #{x2}; $!: #{$!}; cause: #{x2.cause}." + * end + * end + * end + * + * Output: + * + * Exception: Boom 0; $!: Boom 0; cause: nil. + * Exception: Boom 1; $!: Boom 1; cause: Boom 0. + * Exception: Boom 2; $!: Boom 2; cause: Boom 1. * - * Returns the previous exception ($!) at the time this exception was raised. - * This is useful for wrapping exceptions and retaining the original exception - * information. */ static VALUE @@ -1933,11 +2038,11 @@ try_convert_to_exception(VALUE obj) /* * call-seq: - * exc == obj -> true or false + * self == object -> true or false + * + * Returns whether +object+ is the same class as +self+ + * and its #message and #backtrace are equal to those of +self+. * - * Equality---If <i>obj</i> is not an Exception, returns - * <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and - * <i>obj</i> share same class, messages, and backtrace. */ static VALUE @@ -3248,66 +3353,30 @@ syserr_eqq(VALUE self, VALUE exc) /* * Document-class: Exception * - * \Class Exception and its subclasses are used to communicate between - * Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks. + * \Class +Exception+ and its subclasses are used to indicate that an error + * or other problem has occurred, + * and may need to be handled. + * See {Exceptions}[rdoc-ref:exceptions.md]. * - * An Exception object carries information about an exception: - * - Its type (the exception's class). - * - An optional descriptive message. - * - Optional backtrace information. + * An +Exception+ object carries certain information: * - * Some built-in subclasses of Exception have additional methods: e.g., NameError#name. + * - The type (the exception's class), + * commonly StandardError, RuntimeError, or a subclass of one or the other; + * see {Built-In Exception Class Hierarchy}[rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy]. + * - An optional descriptive message; + * see methods ::new, #message. + * - Optional backtrace information; + * see methods #backtrace, #backtrace_locations, #set_backtrace. + * - An optional cause; + * see method #cause. * - * == Defaults + * == Built-In \Exception \Class Hierarchy * - * Two Ruby statements have default exception classes: - * - +raise+: defaults to RuntimeError. - * - +rescue+: defaults to StandardError. - * - * == Global Variables - * - * When an exception has been raised but not yet handled (in +rescue+, - * +ensure+, +at_exit+ and +END+ blocks), two global variables are set: - * - <code>$!</code> contains the current exception. - * - <code>$@</code> contains its backtrace. - * - * == Custom Exceptions - * - * To provide additional or alternate information, - * a program may create custom exception classes - * that derive from the built-in exception classes. - * - * A good practice is for a library to create a single "generic" exception class - * (typically a subclass of StandardError or RuntimeError) - * and have its other exception classes derive from that class. - * This allows the user to rescue the generic exception, thus catching all exceptions - * the library may raise even if future versions of the library add new - * exception subclasses. - * - * For example: - * - * class MyLibrary - * class Error < ::StandardError - * end - * - * class WidgetError < Error - * end - * - * class FrobError < Error - * end - * - * end - * - * To handle both MyLibrary::WidgetError and MyLibrary::FrobError the library - * user can rescue MyLibrary::Error. - * - * == Built-In Exception Classes - * - * The built-in subclasses of Exception are: + * The hierarchy of built-in subclasses of class +Exception+: * * * NoMemoryError * * ScriptError - * * LoadError + * * {LoadError}[https://docs.ruby-lang.org/en/master/LoadError.html] * * NotImplementedError * * SyntaxError * * SecurityError @@ -3333,13 +3402,14 @@ syserr_eqq(VALUE self, VALUE exc) * * RuntimeError * * FrozenError * * SystemCallError - * * Errno::* + * * Errno (and its subclasses, representing system errors) * * ThreadError * * TypeError * * ZeroDivisionError * * SystemExit * * SystemStackError - * * fatal + * * {fatal}[https://docs.ruby-lang.org/en/master/fatal.html] + * */ static VALUE @@ -746,32 +746,91 @@ rb_f_raise(int argc, VALUE *argv) /* * call-seq: - * raise - * raise(string, cause: $!) - * raise(exception [, string [, array]], cause: $!) - * fail - * fail(string, cause: $!) - * fail(exception [, string [, array]], cause: $!) - * - * With no arguments, raises the exception in <code>$!</code> or raises - * a RuntimeError if <code>$!</code> is +nil+. With a single +String+ - * argument, raises a +RuntimeError+ with the string as a message. Otherwise, - * the first parameter should be an +Exception+ class (or another - * object that returns an +Exception+ object when sent an +exception+ - * message). The optional second parameter sets the message associated with - * the exception (accessible via Exception#message), and the third parameter - * is an array of callback information (accessible via - * Exception#backtrace_locations or Exception#backtrace). - * The +cause+ of the generated exception (accessible via Exception#cause) - * is automatically set to the "current" exception (<code>$!</code>), if any. - * An alternative value, either an +Exception+ object or +nil+, can be - * specified via the +:cause+ argument. - * - * Exceptions are caught by the +rescue+ clause of - * <code>begin...end</code> blocks. - * - * raise "Failed to create socket" - * raise ArgumentError, "No parameters", caller_locations + * raise(exception, message = exception.to_s, backtrace = nil, cause: $!) + * raise(message = nil, cause: $!) + * + * Raises an exception; + * see {Exceptions}[rdoc-ref:exceptions.md]. + * + * Argument +exception+ sets the class of the new exception; + * it should be class Exception or one of its subclasses + * (most commonly, RuntimeError or StandardError), + * or an instance of one of those classes: + * + * begin + * raise(StandardError) + * rescue => x + * p x.class + * end + * # => StandardError + * + * Argument +message+ sets the stored message in the new exception, + * which may be retrieved by method Exception#message; + * the message must be + * a {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects] + * or +nil+: + * + * begin + * raise(StandardError, 'Boom') + * rescue => x + * p x.message + * end + * # => "Boom" + * + * If argument +message+ is not given, + * the message is the exception class name. + * + * See {Messages}[rdoc-ref:exceptions.md@Messages]. + * + * Argument +backtrace+ sets the stored backtrace in the new exception, + * which may be retrieved by method Exception#backtrace; + * the backtrace must be an array of strings or +nil+: + * + * begin + * raise(StandardError, 'Boom', %w[foo bar baz]) + * rescue => x + * p x.backtrace + * end + * # => ["foo", "bar", "baz"] + * + * If argument +backtrace+ is not given, + * the backtrace is set according to an array of Thread::Backtrace::Location objects, + * as derived from the call stack. + * + * See {Backtraces}[rdoc-ref:exceptions.md@Backtraces]. + * + * Keyword argument +cause+ sets the stored cause in the new exception, + * which may be retrieved by method Exception#cause; + * the cause must be an exception object (Exception or one of its subclasses), + * or +nil+: + * + * begin + * raise(StandardError, cause: RuntimeError.new) + * rescue => x + * p x.cause + * end + * # => #<RuntimeError: RuntimeError> + * + * If keyword argument +cause+ is not given, + * the cause is the value of <tt>$!</tt>. + * + * See {Cause}[rdoc-ref:exceptions.md@Cause]. + * + * In the alternate calling sequence, + * where argument +exception+ _not_ given, + * raises a new exception of the class given by <tt>$!</tt>, + * or of class RuntimeError if <tt>$!</tt> is +nil+: + * + * begin + * raise + * rescue => x + * p x + * end + * # => RuntimeError + * + * With argument +exception+ not given, + * argument +message+ and keyword argument +cause+ may be given, + * but argument +backtrace+ may not be given. */ static VALUE |