Method: Proc#ruby2_keywords
- Defined in:
- proc.c
#ruby2_keywords ⇒ Proc
Marks the proc as passing keywords through a normal argument splat. This should only be called on procs that accept an argument splat (*args
) but not explicit keywords or a keyword splat. It marks the proc such that if the proc is called with keyword arguments, the final hash argument is marked with a special flag such that if it is the final element of a normal argument splat to another method call, and that method call does not include explicit keywords or a keyword splat, the final element is interpreted as keywords. In other words, keywords will be passed through the proc to other methods.
This should only be used for procs that delegate keywords to another method, and only for backwards compatibility with Ruby versions before 2.7.
This method will probably be removed at some point, as it exists only for backwards compatibility. As it does not exist in Ruby versions before 2.7, check that the proc responds to this method before calling it. Also, be aware that if this method is removed, the behavior of the proc will change so that it does not pass through keywords.
module Mod
foo = ->(meth, *args, &block) do
send(:"do_#{meth}", *args, &block)
end
foo.ruby2_keywords if foo.respond_to?(:ruby2_keywords)
end
3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 |
# File 'proc.c', line 3941
static VALUE
proc_ruby2_keywords(VALUE procval)
{
rb_proc_t *proc;
GetProcPtr(procval, proc);
rb_check_frozen(procval);
if (proc->is_from_method) {
rb_warn("Skipping set of ruby2_keywords flag for proc (proc created from method)");
return procval;
}
switch (proc->block.type) {
case block_type_iseq:
if (ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_rest &&
!ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_kw &&
!ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.has_kwrest) {
ISEQ_BODY(proc->block.as.captured.code.iseq)->param.flags.ruby2_keywords = 1;
}
else {
rb_warn("Skipping set of ruby2_keywords flag for proc (proc accepts keywords or proc does not accept argument splat)");
}
break;
default:
rb_warn("Skipping set of ruby2_keywords flag for proc (proc not defined in Ruby)");
break;
}
return procval;
}
|