summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--object.c13
-rw-r--r--test/ruby/test_array.rb3
-rw-r--r--test/ruby/test_hash.rb3
4 files changed, 21 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e683c73c9..24c6511623 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Dec 12 18:52:26 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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@ruby-lang.org>
* test/ruby/test_regexp.rb: Add test cases for `$KCODE` and `$=` warning
diff --git a/object.c b/object.c
index 1f73cb401b..3111701c58 100644
--- a/object.c
+++ b/object.c
@@ -3169,12 +3169,22 @@ dig_basic_p(VALUE obj, struct dig_method *cache)
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 obj, VALUE notfound)
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;
}
diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb
index 0922cb4c65..d2af339a11 100644
--- a/test/ruby/test_array.rb
+++ b/test/ruby/test_array.rb
@@ -2654,7 +2654,8 @@ class TestArray < Test::Unit::TestCase
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
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index c08908fa76..01990618fb 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -1305,7 +1305,8 @@ class TestHash < Test::Unit::TestCase
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}