Project

General

Profile

Feature #6824 ยป stop.patch

jasiek (Jan Szumiec), 08/02/2012 06:45 PM

View differences:

enumerator.c (working copy)
105 105
VALUE rb_cEnumerator;
106 106
VALUE rb_cLazy;
107 107
static ID id_rewind, id_each, id_new, id_initialize, id_yield, id_call;
108
static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_method;
108
static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_method, id_source;
109 109
static VALUE sym_each, sym_cycle;
110 110

  
111 111
VALUE rb_eStopIteration;
......
567 567
    result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
568 568
    e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
569 569
    rb_ivar_set(e->stop_exc, id_result, result);
570
    rb_ivar_set(e->stop_exc, id_source, obj);
570 571
    return rb_fiber_yield(1, &nil);
571 572
}
572 573

  
......
1724 1725
    return rb_attr_get(self, id_result);
1725 1726
}
1726 1727

  
1728
/*
1729
 * call-seq:
1730
 *   source       -> value
1731
 *
1732
 * Returns the enumerator responsible for raising this instance.
1733
 *
1734
 *   e = [].each
1735
 *
1736
 *   begin
1737
 *     e.next
1738
 *   rescue StopIteration => ex
1739
 *     puts ex.source
1740
 *   end
1741
 *
1742
 */
1743
static VALUE
1744
stop_source(VALUE self)
1745
{
1746
    return rb_attr_get(self, id_source);
1747
}
1748

  
1727 1749
void
1728 1750
InitVM_Enumerator(void)
1729 1751
{
......
1773 1795

  
1774 1796
    rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
1775 1797
    rb_define_method(rb_eStopIteration, "result", stop_result, 0);
1798
    rb_define_method(rb_eStopIteration, "source", stop_source, 0);
1776 1799

  
1777 1800
    /* Generator */
1778 1801
    rb_cGenerator = rb_define_class_under(rb_cEnumerator, "Generator", rb_cObject);
......
1808 1831
    id_receiver = rb_intern("receiver");
1809 1832
    id_arguments = rb_intern("arguments");
1810 1833
    id_method = rb_intern("method");
1834
    id_source = rb_intern("source");
1811 1835
    sym_each = ID2SYM(id_each);
1812 1836
    sym_cycle = ID2SYM(rb_intern("cycle"));
1813 1837

  
test/ruby/test_enumerator.rb (working copy)
185 185
    assert_equal(res, exc.result)
186 186
  end
187 187

  
188
  def test_stop_source
189
    e = [].each
190
    begin
191
      e.next
192
      fail
193
    rescue StopIteration => ex
194
      assert_equal(e, ex.source)
195
    end      
196
  end
197

  
188 198
  def test_next_values
189 199
    o = Object.new
190 200
    def o.each