ruby-changes:40979
From: nobu <ko1@a...>
Date: Sat, 12 Dec 2015 18:52:49 +0900 (JST)
Subject: [ruby-changes:40979] nobu:r53058 (trunk): object.c: raise TypeError
nobu 2015-12-12 18:52:36 +0900 (Sat, 12 Dec 2015) New Revision: 53058 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53058 Log: object.c: raise TypeError * object.c (rb_obj_dig): raise TypeError if an element does not have #dig method. [ruby-core:71798] [Bug #11762] Modified files: trunk/ChangeLog trunk/object.c trunk/test/ruby/test_array.rb trunk/test/ruby/test_hash.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 53057) +++ ChangeLog (revision 53058) @@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat Dec 12 18:52:26 2015 Nobuyoshi Nakada <nobu@r...> + + * object.c (rb_obj_dig): raise TypeError if an element does not + have #dig method. [ruby-core:71798] [Bug #11762] + Sat Dec 12 17:59:07 2015 Yuichiro Kaneko <yui-knk@r...> * test/ruby/test_regexp.rb: Add test cases for `$KCODE` and `$=` warning Index: object.c =================================================================== --- object.c (revision 53057) +++ object.c (revision 53058) @@ -3169,12 +3169,22 @@ dig_basic_p(VALUE obj, struct dig_method https://github.com/ruby/ruby/blob/trunk/object.c#L3169 return cache->basic; } +static void +no_dig_method(int found, VALUE recv, ID mid, int argc, const VALUE *argv, VALUE data) +{ + if (!found) { + rb_raise(rb_eTypeError, "%"PRIsVALUE" does not have #dig method", + CLASS_OF(data)); + } +} + VALUE rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound) { struct dig_method hash = {Qnil}, ary = {Qnil}, strt = {Qnil}; for (; argc > 0; ++argv, --argc) { + if (NIL_P(obj)) return notfound; if (!SPECIAL_CONST_P(obj)) { switch (BUILTIN_TYPE(obj)) { case T_HASH: @@ -3197,7 +3207,8 @@ rb_obj_dig(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/object.c#L3207 break; } } - return rb_check_funcall_default(obj, id_dig, argc, argv, notfound); + return rb_check_funcall_with_hook(obj, id_dig, argc, argv, + no_dig_method, obj); } return obj; } Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 53057) +++ test/ruby/test_array.rb (revision 53058) @@ -2654,7 +2654,8 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L2654 def test_dig h = @cls[@cls[{a: 1}], 0] assert_equal(1, h.dig(0, 0, :a)) - assert_nil(h.dig(1, 0)) + assert_nil(h.dig(2, 0)) + assert_raise(TypeError) {h.dig(1, 0)} end private Index: test/ruby/test_hash.rb =================================================================== --- test/ruby/test_hash.rb (revision 53057) +++ test/ruby/test_hash.rb (revision 53058) @@ -1305,7 +1305,8 @@ class TestHash < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_hash.rb#L1305 def test_dig h = @cls[a: @cls[b: [1, 2, 3]], c: 4] assert_equal(1, h.dig(:a, :b, 0)) - assert_nil(h.dig(:c, 1)) + assert_nil(h.dig(:b, 1)) + assert_raise(TypeError) {h.dig(:c, 1)} o = Object.new def o.dig(*args) {dug: args} -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/