mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Add a keyword-to-last-hash warning for some case of define_method method
and lambda. When define_method is a simple iseq (`define_method(:m) {|x| ... }`), passing keywords to it (`m(**kw)`) didn't print a warning.
This commit is contained in:
parent
dd83f7bf98
commit
55b96c5d2d
2 changed files with 79 additions and 25 deletions
|
@ -185,20 +185,42 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||
|
||||
f = -> { true }
|
||||
assert_equal(true, f[**{}])
|
||||
assert_raise(ArgumentError) { f[**kw] }
|
||||
assert_raise(ArgumentError) { f[**h] }
|
||||
assert_raise(ArgumentError) { f[a: 1] }
|
||||
assert_raise(ArgumentError) { f[**h2] }
|
||||
assert_raise(ArgumentError) { f[**h3] }
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { f[**kw] }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { f[**h] }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { f[a: 1] }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { f[**h2] }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { f[**h3] }
|
||||
end
|
||||
|
||||
f = ->(a) { a }
|
||||
assert_raise(ArgumentError) { f[**{}] }
|
||||
assert_equal(kw, f[**kw])
|
||||
assert_equal(h, f[**h])
|
||||
assert_equal(h, f[a: 1])
|
||||
assert_equal(h2, f[**h2])
|
||||
assert_equal(h3, f[**h3])
|
||||
assert_equal(h3, f[a: 1, **h2])
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(kw, f[**kw])
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h, f[**h])
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h, f[a: 1])
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h2, f[**h2])
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h3, f[**h3])
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h3, f[a: 1, **h2])
|
||||
end
|
||||
|
||||
f = ->(**x) { x }
|
||||
assert_equal(kw, f[**{}])
|
||||
|
@ -685,24 +707,48 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||
define_method(:m) { }
|
||||
end
|
||||
assert_nil(c.m(**{}))
|
||||
assert_raise(ArgumentError) { c.m(**kw) }
|
||||
assert_raise(ArgumentError) { c.m(**h) }
|
||||
assert_raise(ArgumentError) { c.m(a: 1) }
|
||||
assert_raise(ArgumentError) { c.m(**h2) }
|
||||
assert_raise(ArgumentError) { c.m(**h3) }
|
||||
assert_raise(ArgumentError) { c.m(a: 1, **h2) }
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { c.m(**kw) }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { c.m(**h) }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { c.m(a: 1) }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { c.m(**h2) }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { c.m(**h3) }
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_raise(ArgumentError) { c.m(a: 1, **h2) }
|
||||
end
|
||||
|
||||
c = Object.new
|
||||
class << c
|
||||
define_method(:m) {|arg| arg }
|
||||
end
|
||||
assert_raise(ArgumentError) { c.m(**{}) }
|
||||
assert_equal(kw, c.m(**kw))
|
||||
assert_equal(h, c.m(**h))
|
||||
assert_equal(h, c.m(a: 1))
|
||||
assert_equal(h2, c.m(**h2))
|
||||
assert_equal(h3, c.m(**h3))
|
||||
assert_equal(h3, c.m(a: 1, **h2))
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(kw, c.m(**kw))
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h, c.m(**h))
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h, c.m(a: 1))
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h2, c.m(**h2))
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h3, c.m(**h3))
|
||||
end
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal(h3, c.m(a: 1, **h2))
|
||||
end
|
||||
|
||||
c = Object.new
|
||||
class << c
|
||||
|
@ -1211,10 +1257,14 @@ class TestKeywordArguments < Test::Unit::TestCase
|
|||
|
||||
o = Object.new
|
||||
def o.to_hash() { a: 1 } end
|
||||
assert_equal({a: 1}, m1(**o) {|x| break x}, bug9898)
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal({a: 1}, m1(**o) {|x| break x}, bug9898)
|
||||
end
|
||||
o2 = Object.new
|
||||
def o2.to_hash() { b: 2 } end
|
||||
assert_equal({a: 1, b: 2}, m1(**o, **o2) {|x| break x}, bug9898)
|
||||
assert_warn(/The keyword argument is passed as the last hash parameter/m) do
|
||||
assert_equal({a: 1, b: 2}, m1(**o, **o2) {|x| break x}, bug9898)
|
||||
end
|
||||
end
|
||||
|
||||
def test_implicit_hash_conversion
|
||||
|
|
|
@ -2929,6 +2929,10 @@ vm_callee_setup_block_arg(rb_execution_context_t *ec, struct rb_calling_info *ca
|
|||
|
||||
CALLER_SETUP_ARG(cfp, calling, ci, 0); /* splat arg */
|
||||
|
||||
if (calling->kw_splat) {
|
||||
rb_warn_keyword_to_last_hash(calling, ci, iseq);
|
||||
}
|
||||
|
||||
if (arg_setup_type == arg_setup_block &&
|
||||
calling->argc == 1 &&
|
||||
iseq->body->param.flags.has_lead &&
|
||||
|
|
Loading…
Reference in a new issue