Advertisement
Guest User

Untitled

a guest
Sep 1st, 2015
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.89 KB | None | 0 0
  1. commit c29ca8ea702eab870c29438e64e9594146924e2f
  2. Author: Akinori MUSHA <knu@idaemons.org>
  3. Date: Tue Sep 1 14:48:33 2015 +0900
  4.  
  5. * vm_eval.c (rb_f_loop): Kernel#loop returns the "result" value
  6. when StopIteration is raised.
  7.  
  8. diff --git a/ChangeLog b/ChangeLog
  9. index 77779a5..8017d09 100644
  10. --- a/ChangeLog
  11. +++ b/ChangeLog
  12. @@ -1,3 +1,8 @@
  13. +Tue Sep 1 14:49:27 2015 Akinori MUSHA <knu@iDaemons.org>
  14. +
  15. + * vm_eval.c (rb_f_loop): Kernel#loop returns the "result" value
  16. + when StopIteration is raised.
  17. +
  18. Mon Aug 31 17:04:45 2015 Koichi Sasada <ko1@atdot.net>
  19.  
  20. * class.c (move_refined_method): should insert a write barrier
  21. diff --git a/NEWS b/NEWS
  22. index 1803ed9..4ce0d65 100644
  23. --- a/NEWS
  24. +++ b/NEWS
  25. @@ -44,6 +44,10 @@ with all sufficient information, see the ChangeLog file.
  26. this parameter is bitwise-ORed to oflags generated by normal mode argument.
  27. [Feature #11253]
  28.  
  29. +* Kernel
  30. +
  31. + * Kernel#loop returns the "result" value when StopIteration is raised.
  32. +
  33. * Module
  34. * Module#deprecate_constant [Feature #11398]
  35.  
  36. diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb
  37. index b5ced3b..85e8c48 100644
  38. --- a/test/ruby/test_enumerator.rb
  39. +++ b/test/ruby/test_enumerator.rb
  40. @@ -46,6 +46,14 @@ class TestEnumerator < Test::Unit::TestCase
  41. }
  42. end
  43.  
  44. + def test_loop_return_value
  45. + assert_equal nil, loop { break }
  46. + assert_equal 42, loop { break 42 }
  47. +
  48. + e = Enumerator.new { |y| y << 1; y << 2; :stopped }
  49. + assert_equal :stopped, loop { e.next while true }
  50. + end
  51. +
  52. def test_nested_iteration
  53. def (o = Object.new).each
  54. yield :ok1
  55. diff --git a/vm_eval.c b/vm_eval.c
  56. index 00b47e5..a08e211 100644
  57. --- a/vm_eval.c
  58. +++ b/vm_eval.c
  59. @@ -24,7 +24,7 @@ static void vm_set_eval_stack(rb_thread_t * th, const rb_iseq_t *iseq, const rb_
  60. static int vm_collect_local_variables_in_heap(rb_thread_t *th, const VALUE *dfp, const struct local_var_list *vars);
  61.  
  62. static VALUE rb_eUncaughtThrow;
  63. -static ID id_tag, id_value;
  64. +static ID id_result, id_tag, id_value;
  65. #define id_mesg idMesg
  66.  
  67. /* vm_backtrace.c */
  68. @@ -1067,6 +1067,12 @@ loop_i(void)
  69. }
  70.  
  71. static VALUE
  72. +loop_stop(VALUE dummy, VALUE exc)
  73. +{
  74. + return rb_attr_get(exc, id_result);
  75. +}
  76. +
  77. +static VALUE
  78. rb_f_loop_size(VALUE self, VALUE args, VALUE eobj)
  79. {
  80. return DBL2NUM(INFINITY);
  81. @@ -1095,8 +1101,7 @@ static VALUE
  82. rb_f_loop(VALUE self)
  83. {
  84. RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
  85. - rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
  86. - return Qnil; /* dummy */
  87. + return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
  88. }
  89.  
  90. #if VMDEBUG
  91. @@ -2172,6 +2177,7 @@ Init_vm_eval(void)
  92. rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
  93. rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
  94.  
  95. + id_result = rb_intern_const("result");
  96. id_tag = rb_intern_const("tag");
  97. id_value = rb_intern_const("value");
  98. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement