e$B%9%l%C%IJQ?t$r0l;~E*$K@_Dj$9$k%a%=%C%I$r2C$($k$N$O$I$&$G$7$g$&$+!#e(B
e$B$?$H$($Pe(B Thread#bind(sym, val) { … } e$B$H$7$F!“e(B
e$B%V%m%C%/$r8F$S=P$7$F$$$k$”$$$@!"%9%l%C%IJQ?te(B sym e$B$re(B
val e$B$K@_Dj$9$k!"$H$$$&$h$&$J$b$N$G$9!#e(B
p Thread.current[:a] # nil
Thread.current.bind(:a, 100) {
p Thread.current[:a] # 100
}
p Thread.current[:a] # nil e$B$KLa$ke(B
e$B%9%l%C%IJQ?t$O$3$N$h$&$J;H$$J}$,B?$$$N$G!"%a%=%C%I$,$"$C$F$b$$$$e(B
e$B$h$&$K;W$$$^$9!#e(B
e$B$J$*!"e(Bbind e$B0J30$NL>A0$H$7$F$Oe(B let e$B$,;W$$Ib$+$S$^$9!#e(B
e$B$^$?!“e(BThread e$B$8$c$J$/$Fe(B Fiber
e$B$8$c$J$$$+!”$H$$$&OC$O$"$k$+$b$7$l$^$;$s!#e(B
% svn diff --diff-cmd diff -x ‘-u -p’
Index: thread.c
— thread.c (revision 28780)
+++ thread.c (working copy)
@@ -2071,6 +2071,59 @@ rb_thread_aset(VALUE self, VALUE id, VAL
return rb_thread_local_aset(self, rb_to_id(id), val);
}
+struct rb_thread_bind_arg {
- VALUE thread;
- ID id;
- VALUE old;
+};
+static VALUE
+rb_thread_bind_ensure(VALUE _arg)
+{
- struct rb_thread_bind_arg *arg = (struct rb_thread_bind_arg *)_arg;
- rb_thread_local_aset(arg->thread, arg->id, arg->old);
- return Qnil;
+}
+/*
-
- call-seq:
-
-
thr.bind(sym, obj) { ... }
-
-
-
- Set the attribute temporally.
-
-
- This method sets the attribute sym of the thread thr as obj
-
- between the block is called.
-
- It restore the attribute after the block exits
-
- even if an exception is raised in the block.
-
-
- This method returns the value of the block.
-
-
-
Thread.current.bind(:a, 1) {
-
-
-
# Thread.current[:a] is 1.
-
-
-
Thread.current.bind(:a, 2) {
-
-
-
# Thread.current[:a] is 2.
-
-
-
Thread.current.bind(:a, 3) {
-
-
-
# Thread.current[:a] is 3.
-
-
-
}
-
-
-
# Thread.current[:a] is 2.
-
-
-
}
-
-
-
# Thread.current[:a] is 1.
-
-
-
}
-
-
- */
+static VALUE
+rb_thread_bind(VALUE thread, VALUE sym, VALUE val)
+{
- ID id = rb_to_id(sym);
- struct rb_thread_bind_arg arg;
- arg.thread = thread;
- arg.id = id;
- arg.old = rb_thread_local_aref(thread, id);
- rb_thread_local_aset(thread, id, val);
- return rb_ensure(rb_yield, Qnil, rb_thread_bind_ensure,
(VALUE)&arg);
+}
/*
- call-seq:
-
thr.key?(sym) -> true or false
@@ -4202,6 +4255,7 @@ Init_Thread(void)
rb_define_method(rb_cThread, “wakeup”, rb_thread_wakeup, 0);
rb_define_method(rb_cThread, “[]”, rb_thread_aref, 1);
rb_define_method(rb_cThread, “[]=”, rb_thread_aset, 2);
- rb_define_method(rb_cThread, “bind”, rb_thread_bind, 2);
rb_define_method(rb_cThread, “key?”, rb_thread_key_p, 1);
rb_define_method(rb_cThread, “keys”, rb_thread_keys, 0);
rb_define_method(rb_cThread, “priority”, rb_thread_priority, 0);