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: 21f0aa09f5ae
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0d9ec8530156
Choose a head ref
  • 6 commits
  • 4 files changed
  • 2 contributors

Commits on Mar 20, 2018

  1. Enumerable#one? now accept a pattern argument

    For more information, please see feature #11286.
    nomadium committed Mar 20, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f2cbbc7 View commit details
  2. Enumerable#none? now accept a pattern argument

    For more information, please see feature #11286.
    nomadium committed Mar 20, 2018
    Copy the full SHA
    3c3bd8c View commit details
  3. Enumerable#any? now accept a pattern argument

    For more information, please see feature #11286.
    nomadium committed Mar 20, 2018
    Copy the full SHA
    1115791 View commit details
  4. Enumerable#all? now accept a pattern argument

    For more information, please see feature #11286.
    nomadium committed Mar 20, 2018
    Copy the full SHA
    3e8c616 View commit details

Commits on Mar 21, 2018

  1. Fix failing test with Enumerable#any?

    Replace each call + JavaInternalBlockBody with callEach + BlockCallback
    as is implemented Enumerable#all? as well.
    
    The failed test was:
    https://github.com/jruby/jruby/blob/3813f0a53c22af8122e8c2b70c7d87ae35323109/spec/ruby/core/enumerable/any_spec.rb#L214
    nomadium committed Mar 21, 2018
    Copy the full SHA
    feac6b5 View commit details
  2. Merge pull request #5096 from nomadium/enumerable-methods-one-none-an…

    …y-and-all-now-accept-pattern-argument
    
    Enumerable#any?, all?, none? and one? now accept a pattern argument
    headius authored Mar 21, 2018
    Copy the full SHA
    0d9ec85 View commit details
