arguments to Thread#raise ?

P

Paul Brannan

If I write:

exc = StandardError.new("foo")
Thread.main.raise exc, exc.message, exc.backtrace

I get:

test2.rb:2: foo (StandardError)

But if I write:

exc = StandardError.new("foo")
t = Thread.new do
Thread.main.raise exc, exc.message, exc.backtrace
end
t.join

Then I get:

test2.rb:3:in `raise': wrong number of arguments (3 for 2) (ArgumentError)
from test2.rb:5:in `join'
from test2.rb:5

Version:

ruby 1.9.0 (2004-06-22) [i686-linux]

Is this expected behavior? What are the arguments to Thread#raise
supposed to be?

Paul
 
T

ts

P> Thread.main.raise exc, exc.message, exc.backtrace

This is Kernel#raise which can take 3 arguments : exception, message,
backtrace


P> t = Thread.new do
P> Thread.main.raise exc, exc.message, exc.backtrace

This is Thread#raise which can take only 2 arguments : exception and
message


Guy Decoux
 
P

Paul Brannan

P> Thread.main.raise exc, exc.message, exc.backtrace

This is Kernel#raise which can take 3 arguments : exception, message,
backtrace

It essentially does the same as Kernel#raise under the hood, but I'm
definitely calling Thread#raise (rb_thread_raise_m), not Kernel#raise
(rb_f_raise).
P> t = Thread.new do
P> Thread.main.raise exc, exc.message, exc.backtrace

This is Thread#raise which can take only 2 arguments : exception and
message

Why is that (I mean, is there any technical reason for the
inconsistency)?

In order to get the backtrace I wanted, I had to use a pretty ugly
workaround.

Paul
 
N

nobu.nokada

Hi,

At Thu, 8 Jul 2004 02:53:57 +0900,
Paul Brannan wrote in [ruby-talk:105512]:
It essentially does the same as Kernel#raise under the hood, but I'm
definitely calling Thread#raise (rb_thread_raise_m), not Kernel#raise
(rb_f_raise).

The former calls the later if the target thread is current.
Why is that (I mean, is there any technical reason for the
inconsistency)?

I don't know exact reason, but it feels wrong. Also, I suspect
the arguments should be evaluated in the caller's context.


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.675
diff -u -2 -p -r1.675 eval.c
--- eval.c 5 Jul 2004 00:03:11 -0000 1.675
+++ eval.c 7 Jul 2004 22:05:53 -0000
@@ -145,4 +145,6 @@ static VALUE rb_f_block_given_p _((void)
static VALUE umethod_bind _((VALUE, VALUE));
static VALUE rb_mod_define_method _((int, VALUE*, VALUE));
+NORETURN(static void rb_raise_jump _((VALUE)));
+static VALUE rb_make_exception _((int argc, VALUE *argv));

static int scope_vmode;
@@ -4391,4 +4393,13 @@ rb_f_raise(argc, argv)
VALUE *argv;
{
+ rb_raise_jump(rb_make_exception(argc, argv));
+ return Qnil; /* not reached */
+}
+
+static VALUE
+rb_make_exception(argc, argv)
+ int argc;
+ VALUE *argv;
+{
VALUE mesg;
ID exception;
@@ -4430,4 +4441,11 @@ rb_f_raise(argc, argv)
}

+ return mesg;
+}
+
+static void
+rb_raise_jump(mesg)
+ VALUE mesg;
+{
if (ruby_frame != top_frame) {
PUSH_FRAME(); /* fake frame */
@@ -4437,6 +4455,4 @@ rb_f_raise(argc, argv)
}
rb_longjmp(TAG_RAISE, mesg);
-
- return Qnil; /* not reached */
}

@@ -9765,6 +9781,5 @@ rb_thread_check(data)
static VALUE rb_thread_raise _((int, VALUE*, rb_thread_t));

-static int th_raise_argc;
-static VALUE th_raise_argv[2];
+static VALUE th_raise_exception;
static NODE *th_raise_node;
static VALUE th_cmd;
@@ -9866,5 +9881,5 @@ rb_thread_switch(n)
ruby_frame->last_func = 0;
ruby_current_node = th_raise_node;
- rb_f_raise(th_raise_argc, th_raise_argv);
+ rb_raise_jump(th_raise_exception);
break;
case RESTORE_SIGNAL:
@@ -9872,5 +9887,5 @@ rb_thread_switch(n)
break;
case RESTORE_EXIT:
- ruby_errinfo = th_raise_argv[0];
+ ruby_errinfo = th_raise_exception;
ruby_current_node = th_raise_node;
error_print();
@@ -10035,6 +10050,5 @@ rb_thread_main_jump(err, tag)
{
curr_thread = main_thread;
- th_raise_argc = 1;
- th_raise_argv[0] = err;
+ th_raise_exception = err;
th_raise_node = ruby_current_node;
rb_thread_restore_context(main_thread, tag);
@@ -11817,4 +11831,5 @@ rb_thread_raise(argc, argv, th)
{
volatile rb_thread_t th_save = th;
+ VALUE exc;

if (!th->next) {
@@ -11822,6 +11837,7 @@ rb_thread_raise(argc, argv, th)
}
if (rb_thread_dead(th)) return Qnil;
+ exc = rb_make_exception(argc, argv);
if (curr_thread == th) {
- rb_f_raise(argc, argv);
+ rb_raise_jump(exc);
}

@@ -11832,9 +11848,8 @@ rb_thread_raise(argc, argv, th)
}

- rb_scan_args(argc, argv, "11", &th_raise_argv[0], &th_raise_argv[1]);
rb_thread_ready(th);
curr_thread = th;

- th_raise_argc = argc;
+ th_raise_exception = exc;
th_raise_node = ruby_current_node;
rb_thread_restore_context(curr_thread, RESTORE_RAISE);
 
P

Paul Brannan

I don't know exact reason, but it feels wrong. Also, I suspect
the arguments should be evaluated in the caller's context.

The code is much easier to read/follow this way, too.

Paul
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: arguments to Thread#raise ?"

|I don't know exact reason, but it feels wrong. Also, I suspect
|the arguments should be evaluated in the caller's context.

I like this. Commit to the HEAD. Do you think it's good enough for
last minute change to 1.8.2? If you feel so, go ahead and commit.

matz.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,147
Messages
2,570,834
Members
47,382
Latest member
MichaleStr

Latest Threads

Top