1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* enumerator.c (enumerator_next, enumerator_rewind),

lib/generator.rb (Enumerator#rewind): If the enclosed object
  responds to a "rewind" method, call it.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@20645 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
knu 2008-12-11 12:14:10 +00:00
parent dd5a95a14c
commit 5d8659a195
4 changed files with 67 additions and 5 deletions

View file

@ -1,3 +1,9 @@
Thu Dec 11 21:09:47 2008 Akinori MUSHA <knu@iDaemons.org>
* enumerator.c (enumerator_next, enumerator_rewind),
lib/generator.rb (Enumerator#rewind): If the enclosed object
responds to a "rewind" method, call it.
Thu Dec 11 21:07:56 2008 Kouhei Sutou <kou@cozmixng.org> Thu Dec 11 21:07:56 2008 Kouhei Sutou <kou@cozmixng.org>
* lib/rss/maker.rb, lib/rss/maker/0.9.rb, lib/rss/maker/base.rb: * lib/rss/maker.rb, lib/rss/maker/0.9.rb, lib/rss/maker/base.rb:

10
NEWS
View file

@ -36,6 +36,10 @@ with all sufficient information, see the ChangeLog file.
Now can generate an enumerator from a block that defines Now can generate an enumerator from a block that defines
enumeration instead of an enumerable object. enumeration instead of an enumerable object.
* Enumerator#rewind
Now calls the "rewind" method of the enclosed object if defined.
* Hash#default_proc= * Hash#default_proc=
New method. New method.
@ -117,6 +121,12 @@ with all sufficient information, see the ChangeLog file.
* do not raise ShiftingError if an aged file already exists. * do not raise ShiftingError if an aged file already exists.
(no ShiftingError will be raised from 1.2.7, just warn() instead) (no ShiftingError will be raised from 1.2.7, just warn() instead)
=== Compatibility issues (excluding feature bug fixes)
* Enumerator#rewind
See above.
== Changes since the 1.8.6 release == Changes since the 1.8.6 release
=== Configuration changes === Configuration changes

View file

@ -22,6 +22,7 @@
*/ */
VALUE rb_cEnumerator; VALUE rb_cEnumerator;
static VALUE sym_each; static VALUE sym_each;
static ID id_rewind;
VALUE rb_eStopIteration; VALUE rb_eStopIteration;
@ -497,6 +498,18 @@ enumerator_with_object(obj, memo)
return memo; return memo;
} }
static int
require_generator()
{
static int done = 0;
if (done)
return 0; /* not the first time */
rb_require("generator");
done = 1;
return 1; /* the first time */
}
/* /*
* call-seq: * call-seq:
* e.next => object * e.next => object
@ -517,8 +530,15 @@ static VALUE
enumerator_next(obj) enumerator_next(obj)
VALUE obj; VALUE obj;
{ {
rb_require("generator"); if (require_generator()) {
return rb_funcall(obj, rb_intern("next"), 0, 0); /*
* Call the new rewind method that the generator library
* redefines.
*/
return rb_funcall(obj, rb_intern("next"), 0, 0);
} else {
rb_raise(rb_eRuntimeError, "unexpected call; the generator library must have failed in redefining this method");
}
} }
/* /*
@ -526,14 +546,33 @@ enumerator_next(obj)
* e.rewind => e * e.rewind => e
* *
* Rewinds the enumeration sequence by the next method. * Rewinds the enumeration sequence by the next method.
*
* If the enclosed object responds to a "rewind" method, it is called.
*/ */
static VALUE static VALUE
enumerator_rewind(obj) enumerator_rewind(obj)
VALUE obj; VALUE obj;
{ {
rb_require("generator"); if (require_generator()) {
return rb_funcall(obj, rb_intern("rewind"), 0, 0); /*
* Call the new rewind method that the generator library
* redefines.
*/
return rb_funcall(obj, rb_intern("rewind"), 0, 0);
} else {
/*
* Once the generator library is loaded and the rewind method
* is overridden, this method changes itself to a secret knob
* to rewind the internal object. (black magic!)
*/
struct enumerator *e;
e = enumerator_ptr(obj);
if (rb_respond_to(e->obj, id_rewind))
rb_funcall(e->obj, id_rewind, 0);
return obj;
}
} }
/* /*
@ -815,7 +854,8 @@ Init_Enumerator()
rb_define_method(rb_cYielder, "yield", yielder_yield, -2); rb_define_method(rb_cYielder, "yield", yielder_yield, -2);
rb_define_method(rb_cYielder, "<<", yielder_yield, -2); rb_define_method(rb_cYielder, "<<", yielder_yield, -2);
sym_each = ID2SYM(rb_intern("each")); sym_each = ID2SYM(rb_intern("each"));
id_rewind = rb_intern("rewind");
/* backward compatibility */ /* backward compatibility */
rb_provide("enumerator.so"); rb_provide("enumerator.so");

View file

@ -193,12 +193,18 @@ class Enumerator
raise StopIteration, 'iteration reached at end' raise StopIteration, 'iteration reached at end'
end end
# :nodoc:
alias __orig_rewind rewind
# call-seq: # call-seq:
# e.rewind => e # e.rewind => e
# #
# Rewinds the enumeration sequence by the next method. # Rewinds the enumeration sequence by the next method.
#
# If the enclosed object responds to a "rewind" method, it is called.
def rewind def rewind
__generator.rewind __generator.rewind
__orig_rewind
self self
end end
end end