26 changes: 17 additions & 9 deletions core/src/main/java/org/jruby/RubyArray.java
Original file line number Diff line number Diff line change
@@ -4374,8 +4374,8 @@ public IRubyObject rotate(ThreadContext context, IRubyObject cnt) {

// Enumerable direct implementations (non-"each" versions)
// NOTE: not a @JRubyMethod(name = "all?") as there's no Array#all? on MRI
public IRubyObject all_p(ThreadContext context, Block block) {
if (!isBuiltin("each")) return RubyEnumerable.all_pCommon(context, this, block);
public IRubyObject all_p(ThreadContext context, IRubyObject[] args, Block block) {
if (!isBuiltin("each")) return RubyEnumerable.all_pCommon(context, this, args, block);
if (!block.isGiven()) return all_pBlockless(context);

for (int i = 0; i < realLength; i++) {
@@ -4393,11 +4393,12 @@ private IRubyObject all_pBlockless(ThreadContext context) {
return context.runtime.getTrue();
}

@JRubyMethod(name = "any?")
public IRubyObject any_p(ThreadContext context, Block block) {
@JRubyMethod(name = "any?", optional = 1)
public IRubyObject any_p(ThreadContext context, IRubyObject[] args, Block block) {
if (isEmpty()) return context.runtime.getFalse();
if (!isBuiltin("each")) return RubyEnumerable.any_pCommon(context, this, block);
if (!block.isGiven()) return any_pBlockless(context);
if (!isBuiltin("each")) return RubyEnumerable.any_pCommon(context, this, args, block);
boolean patternGiven = args.length > 0;
if (!block.isGiven() || patternGiven) return any_pBlockless(context, args);

for (int i = 0; i < realLength; i++) {
if (block.yield(context, eltOk(i)).isTrue()) return context.runtime.getTrue();
@@ -4406,9 +4407,16 @@ public IRubyObject any_p(ThreadContext context, Block block) {
return context.runtime.getFalse();
}

private IRubyObject any_pBlockless(ThreadContext context) {
for (int i = 0; i < realLength; i++) {
if (eltOk(i).isTrue()) return context.runtime.getTrue();
private IRubyObject any_pBlockless(ThreadContext context, IRubyObject[] args) {
IRubyObject pattern = args.length > 0 ? args[0] : null;
if (pattern == null) {
for (int i = 0; i < realLength; i++) {
if (eltOk(i).isTrue()) return context.runtime.getTrue();
}
} else {
for (int i = 0; i < realLength; i++) {
if (pattern.callMethod(context, "===", eltOk(i)).isTrue()) return context.runtime.getTrue();
}
}

return context.runtime.getFalse();
187 changes: 125 additions & 62 deletions core/src/main/java/org/jruby/RubyEnumerable.java
Original file line number Diff line number Diff line change
@@ -1541,13 +1541,15 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return RubyArray.newArrayMayCopy(runtime, result);
}

@JRubyMethod(name = "none?")
public static IRubyObject none_p(ThreadContext context, IRubyObject self, final Block block) {
@JRubyMethod(name = "none?", optional = 1)
public static IRubyObject none_p(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;
final IRubyObject pattern = (args.length > 0) ? args[0] : null;
final boolean patternGiven = pattern != null;

try {
if (block.isGiven()) {
if (block.isGiven() && !patternGiven) {
callEach(runtime, context, self, block.getSignature(), new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "none?");
@@ -1558,14 +1560,25 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "none?");
IRubyObject larg = packEnumValues(runtime, largs);
if (larg.isTrue()) throw JumpException.SPECIAL_JUMP;
return runtime.getNil();
}
});
if (patternGiven) {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "none?");
IRubyObject larg = packEnumValues(runtime, largs);
if (pattern.callMethod(ctx, "===", larg).isTrue()) throw JumpException.SPECIAL_JUMP;
return runtime.getNil();
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "none?");
IRubyObject larg = packEnumValues(runtime, largs);
if (larg.isTrue()) throw JumpException.SPECIAL_JUMP;
return runtime.getNil();
}
});
}
}
} catch (JumpException.SpecialJump sj) {
return runtime.getFalse();
@@ -1574,7 +1587,7 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
}

public static IRubyObject none_p19(ThreadContext context, IRubyObject self, final Block block) {
return none_p(context, self, block);
return none_p(context, self, new IRubyObject[]{}, block);
}

@Deprecated
@@ -1607,14 +1620,16 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return runtime.getTrue();
}

@JRubyMethod(name = "one?")
public static IRubyObject one_p(ThreadContext context, IRubyObject self, final Block block) {
@JRubyMethod(name = "one?", optional = 1)
public static IRubyObject one_p(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;
final boolean[] result = new boolean[] { false };
final IRubyObject pattern = (args.length > 0) ? args[0] : null;
final boolean patternGiven = pattern != null;

try {
if (block.isGiven()) {
if (block.isGiven() && !patternGiven) {
callEach(runtime, context, self, block.getSignature(), new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "one?");
@@ -1630,20 +1645,37 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "one?");
IRubyObject larg = packEnumValues(runtime, largs);
if (larg.isTrue()) {
if (result[0]) {
throw JumpException.SPECIAL_JUMP;
} else {
result[0] = true;
if (patternGiven) {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "one?");
IRubyObject larg = packEnumValues(runtime, largs);
if (pattern.callMethod(ctx, "===", larg).isTrue()) {
if (result[0]) {
throw JumpException.SPECIAL_JUMP;
} else {
result[0] = true;
}
}
return runtime.getNil();
}
return runtime.getNil();
}
});
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
checkContext(localContext, ctx, "one?");
IRubyObject larg = packEnumValues(runtime, largs);
if (larg.isTrue()) {
if (result[0]) {
throw JumpException.SPECIAL_JUMP;
} else {
result[0] = true;
}
}
return runtime.getNil();
}
});
}
}
} catch (JumpException.SpecialJump sj) {
return runtime.getFalse();
@@ -1653,7 +1685,7 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {

@Deprecated
public static IRubyObject one_p19(ThreadContext context, IRubyObject self, final Block block) {
return one_p(context, self, block);
return one_p(context, self, new IRubyObject[]{}, block);
}

@Deprecated
@@ -1699,28 +1731,30 @@ public IRubyObject call(ThreadContext ctx, IRubyObject[] largs, Block blk) {
return result[0] ? runtime.getTrue() : runtime.getFalse();
}

@JRubyMethod(name = "all?")
public static IRubyObject all_p(ThreadContext context, IRubyObject self, final Block block) {
if (self instanceof RubyArray) return ((RubyArray) self).all_p(context, block);
return all_pCommon(context, self, block);
@JRubyMethod(name = "all?", optional = 1)
public static IRubyObject all_p(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block block) {
if (self instanceof RubyArray) return ((RubyArray) self).all_p(context, args, block);
return all_pCommon(context, self, args, block);
}

@Deprecated
public static IRubyObject all_p19(ThreadContext context, IRubyObject self, final Block block) {
return all_p(context, self, block);
return all_p(context, self, new IRubyObject[]{}, block);
}

@Deprecated
public static IRubyObject all_pCommon(final ThreadContext context, IRubyObject self, final Block block, Arity callbackArity) {
return all_pCommon(context, self, block);
return all_pCommon(context, self, new IRubyObject[]{}, block);
}

public static IRubyObject all_pCommon(ThreadContext context, IRubyObject self, final Block block) {
public static IRubyObject all_pCommon(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block block) {
final Ruby runtime = context.runtime;
final ThreadContext localContext = context;
final IRubyObject pattern = args.length > 0 ? args[0] : null;
final boolean patternGiven = pattern != null;

try {
if (block.isGiven()) {
if (block.isGiven() && !patternGiven) {
callEach(runtime, context, self, block.getSignature(), new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "all?");
@@ -1732,16 +1766,29 @@ public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!larg.isTrue()) {
throw JumpException.SPECIAL_JUMP;
if (patternGiven) {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!pattern.callMethod(context, "===", larg).isTrue()) {
throw JumpException.SPECIAL_JUMP;
}
return context.nil;
}
return context.nil;
}
});
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "all?");
IRubyObject larg = packEnumValues(runtime, largs);
if (!larg.isTrue()) {
throw JumpException.SPECIAL_JUMP;
}
return context.nil;
}
});
}
}
} catch (JumpException.SpecialJump sj) {
return runtime.getFalse();
@@ -1750,36 +1797,52 @@ public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
return runtime.getTrue();
}

