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:
		
							parent
							
								
									dd5a95a14c
								
							
						
					
					
						commit
						5d8659a195
					
				
					 4 changed files with 67 additions and 5 deletions
				
			
		
							
								
								
									
										50
									
								
								enumerator.c
									
										
									
									
									
								
							
							
						
						
									
										50
									
								
								enumerator.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
 */
 | 
			
		||||
VALUE rb_cEnumerator;
 | 
			
		||||
static VALUE sym_each;
 | 
			
		||||
static ID id_rewind;
 | 
			
		||||
 | 
			
		||||
VALUE rb_eStopIteration;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -497,6 +498,18 @@ enumerator_with_object(obj, 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:
 | 
			
		||||
 *   e.next   => object
 | 
			
		||||
| 
						 | 
				
			
			@ -517,8 +530,15 @@ static VALUE
 | 
			
		|||
enumerator_next(obj)
 | 
			
		||||
    VALUE obj;
 | 
			
		||||
{
 | 
			
		||||
    rb_require("generator");
 | 
			
		||||
    return rb_funcall(obj, rb_intern("next"), 0, 0);
 | 
			
		||||
    if (require_generator()) {
 | 
			
		||||
	/*
 | 
			
		||||
	 * 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
 | 
			
		||||
 *
 | 
			
		||||
 * Rewinds the enumeration sequence by the next method.
 | 
			
		||||
 *
 | 
			
		||||
 * If the enclosed object responds to a "rewind" method, it is called.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
enumerator_rewind(obj)
 | 
			
		||||
    VALUE obj;
 | 
			
		||||
{
 | 
			
		||||
    rb_require("generator");
 | 
			
		||||
    return rb_funcall(obj, rb_intern("rewind"), 0, 0);
 | 
			
		||||
    if (require_generator()) {
 | 
			
		||||
	/*
 | 
			
		||||
	 * 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, "<<", yielder_yield, -2);
 | 
			
		||||
 | 
			
		||||
    sym_each	 	= ID2SYM(rb_intern("each"));
 | 
			
		||||
    sym_each = ID2SYM(rb_intern("each"));
 | 
			
		||||
    id_rewind = rb_intern("rewind");
 | 
			
		||||
 | 
			
		||||
    /* backward compatibility */
 | 
			
		||||
    rb_provide("enumerator.so");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue