[前][次][番号順一覧][スレッド一覧]

ruby-changes:31605

From: nobu <ko1@a...>
Date: Fri, 15 Nov 2013 23:08:54 +0900 (JST)
Subject: [ruby-changes:31605] nobu:r43684 (trunk): eval.c: refactor exception cause

nobu	2013-11-15 23:08:49 +0900 (Fri, 15 Nov 2013)

  New Revision: 43684

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43684

  Log:
    eval.c: refactor exception cause
    
    * eval.c (setup_exception): set up cause after exception to be raised
      is fixed.  [Feature #8257]

  Modified files:
    trunk/eval.c
    trunk/test/ruby/test_exception.rb
Index: eval.c
===================================================================
--- eval.c	(revision 43683)
+++ eval.c	(revision 43684)
@@ -431,6 +431,34 @@ rb_frozen_class_p(VALUE klass) https://github.com/ruby/ruby/blob/trunk/eval.c#L431
 }
 
 NORETURN(static void rb_longjmp(int, volatile VALUE));
+static VALUE get_errinfo(void);
+static VALUE get_thread_errinfo(rb_thread_t *th);
+
+static VALUE
+exc_setup_cause(VALUE exc, VALUE cause)
+{
+    ID id_cause;
+    CONST_ID(id_cause, "cause");
+
+#if SUPPORT_JOKE
+    if (NIL_P(cause)) {
+	ID id_true_cause;
+	CONST_ID(id_true_cause, "true_cause");
+
+	cause = rb_attr_get(rb_eFatal, id_true_cause);
+	if (NIL_P(cause)) {
+	    cause = rb_exc_new_cstr(rb_eFatal, "because using such Ruby");
+	    rb_ivar_set(cause, id_cause, INT2FIX(42)); /* the answer */
+	    OBJ_FREEZE(cause);
+	    rb_ivar_set(rb_eFatal, id_true_cause, cause);
+	}
+    }
+#endif
+    if (!NIL_P(cause) && cause != exc) {
+	rb_ivar_set(exc, id_cause, cause);
+    }
+    return exc;
+}
 
 static void
 setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg)
@@ -447,6 +475,7 @@ setup_exception(rb_thread_t *th, int tag https://github.com/ruby/ruby/blob/trunk/eval.c#L475
     if (NIL_P(mesg)) {
 	mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
     }
+    exc_setup_cause(mesg, get_thread_errinfo(th));
 
     file = rb_sourcefile();
     if (file) line = rb_sourceline();
@@ -552,8 +581,6 @@ rb_interrupt(void) https://github.com/ruby/ruby/blob/trunk/eval.c#L581
     rb_raise(rb_eInterrupt, "%s", "");
 }
 
-static VALUE get_errinfo(void);
-
 /*
  *  call-seq:
  *     raise
@@ -641,10 +668,6 @@ make_exception(int argc, VALUE *argv, in https://github.com/ruby/ruby/blob/trunk/eval.c#L668
 	if (argc > 2)
 	    set_backtrace(mesg, argv[2]);
     }
-    {
-	VALUE cause = get_errinfo();
-	if (!NIL_P(cause)) rb_iv_set(mesg, "cause", cause);
-    }
 
     return mesg;
 }
Index: test/ruby/test_exception.rb
===================================================================
--- test/ruby/test_exception.rb	(revision 43683)
+++ test/ruby/test_exception.rb	(revision 43684)
@@ -479,16 +479,31 @@ end.join https://github.com/ruby/ruby/blob/trunk/test/ruby/test_exception.rb#L479
 
   def test_cause
     msg = "[Feature #8257]"
+    cause = nil
     e = assert_raise(StandardError) {
       begin
         raise msg
       rescue => e
-        assert_nil(e.cause, msg)
+        cause = e.cause
         raise StandardError
       end
     }
+    assert_nil(cause, msg)
     cause = e.cause
     assert_instance_of(RuntimeError, cause, msg)
     assert_equal(msg, cause.message, msg)
   end
+
+  def test_cause_reraised
+    msg = "[Feature #8257]"
+    cause = nil
+    e = assert_raise(RuntimeError) {
+      begin
+        raise msg
+      rescue => e
+        raise e
+      end
+    }
+    assert_not_same(e, e.cause, "#{msg}: should not be recursive")
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]