From: ko1@... Date: 2014-10-23T00:56:44+00:00 Subject: [ruby-core:65861] [ruby-trunk - Bug #10413] [Open] Unexpected block invocation with unknown keywords Issue #10413 has been updated by Koichi Sasada. Status changed from Closed to Open How about to change rb_hash_delete()? Nobody expect rb_hash_delete() invoke a passed block. ``` Index: hash.c =================================================================== --- hash.c (revision 48083) +++ hash.c (working copy) @@ -972,8 +972,8 @@ rb_hash_index(VALUE hash, VALUE value) return rb_hash_key(hash, value); } -static VALUE -rb_hash_delete_key(VALUE hash, VALUE key) +VALUE +rb_hash_delete(VALUE hash, VALUE key) { st_data_t ktmp = (st_data_t)key, val; @@ -1008,13 +1008,13 @@ rb_hash_delete_key(VALUE hash, VALUE key * */ -VALUE -rb_hash_delete(VALUE hash, VALUE key) +static VALUE +rb_hash_delete_m(VALUE hash, VALUE key) { VALUE val; rb_hash_modify_check(hash); - val = rb_hash_delete_key(hash, key); + val = rb_hash_delete(hash, key); if (val != Qundef) return val; if (rb_block_given_p()) { return rb_yield(key); @@ -1066,7 +1066,7 @@ rb_hash_shift(VALUE hash) else { rb_hash_foreach(hash, shift_i_safe, (VALUE)&var); if (var.key != Qundef) { - rb_hash_delete_key(hash, var.key); + rb_hash_delete(hash, var.key); return rb_assoc_new(var.key, var.val); } } @@ -3881,7 +3881,7 @@ Init_Hash(void) rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1); rb_define_method(rb_cHash,"shift", rb_hash_shift, 0); - rb_define_method(rb_cHash,"delete", rb_hash_delete, 1); + rb_define_method(rb_cHash,"delete", rb_hash_delete_m, 1); rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0); rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0); rb_define_method(rb_cHash,"select", rb_hash_select, 0); ``` ---------------------------------------- Bug #10413: Unexpected block invocation with unknown keywords https://bugs.ruby-lang.org/issues/10413#change-49596 * Author: Koichi Sasada * Status: Open * Priority: Normal * Assignee: Koichi Sasada * Category: core * Target version: current: 2.2.0 * ruby -v: 2.2dev * Backport: 2.0.0: REQUIRED, 2.1: REQUIRED ---------------------------------------- When unknown keywords are passed, unexpected block is invoked. ```ruby def bar(k2: 'v2') end def foo bar(k1: 1) end foo(){ puts caller_locations raise "unreachable" } ``` current behavior: ``` ruby 2.2.0dev (2014-10-22 trunk 48083) [i386-mswin32_110] test.rb:10:in `block in
': unreachable (RuntimeError) from test.rb:5:in `foo' from test.rb:8:in `
' test.rb:5:in `foo' test.rb:8:in `
' ``` expected: ``` ../../gitruby/test.rb:5:in `foo': unknown keyword: k1 (ArgumentError) from ../../gitruby/test.rb:8:in `
' ``` This strange behavior is because "unknown_keyword_error" in class.c calls rb_hash_delete() (Hash#delete) with :k1 and invoke passed block. I'm now re-writing all of this part and my branch does not have this problem. However, Ruby 2.0 and 2.1 have same problem. -- https://bugs.ruby-lang.org/