summaryrefslogtreecommitdiff
path: root/vm_method.c
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2019-09-18 12:08:14 -0700
committerJeremy Evans <code@jeremyevans.net>2019-09-20 07:45:11 -0700
commit27b67468724dc48ed8305d8cb33484a4af98fc05 (patch)
treeed3a664dc2f2a7f729894a3d253171ce19b7f25b /vm_method.c
parente81a3e6df54842b5a836dad7055a4295cf4155bc (diff)
Make passing empty keywords to dig pass empty keywords to next dig method
If defined in Ruby, dig would be defined as def dig(arg, *rest) end, it would not use keywords. If the last dig argument was an empty hash, it could be treated as keyword arguments by the next dig method. Allow dig to pass along the empty keyword flag if called with an empty keyword, to suppress the previous behavior and force treating the hash as a positional argument and not keywords. Also handle the case where dig calls method_missing, passing the empty keyword flag to that as well. This requires adding rb_check_funcall_with_hook_kw functions, so that dig can specify how arguments are treated. It also adds kw_splat arguments to a couple static functions.
Diffstat (limited to 'vm_method.c')
-rw-r--r--vm_method.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/vm_method.c b/vm_method.c
index 7421bc96c2..63dc73f94b 100644
--- a/vm_method.c
+++ b/vm_method.c
@@ -1916,12 +1916,14 @@ rb_method_basic_definition_p(VALUE klass, ID id)
static VALUE
call_method_entry(rb_execution_context_t *ec, VALUE defined_class, VALUE obj, ID id,
- const rb_method_entry_t *me, int argc, const VALUE *argv)
+ const rb_method_entry_t *me, int argc, const VALUE *argv, int kw_splat)
{
const rb_callable_method_entry_t *cme =
- prepare_callable_method_entry(defined_class, id, me);
+ prepare_callable_method_entry(defined_class, id, me);
VALUE passed_block_handler = vm_passed_block_handler(ec);
- VALUE result = rb_vm_call0(ec, obj, id, argc, argv, cme, VM_NO_KEYWORDS);
+ VALUE v = rb_adjust_argv_kw_splat(&argc, &argv, &kw_splat);
+ VALUE result = rb_vm_call0(ec, obj, id, argc, argv, cme, kw_splat);
+ rb_free_tmp_buffer(&v);
vm_passed_block_handler_set(ec, passed_block_handler);
return result;
}
@@ -1938,7 +1940,7 @@ basic_obj_respond_to_missing(rb_execution_context_t *ec, VALUE klass, VALUE obj,
if (!me || METHOD_ENTRY_BASIC(me)) return Qundef;
args[0] = mid;
args[1] = priv;
- return call_method_entry(ec, defined_class, obj, rtmid, me, 2, args);
+ return call_method_entry(ec, defined_class, obj, rtmid, me, 2, args, RB_NO_KEYWORDS);
}
static inline int
@@ -2005,7 +2007,7 @@ vm_respond_to(rb_execution_context_t *ec, VALUE klass, VALUE obj, ID id, int pri
}
}
}
- result = call_method_entry(ec, defined_class, obj, resid, me, argc, args);
+ result = call_method_entry(ec, defined_class, obj, resid, me, argc, args, RB_NO_KEYWORDS);
return RTEST(result);
}
}