Skip to content

Commit

Permalink
Convert kwarg arg via to_hash if not a hash. procs should not strip o…
Browse files Browse the repository at this point in the history
…ff kwargs arg during prepareArguments
  • Loading branch information
enebo committed Apr 8, 2015
1 parent 6196101 commit 4cdc6e9
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
11 changes: 9 additions & 2 deletions core/src/main/java/org/jruby/RubyProc.java
Expand Up @@ -36,6 +36,7 @@

import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.lexer.yacc.SimpleSourcePosition;
import org.jruby.parser.StaticScope;
Expand All @@ -44,7 +45,9 @@
import org.jruby.runtime.Block;
import org.jruby.runtime.BlockBody;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.CompiledIRBlockBody;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.IRBlockBody;
import org.jruby.runtime.InterpretedIRBlockBody;
import org.jruby.runtime.MethodBlock;
import org.jruby.runtime.ObjectAllocator;
Expand Down Expand Up @@ -266,9 +269,13 @@ public static IRubyObject[] prepareArgs(ThreadContext context, Block.Type type,
actual = args.length;
}

// fixed arity > 0 with mismatch needs a new args array
if (isFixed && required > 0 && required != actual) {
// FIXME: This code is horrible so I named it poorly. We add 1 if we have kwargs so we do not accidentally
// chomp it off of args array. Much of this logic needs to be encapsulated as part of our transition from
// Arity to Signature.
int fudge = blockBody instanceof IRBlockBody && ((IRBlockBody) blockBody).getSignature().kwargs() ? 1 : 0;

// fixed arity > 0 with mismatch needs a new args array
if (isFixed && required > 0 && required+fudge != actual) {
IRubyObject[] newArgs = Arrays.copyOf(args, required);

// pad with nil
Expand Down
10 changes: 9 additions & 1 deletion core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Expand Up @@ -544,7 +544,15 @@ public static RubyHash extractKwargsHash(Object[] args, int requiredArgsCount, b

Object lastArg = args[args.length - 1];

return !(lastArg instanceof RubyHash) ? null : (RubyHash) lastArg;
if (lastArg instanceof RubyHash) return (RubyHash) lastArg;

if (((IRubyObject) lastArg).respondsTo("to_hash")) {
lastArg = ((IRubyObject) lastArg).callMethod(((IRubyObject) lastArg).getRuntime().getCurrentContext(), "to_hash");

if (lastArg instanceof RubyHash) return (RubyHash) lastArg;
}

return null;
}

public static void checkForExtraUnwantedKeywordArgs(final ThreadContext context, RubyHash keywordArgs) {
Expand Down
3 changes: 1 addition & 2 deletions test/mri/excludes/TestKeywordArguments.rb
@@ -1,5 +1,4 @@
exclude :test_block_required_keyword, "needs investigation"
exclude :test_implicit_hash_conversion, "needs investigation"
exclude :test_implicit_hash_conversion, "JIT-only"
exclude :test_lambda, "JIT-only"
exclude :test_p6, "JIT-only"
exclude :test_required_keyword_with_reserved, "needs investigation"
Expand Down

0 comments on commit 4cdc6e9

Please sign in to comment.