diff options
author | Jeremy Evans <[email protected]> | 2019-10-04 12:51:57 -0700 |
---|---|---|
committer | Jeremy Evans <[email protected]> | 2020-01-02 18:40:45 -0800 |
commit | beae6cbf0fd8b6619e5212552de98022d4c4d4d4 (patch) | |
tree | a926f619ed39569df4e93ec31157acdb78796379 /enumerator.c | |
parent | 8ba261c7546e3cd12ff6870bb41dd0a0bee32ba8 (diff) |
Fully separate positional arguments and keyword arguments
This removes the warnings added in 2.7, and changes the behavior
so that a final positional hash is not treated as keywords or
vice-versa.
To handle the arg_setup_block splat case correctly with keyword
arguments, we need to check if we are taking a keyword hash.
That case didn't have a test, but it affects real-world code,
so add a test for it.
This removes rb_empty_keyword_given_p() and related code, as
that is not needed in Ruby 3. The empty keyword case is the
same as the no keyword case in Ruby 3.
This changes rb_scan_args to implement keyword argument
separation for C functions when the : character is used.
For backwards compatibility, it returns a duped hash.
This is a bad idea for performance, but not duping the hash
breaks at least Enumerator::ArithmeticSequence#inspect.
Instead of having RB_PASS_CALLED_KEYWORDS be a number,
simplify the code by just making it be rb_keyword_given_p().
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/2794
Diffstat (limited to 'enumerator.c')
-rw-r--r-- | enumerator.c | 14 |
1 files changed, 6 insertions, 8 deletions
diff --git a/enumerator.c b/enumerator.c index 790818064f..fa30a59819 100644 --- a/enumerator.c +++ b/enumerator.c @@ -384,8 +384,6 @@ enumerator_allocate(VALUE klass) return enum_obj; } -#define PASS_KW_SPLAT (rb_empty_keyword_given_p() ? RB_PASS_EMPTY_KEYWORDS : rb_keyword_given_p()) - static VALUE enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *argv, rb_enumerator_size_func *size_fn, VALUE size, int kw_splat) { @@ -480,7 +478,7 @@ enumerator_initialize(int argc, VALUE *argv, VALUE obj) meth = *argv++; --argc; } - kw_splat = PASS_KW_SPLAT; + kw_splat = rb_keyword_given_p(); } return enumerator_init(obj, recv, meth, argc, argv, 0, size, kw_splat); @@ -535,10 +533,10 @@ rb_enumeratorize_with_size(VALUE obj, VALUE meth, int argc, const VALUE *argv, r /* Similar effect as calling obj.to_enum, i.e. dispatching to either Kernel#to_enum vs Lazy#to_enum */ if (RTEST(rb_obj_is_kind_of(obj, rb_cLazy))) - return lazy_to_enum_i(obj, meth, argc, argv, size_fn, PASS_KW_SPLAT); + return lazy_to_enum_i(obj, meth, argc, argv, size_fn, rb_keyword_given_p()); else return enumerator_init(enumerator_allocate(rb_cEnumerator), - obj, meth, argc, argv, size_fn, Qnil, PASS_KW_SPLAT); + obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p()); } VALUE @@ -1892,7 +1890,7 @@ lazy_add_method(VALUE obj, int argc, VALUE *argv, VALUE args, VALUE memo, static VALUE enumerable_lazy(VALUE obj) { - VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size, PASS_KW_SPLAT); + VALUE result = lazy_to_enum_i(obj, sym_each, 0, 0, lazyenum_size, rb_keyword_given_p()); /* Qfalse indicates that the Enumerator::Lazy has no method name */ rb_ivar_set(result, id_method, Qfalse); return result; @@ -1940,7 +1938,7 @@ lazy_to_enum(int argc, VALUE *argv, VALUE self) if (RTEST((super_meth = rb_hash_aref(lazy_use_super_method, meth)))) { meth = super_meth; } - lazy = lazy_to_enum_i(self, meth, argc, argv, 0, PASS_KW_SPLAT); + lazy = lazy_to_enum_i(self, meth, argc, argv, 0, rb_keyword_given_p()); if (rb_block_given_p()) { enumerator_ptr(lazy)->size = rb_block_proc(); } @@ -3318,7 +3316,7 @@ rb_arith_seq_new(VALUE obj, VALUE meth, int argc, VALUE const *argv, VALUE beg, VALUE end, VALUE step, int excl) { VALUE aseq = enumerator_init(enumerator_allocate(rb_cArithSeq), - obj, meth, argc, argv, size_fn, Qnil, PASS_KW_SPLAT); + obj, meth, argc, argv, size_fn, Qnil, rb_keyword_given_p()); rb_ivar_set(aseq, id_begin, beg); rb_ivar_set(aseq, id_end, end); rb_ivar_set(aseq, id_step, step); |