Skip to content

Commit ad95b0b

Browse files
committed
Merge pull request #2486 from Who828/impl_feed
Implemented Enumerator#feed method
2 parents 96174b6 + 38c8c49 commit ad95b0b

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

core/src/main/java/org/jruby/RubyEnumerator.java

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ public class RubyEnumerator extends RubyObject {
6767

6868
/** Function object for lazily computing size (used for internally created enumerators) */
6969
private SizeFn sizeFn;
70+
71+
private IRubyObject feedValue;
7072

7173
public static void defineEnumerator(Ruby runtime) {
7274
RubyModule enm = runtime.getClassFromPath("Enumerable");
@@ -255,14 +257,16 @@ private IRubyObject initialize(IRubyObject object, IRubyObject method, IRubyObje
255257
}
256258

257259
private IRubyObject initialize20(IRubyObject object, IRubyObject method, IRubyObject[] methodArgs, IRubyObject size, SizeFn sizeFn) {
260+
final Ruby runtime = getRuntime();
258261
this.object = object;
259262
this.method = method.asJavaString();
260263
this.methodArgs = methodArgs;
261264
this.size = size;
262265
this.sizeFn = sizeFn;
266+
this.feedValue = runtime.getNil();
263267
setInstanceVariable("@__object__", object);
264268
setInstanceVariable("@__method__", method);
265-
setInstanceVariable("@__args__", RubyArray.newArrayNoCopyLight(getRuntime(), methodArgs));
269+
setInstanceVariable("@__args__", RubyArray.newArrayNoCopyLight(runtime, methodArgs));
266270
return this;
267271
}
268272

@@ -275,7 +279,8 @@ public IRubyObject dup() {
275279
copy.method = this.method;
276280
copy.methodArgs = this.methodArgs;
277281
copy.size = this.size;
278-
copy.sizeFn = this.sizeFn;
282+
copy.sizeFn = this.sizeFn;
283+
copy.feedValue = getRuntime().getNil();
279284
return copy;
280285
}
281286

@@ -452,7 +457,7 @@ public IRubyObject with_index19(ThreadContext context, IRubyObject arg, final Bl
452457
@JRubyMethod
453458
public synchronized IRubyObject next(ThreadContext context) {
454459
ensureNexter(context);
455-
460+
if (!feedValue.isNil()) feedValue = context.nil;
456461
return nexter.next();
457462
}
458463

@@ -485,10 +490,21 @@ public synchronized IRubyObject peekValues(ThreadContext context) {
485490
@JRubyMethod(name = "next_values")
486491
public synchronized IRubyObject nextValues(ThreadContext context) {
487492
ensureNexter(context);
488-
493+
if (!feedValue.isNil()) feedValue = context.nil;
489494
return RubyArray.newArray(context.runtime, nexter.next());
490495
}
491496

497+
@JRubyMethod
498+
public IRubyObject feed(ThreadContext context, IRubyObject val) {
499+
ensureNexter(context);
500+
if (!feedValue.isNil()) {
501+
throw context.runtime.newTypeError("feed value already set");
502+
}
503+
feedValue = val;
504+
nexter.setFeedValue(val);
505+
return context.nil;
506+
}
507+
492508
private void ensureNexter(ThreadContext context) {
493509
if (nexter == null) {
494510
if (Options.ENUMERATOR_LIGHTWEIGHT.load()) {
@@ -537,14 +553,24 @@ private static abstract class Nexter {
537553

538554
/** args to each method */
539555
protected final IRubyObject[] methodArgs;
556+
557+
private IRubyObject feedValue;
540558

541559
public Nexter(Ruby runtime, IRubyObject object, String method, IRubyObject[] methodArgs) {
542560
this.object = object;
543561
this.method = method;
544562
this.methodArgs = methodArgs;
545563
this.runtime = runtime;
546564
}
547-
565+
566+
public void setFeedValue(IRubyObject feedValue) {
567+
this.feedValue = feedValue;
568+
}
569+
570+
public IRubyObject getFeedValue() {
571+
return feedValue;
572+
}
573+
548574
public abstract IRubyObject next();
549575

550576
public abstract void shutdown();
@@ -616,8 +642,9 @@ private static class TerminateEnumeration extends RuntimeException implements Un
616642

617643
public ThreadedNexter(Ruby runtime, IRubyObject object, String method, IRubyObject[] methodArgs) {
618644
super(runtime, object, method, methodArgs);
645+
setFeedValue(runtime.getNil());
619646
}
620-
647+
621648
@Override
622649
public synchronized IRubyObject next() {
623650
if (doneObject != null) {
@@ -741,7 +768,9 @@ public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block)
741768
throw terminateEnumeration;
742769
}
743770

744-
return context.nil;
771+
IRubyObject feedValue = getFeedValue();
772+
setFeedValue(context.nil);
773+
return feedValue;
745774
}
746775
}, context));
747776
} catch (TerminateEnumeration te) {

0 commit comments

Comments
 (0)