Skip to content

Commit aafb40b

Browse files
headiusenebo
authored andcommitted
Fix coercion of arrays in Kernel#Array and Array#product.
Fixes #1961. Fixes #1962.
1 parent 51ed1b2 commit aafb40b

File tree

4 files changed

+34
-13
lines changed

4 files changed

+34
-13
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3542,7 +3542,7 @@ public IRubyObject product19(ThreadContext context, IRubyObject[] args, Block bl
35423542
int counters[] = new int[n];
35433543

35443544
arrays[0] = this;
3545-
for (int i = 1; i < n; i++) arrays[i] = args[i - 1].convertToArray();
3545+
for (int i = 1; i < n; i++) arrays[i] = TypeConverter.to_ary(context, args[i - 1]);
35463546

35473547
int resultLen = 1;
35483548
for (int i = 0; i < n; i++) {

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,11 +375,17 @@ public static IRubyObject abort(ThreadContext context, IRubyObject recv, IRubyOb
375375
return runtime.getNil(); // not reached
376376
}
377377

378-
@JRubyMethod(name = "Array", required = 1, module = true, visibility = PRIVATE)
379-
public static IRubyObject new_array(ThreadContext context, IRubyObject recv, IRubyObject object) {
378+
@JRubyMethod(name = "Array", required = 1, module = true, visibility = PRIVATE, compat = RUBY1_8)
379+
public static IRubyObject new_array18(ThreadContext context, IRubyObject recv, IRubyObject object) {
380380
return Helpers.asArray18(context, object);
381381
}
382382

383+
// MRI: rb_f_array
384+
@JRubyMethod(name = "Array", required = 1, module = true, visibility = PRIVATE, compat = RUBY1_9)
385+
public static IRubyObject new_array(ThreadContext context, IRubyObject recv, IRubyObject object) {
386+
return TypeConverter.rb_Array(context, object);
387+
}
388+
383389
@JRubyMethod(name = "Complex", module = true, visibility = PRIVATE, compat = RUBY1_9)
384390
public static IRubyObject new_complex(ThreadContext context, IRubyObject recv) {
385391
return Helpers.invoke(context, context.runtime.getComplex(), "convert");

core/src/main/java/org/jruby/runtime/Helpers.java

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1852,16 +1852,7 @@ public static RubyArray asArray18(ThreadContext context, IRubyObject value) {
18521852
// mri: rb_Array
18531853
// FIXME: Replace arrayValue/asArray18 with this on 9k (currently dead -- respond_to? logic broken further down the line -- fix that first)
18541854
public static RubyArray asArray(ThreadContext context, IRubyObject value) {
1855-
RubyClass array = context.runtime.getArray();
1856-
IRubyObject tmp = TypeConverter.convertToTypeWithCheck19(value, array, "to_ary");
1857-
1858-
if (tmp.isNil()) {
1859-
tmp = TypeConverter.convertToTypeWithCheck19(value, array, "to_a");
1860-
1861-
if (tmp.isNil()) return context.runtime.newEmptyArray();
1862-
}
1863-
1864-
return (RubyArray) tmp; // converters will guarantee it is RubyArray or raise.
1855+
return TypeConverter.rb_Array(context, value);
18651856
}
18661857

18671858
public static IRubyObject aryToAry(IRubyObject value) {

core/src/main/java/org/jruby/util/TypeConverter.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
package org.jruby.util;
2828

2929
import org.jruby.Ruby;
30+
import org.jruby.RubyArray;
3031
import org.jruby.RubyBignum;
3132
import org.jruby.RubyBoolean;
3233
import org.jruby.RubyClass;
@@ -283,6 +284,11 @@ public static IRubyObject checkStringType(Ruby runtime, IRubyObject obj) {
283284
return TypeConverter.convertToTypeWithCheck(obj, runtime.getHash(), "to_str");
284285
}
285286

287+
// MRI: rb_check_array_type
288+
public static IRubyObject checkArrayType(IRubyObject self) {
289+
return TypeConverter.convertToTypeWithCheck19(self, self.getRuntime().getArray(), "to_ary");
290+
}
291+
286292
public static IRubyObject handleUncoercibleObject(boolean raise, IRubyObject obj, RubyClass target) throws RaiseException {
287293
if (raise) throw obj.getRuntime().newTypeError("can't convert " + typeAsString(obj) + " into " + target);
288294

@@ -330,6 +336,24 @@ public static IRubyObject convertToInteger(ThreadContext context, IRubyObject va
330336
return tmp;
331337
}
332338

339+
// MRI: rb_Array
340+
public static RubyArray rb_Array(ThreadContext context, IRubyObject val) {
341+
IRubyObject tmp = checkArrayType(val);
342+
343+
if (tmp.isNil()) {
344+
tmp = convertToTypeWithCheck19(val, context.runtime.getArray(), "to_a");
345+
if (tmp.isNil()) {
346+
return context.runtime.newArray(val);
347+
}
348+
}
349+
return (RubyArray)tmp;
350+
}
351+
352+
// MRI: to_ary
353+
public static RubyArray to_ary(ThreadContext context, IRubyObject ary) {
354+
return (RubyArray)convertToType19(ary, context.runtime.getArray(), "to_ary");
355+
}
356+
333357
private static void raiseIntegerBaseError(ThreadContext context) {
334358
throw context.runtime.newArgumentError("base specified for non string value");
335359
}

0 commit comments

Comments
 (0)