Feature #10344 » 0001-Implement-Fiber-raise.patch
cont.c | ||
---|---|---|
make_passing_arg(int argc, const VALUE *argv)
|
||
{
|
||
switch (argc) {
|
||
case -1:
|
||
return argv[0];
|
||
case 0:
|
||
return Qnil;
|
||
case 1:
|
||
... | ... | |
/*
|
||
* call-seq:
|
||
* fiber.raise -> obj
|
||
* fiber.raise(string) -> obj
|
||
* fiber.raise(exception [, string [, array]]) -> obj
|
||
*
|
||
* Raises an exception in the fiber at the point at which the last
|
||
* <code>Fiber.yield</code> was called, or at the start if neither +resume+
|
||
* nor +raise+ were called before.
|
||
*
|
||
* With no arguments, raises a +RuntimeError+. With a single +String+
|
||
* argument, raises a +RuntimeError+ with the string as a message. Otherwise,
|
||
* the first parameter should be the name of an +Exception+ class (or an
|
||
* object that returns an +Exception+ object when sent an +exception+
|
||
* message). The optional second parameter sets the message associated with
|
||
* the exception, and the third parameter is an array of callback information.
|
||
* Exceptions are caught by the +rescue+ clause of <code>begin...end</code>
|
||
* blocks.
|
||
*/
|
||
static VALUE
|
||
rb_fiber_raise(int argc, VALUE *argv, VALUE fib)
|
||
{
|
||
VALUE exc = rb_make_exception(argc, argv);
|
||
return rb_fiber_resume(fib, -1, &exc);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* fiber.transfer(args, ...) -> obj
|
||
*
|
||
* Transfer control to another fiber, resuming it from where it last
|
||
... | ... | |
rb_define_singleton_method(rb_cFiber, "yield", rb_fiber_s_yield, -1);
|
||
rb_define_method(rb_cFiber, "initialize", rb_fiber_init, 0);
|
||
rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1);
|
||
rb_define_method(rb_cFiber, "raise", rb_fiber_raise, -1);
|
||
}
|
||
RUBY_SYMBOL_EXPORT_BEGIN
|
test/ruby/test_fiber.rb | ||
---|---|---|
}
|
||
fib.resume
|
||
}
|
||
assert_raise(FiberError){
|
||
fib = Fiber.new{}
|
||
fib.raise "raise in unborn fiber"
|
||
}
|
||
assert_raise(FiberError){
|
||
fib = Fiber.new{}
|
||
fib.resume
|
||
fib.raise "raise in dead fiber"
|
||
}
|
||
end
|
||
def test_return
|
||
... | ... | |
}
|
||
end
|
||
def test_raise
|
||
assert_raise(ZeroDivisionError){
|
||
Fiber.new do
|
||
1/0
|
||
end.resume
|
||
}
|
||
assert_raise(RuntimeError){
|
||
fib = Fiber.new{ Fiber.yield }
|
||
fib.raise "raise and propagate"
|
||
}
|
||
assert_nothing_raised{
|
||
fib = Fiber.new do
|
||
begin
|
||
Fiber.yield
|
||
rescue
|
||
end
|
||
end
|
||
fib.resume
|
||
fib.raise "rescue in fiber"
|
||
}
|
||
fib = Fiber.new do
|
||
begin
|
||
Fiber.yield
|
||
rescue
|
||
Fiber.yield :ok
|
||
end
|
||
end
|
||
fib.resume
|
||
assert_equal(:ok, fib.raise)
|
||
end
|
||
def test_transfer
|
||
ary = []
|
||
f2 = nil
|