diff options
author | Jeremy Evans <[email protected]> | 2019-08-27 18:38:48 -0700 |
---|---|---|
committer | Jeremy Evans <[email protected]> | 2022-03-17 11:52:02 -0700 |
commit | b6804d62f822237e136e698e006c913df9990ec2 (patch) | |
tree | 49fb54048952f0ccd8a1e026c28688b025b68be3 /proc.c | |
parent | 29b68b89a0c0ea7de46c058fab746550398151f0 (diff) |
Make Proc#parameters support lambda keyword for returning parameters as if lambda
This makes it easier to use Proc#parameters to build wrappers.
Implements [Feature #15357]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/5677
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 39 |
1 files changed, 33 insertions, 6 deletions
@@ -1415,19 +1415,46 @@ rb_unnamed_parameters(int arity) /* * call-seq: - * prc.parameters -> array + * prc.parameters(lambda: nil) -> array * - * Returns the parameter information of this proc. + * Returns the parameter information of this proc. If the lambda + * keyword is provided and not nil, treats the proc as a lambda if + * true and as a non-lambda if false. * + * prc = proc{|x, y=42, *other|} + * prc.parameters #=> [[:opt, :x], [:opt, :y], [:rest, :other]] * prc = lambda{|x, y=42, *other|} * prc.parameters #=> [[:req, :x], [:opt, :y], [:rest, :other]] + * prc = proc{|x, y=42, *other|} + * prc.parameters(lambda: true) #=> [[:req, :x], [:opt, :y], [:rest, :other]] + * prc = lambda{|x, y=42, *other|} + * prc.parameters(lamdba: false) #=> [[:opt, :x], [:opt, :y], [:rest, :other]] */ static VALUE -rb_proc_parameters(VALUE self) +rb_proc_parameters(int argc, VALUE *argv, VALUE self) { - int is_proc; - const rb_iseq_t *iseq = rb_proc_get_iseq(self, &is_proc); + static ID keyword_ids[1]; + VALUE opt, lambda; + VALUE kwargs[1]; + int is_proc ; + const rb_iseq_t *iseq; + + iseq = rb_proc_get_iseq(self, &is_proc); + + if (!keyword_ids[0]) { + CONST_ID(keyword_ids[0], "lambda"); + } + + rb_scan_args(argc, argv, "0:", &opt); + if (!NIL_P(opt)) { + rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs); + lambda = kwargs[0]; + if (!NIL_P(lambda)) { + is_proc = !RTEST(lambda); + } + } + if (!iseq) { return rb_unnamed_parameters(rb_proc_arity(self)); } @@ -4248,7 +4275,7 @@ Init_Proc(void) rb_define_method(rb_cProc, "==", proc_eq, 1); rb_define_method(rb_cProc, "eql?", proc_eq, 1); rb_define_method(rb_cProc, "source_location", rb_proc_location, 0); - rb_define_method(rb_cProc, "parameters", rb_proc_parameters, 0); + rb_define_method(rb_cProc, "parameters", rb_proc_parameters, -1); rb_define_method(rb_cProc, "ruby2_keywords", proc_ruby2_keywords, 0); // rb_define_method(rb_cProc, "isolate", rb_proc_isolate, 0); is not accepted. |