Skip to content

Commit 4c00e56

Browse files
committed
Use same logic as IR for kwarg handling in IO#write
When passing kwargs from a ruby2_keywords method to a core "real keywords" method, we lose the keywordiness of the incoming hash and raise an argument error for the arity mismatch. By using the same logic as IR here, we properly handle the incoming r2k hash. This same patch could be applied generally to all core methods that accept keywords, but given the rarity of r2k to core "real keywords" methods we have chosen to only do targeted fixes. This reduces the potential impact (versus a new, more general solution) and the required work (9.4.10 is eagerly awaited). We will explore more reliable, general improvements to core method kwarg handling in JRuby 10. Fixes #8398.
1 parent 5f77c63 commit 4c00e56

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

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

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import org.jruby.exceptions.RaiseException;
7474
import org.jruby.ext.fcntl.FcntlLibrary;
7575
import org.jruby.internal.runtime.ThreadedRunnable;
76+
import org.jruby.ir.runtime.IRRuntimeHelpers;
7677
import org.jruby.platform.Platform;
7778
import org.jruby.runtime.Arity;
7879
import org.jruby.runtime.Block;
@@ -4292,21 +4293,24 @@ public static IRubyObject write(ThreadContext context, IRubyObject recv, IRubyOb
42924293

42934294
// MRI: io_s_write
42944295
public static IRubyObject ioStaticWrite(ThreadContext context, IRubyObject recv, IRubyObject[] argv, boolean binary) {
4295-
boolean keywords = hasKeywords(ThreadContext.resetCallInfo(context));
4296+
IRubyObject keywords = IRRuntimeHelpers.receiveKeywords(context, argv, false, true, false);
42964297
final Ruby runtime = context.runtime;
42974298
IRubyObject string, offset, opt;
42984299
string = offset = opt = context.nil;
42994300

43004301
switch (argv.length) {
43014302
case 4:
4302-
if (!keywords) throw runtime.newArgumentError(argv.length, 2, 3);
4303-
opt = argv[3].convertToHash();
4303+
if (!(keywords instanceof RubyHash)) throw runtime.newArgumentError(argv.length, 2, 3);
4304+
opt = keywords;
43044305
offset = argv[2];
43054306
string = argv[1];
43064307
break;
43074308
case 3:
4308-
opt = TypeConverter.checkHashType(runtime, argv[2]);
4309-
if (opt.isNil()) offset = argv[2];
4309+
if (keywords instanceof RubyHash) {
4310+
opt = keywords;
4311+
} else {
4312+
offset = argv[2];
4313+
}
43104314
string = argv[1];
43114315
break;
43124316
case 2:

0 commit comments

Comments
 (0)