@JRubyMethod(name = "any?")
public static IRubyObject any_p(ThreadContext context, IRubyObject self, final Block block) {
return any_pCommon(context, self, block);
@JRubyMethod(name = "any?", optional = 1)
public static IRubyObject any_p(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block block) {
return any_pCommon(context, self, args, block);
}

@Deprecated
public static IRubyObject any_pCommon(ThreadContext context, IRubyObject self, final Block block, Arity callbackArity) {
return any_pCommon(context, self, block);
return any_pCommon(context, self, new IRubyObject[]{}, block);
}

public static IRubyObject any_pCommon(ThreadContext context, IRubyObject self, final Block block) {
public static IRubyObject any_pCommon(ThreadContext context, IRubyObject self, IRubyObject[] args, final Block block) {
final Ruby runtime = context.runtime;
final IRubyObject pattern = (args.length > 0) ? args[0] : null;
final boolean patternGiven = pattern != null;
final ThreadContext localContext = context;

try {
if (block.isGiven()) {
each(context, self, new JavaInternalBlockBody(runtime, context, "Enumerable#any?", block.getSignature()) {
public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
IRubyObject packedArg = packEnumValues(context, args);
if (block.yield(context, packedArg).isTrue()) throw JumpException.SPECIAL_JUMP;
if (block.isGiven() && !patternGiven) {
callEach(runtime, context, self, block.getSignature(), new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "any?");
IRubyObject larg = packEnumValues(runtime, largs);
if (block.yield(context, larg).isTrue()) throw JumpException.SPECIAL_JUMP;
return context.nil;
}
});
} else {
each(context, self, new JavaInternalBlockBody(runtime, context, "Enumerable#any?", Signature.ONE_REQUIRED) {
public IRubyObject yield(ThreadContext context, IRubyObject[] args) {
IRubyObject packedArg = packEnumValues(context.runtime, args);
if (packedArg.isTrue()) throw JumpException.SPECIAL_JUMP;
return context.nil;
}
});
if (patternGiven) {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "any?");
IRubyObject larg = packEnumValues(runtime, largs);
if (pattern.callMethod(context, "===", larg).isTrue()) throw JumpException.SPECIAL_JUMP;
return context.nil;
}
});
} else {
callEach(runtime, context, self, Signature.ONE_REQUIRED, new BlockCallback() {
public IRubyObject call(ThreadContext context, IRubyObject[] largs, Block blk) {
checkContext(localContext, context, "any?");
IRubyObject larg = packEnumValues(runtime, largs);
if (larg.isTrue()) throw JumpException.SPECIAL_JUMP;
return context.nil;
}
});
}
}
} catch (JumpException.SpecialJump sj) {
return runtime.getTrue();
24 changes: 21 additions & 3 deletions core/src/main/java/org/jruby/RubyHash.java
Original file line number Diff line number Diff line change
@@ -2055,11 +2055,15 @@ public IRubyObject rbClone(ThreadContext context) {
return clone;
}

@JRubyMethod(name = "any?")
public IRubyObject any_p(ThreadContext context, Block block) {
@JRubyMethod(name = "any?", optional = 1)
public IRubyObject any_p(ThreadContext context, IRubyObject[] args, Block block) {
IRubyObject pattern = args.length > 0 ? args[0] : null;
boolean patternGiven = pattern != null;

if (isEmpty()) return context.runtime.getFalse();

if (!block.isGiven()) return context.runtime.getTrue();
if (!block.isGiven() && !patternGiven) return context.runtime.getTrue();
if (patternGiven) return any_p_p(context, pattern);

if (block.getSignature().arityValue() > 1) {
return any_p_i_fast(context, block);
@@ -2094,6 +2098,20 @@ private IRubyObject any_p_i_fast(ThreadContext context, Block block) {
}
}

private IRubyObject any_p_p(ThreadContext context, IRubyObject pattern) {
iteratorEntry();
try {
for (RubyHashEntry entry = head.nextAdded; entry != head; entry = entry.nextAdded) {
IRubyObject newAssoc = RubyArray.newArray(context.runtime, entry.key, entry.value);
if (pattern.callMethod(context, "===", newAssoc).isTrue())
return context.runtime.getTrue();
}
return context.runtime.getFalse();
} finally {
iteratorExit();
}
}

/**
* A lightweight dup for internal use that does not dispatch to initialize_copy nor rehash the keys. Intended for
* use in dup'ing keyword args for processing.
Loading