Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 9e45e5c31959^
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bce1800506d8
Choose a head ref
  • 7 commits
  • 2 files changed
  • 3 contributors

Commits on Apr 19, 2017

  1. Implemented Enumerator#peek_values

    Who828 authored and kares committed Apr 19, 2017
    Copy the full SHA
    9e45e5c View commit details
  2. Copy the full SHA
    45e6354 View commit details
  3. Implemented Enumerator#feed method

    Who828 authored and kares committed Apr 19, 2017
    Copy the full SHA
    caa63c7 View commit details
  4. Copy the full SHA
    9f4a63f View commit details
  5. Copy the full SHA
    ceea221 View commit details
  6. Copy the full SHA
    c1de852 View commit details
  7. Copy the full SHA
    bce1800 View commit details
Showing with 65 additions and 4 deletions.
  1. +1 −1 core/src/main/java/org/jruby/RubyArray.java
  2. +64 −3 core/src/main/java/org/jruby/RubyEnumerator.java
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -1650,7 +1650,7 @@ public IRubyObject each_slice(ThreadContext context, IRubyObject arg, Block bloc
final int size = RubyNumeric.num2int(arg);
final Ruby runtime = context.runtime;
if (size <= 0) throw runtime.newArgumentError("invalid slice size");
return block.isGiven() ? eachSlice(context, size, block) : enumeratorize(context.runtime, this, "each_slice", arg);
return block.isGiven() ? eachSlice(context, size, block) : RubyEnumerator.enumeratorizeWithSize(context, this, "each_slice", arg, arg);
}

/** rb_ary_each_index
67 changes: 64 additions & 3 deletions core/src/main/java/org/jruby/RubyEnumerator.java
Original file line number Diff line number Diff line change
@@ -66,6 +66,8 @@ public class RubyEnumerator extends RubyObject {

/** A value or proc to provide the size of the Enumerator contents*/
private IRubyObject size;

private IRubyObject feedValue;

public static void defineEnumerator(Ruby runtime) {
RubyModule enm = runtime.getClassFromPath("Enumerable");
@@ -96,11 +98,24 @@ private RubyEnumerator(Ruby runtime, RubyClass type) {
initialize(runtime.getNil(), RubyString.newEmptyString(runtime), IRubyObject.NULL_ARRAY);
}

private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[]args, IRubyObject size) {
super(runtime, type);
initialize20(object, method, args, size);
}

private RubyEnumerator(Ruby runtime, RubyClass type, IRubyObject object, IRubyObject method, IRubyObject[]args) {
super(runtime, type);
initialize(object, method, args);
}

/**
* Transform object into an Enumerator with the given size
*/
static IRubyObject enumeratorizeWithSize(ThreadContext context, IRubyObject object, String method,IRubyObject arg, IRubyObject size) {
Ruby runtime = context.runtime;
return new RubyEnumerator(runtime, runtime.getEnumerator(), object, runtime.fastNewSymbol(method), new IRubyObject[] { arg }, size);
}

public static IRubyObject enumeratorize(Ruby runtime, IRubyObject object, String method) {
return new RubyEnumerator(runtime, runtime.getEnumerator(), object, runtime.fastNewSymbol(method), IRubyObject.NULL_ARRAY);
}
@@ -243,13 +258,15 @@ private IRubyObject initialize(IRubyObject object, IRubyObject method, IRubyObje
}

private IRubyObject initialize20(IRubyObject object, IRubyObject method, IRubyObject[] methodArgs, IRubyObject size) {
final Ruby runtime = getRuntime();
this.object = object;
this.method = method.asJavaString();
this.methodArgs = methodArgs;
this.size = size;
this.feedValue = runtime.getNil();
setInstanceVariable("@__object__", object);
setInstanceVariable("@__method__", method);
setInstanceVariable("@__args__", RubyArray.newArrayNoCopyLight(getRuntime(), methodArgs));
setInstanceVariable("@__args__", RubyArray.newArrayNoCopyLight(runtime, methodArgs));
return this;
}

@@ -261,6 +278,8 @@ public IRubyObject dup() {
copy.object = this.object;
copy.method = this.method;
copy.methodArgs = this.methodArgs;
copy.size = this.size;
copy.feedValue = getRuntime().getNil();
return copy;
}

@@ -271,6 +290,10 @@ public IRubyObject dup() {
*/
@JRubyMethod
public IRubyObject each(ThreadContext context, Block block) {
if (!block.isGiven()) {
return this;
}

return object.callMethod(context, method, methodArgs, block);
}

@@ -432,7 +455,7 @@ public static IRubyObject with_index19(ThreadContext context, IRubyObject self,
@JRubyMethod
public synchronized IRubyObject next(ThreadContext context) {
ensureNexter(context);

if (!feedValue.isNil()) feedValue = context.nil;
return nexter.next();
}

@@ -455,6 +478,31 @@ public synchronized IRubyObject peek(ThreadContext context) {
return nexter.peek();
}

@JRubyMethod(name = "peek_values", compat = RUBY1_9)
public synchronized IRubyObject peekValues(ThreadContext context) {
ensureNexter(context);

return RubyArray.newArray(context.runtime, nexter.peek());
}

@JRubyMethod(name = "next_values", compat = RUBY1_9)
public synchronized IRubyObject nextValues(ThreadContext context) {
ensureNexter(context);
if (!feedValue.isNil()) feedValue = context.nil;
return RubyArray.newArray(context.runtime, nexter.next());
}

@JRubyMethod(compat = RUBY1_9)
public IRubyObject feed(ThreadContext context, IRubyObject val) {
ensureNexter(context);
if (!feedValue.isNil()) {
throw context.runtime.newTypeError("feed value already set");
}
feedValue = val;
nexter.setFeedValue(val);
return context.nil;
}

private void ensureNexter(ThreadContext context) {
if (nexter == null) {
if (Options.ENUMERATOR_LIGHTWEIGHT.load()) {
@@ -494,13 +542,23 @@ private static abstract class Nexter {
/** args to each method */
protected final IRubyObject[] methodArgs;

private IRubyObject feedValue;

public Nexter(Ruby runtime, IRubyObject object, String method, IRubyObject[] methodArgs) {
this.object = object;
this.method = method;
this.methodArgs = methodArgs;
this.runtime = runtime;
}

public void setFeedValue(IRubyObject feedValue) {
this.feedValue = feedValue;
}

public IRubyObject getFeedValue() {
return feedValue;
}

public abstract IRubyObject next();

public abstract void shutdown();
@@ -569,6 +627,7 @@ private static class ThreadedNexter extends Nexter implements Runnable {

public ThreadedNexter(Ruby runtime, IRubyObject object, String method, IRubyObject[] methodArgs) {
super(runtime, object, method, methodArgs);
setFeedValue(runtime.getNil());
}

public synchronized IRubyObject next() {
@@ -688,7 +747,9 @@ public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block)
throw new JumpException.BreakJump(-1, NEVER);
}

return context.nil;
IRubyObject feedValue = getFeedValue();
setFeedValue(context.nil);
return feedValue;
}
}, context));
} catch (JumpException.BreakJump bj) {