diff --git a/array.c b/array.c
index 159dc8f..22b53f6 100644
--- a/array.c
+++ b/array.c
@@ -5533,15 +5533,25 @@ rb_ary_any_p(VALUE ary)
/*
* call-seq:
- * ary.dig(idx, ...) -> object
+ * ary.dig(index, indexes...) -> object
*
- * Extracts the nested array value specified by the sequence of idx
- * objects.
+ * Extracts a nested value by navigating the given +index+
+ * (and indexes, recursively). This is useful for navigating
+ * parsed JSON or other nested data. Nested data may be any
+ * object that implements the +dig+ method.
*
- * a = [[1, [2, 3]]]
+ * Returns the nested value, or nil if an index/key is not found
+ * at any level, or if a nested key navigates to an object that
+ * does not implement +dig+. Does not raise exceptions.
*
- * a.dig(0, 1, 1) #=> 3
- * a.dig(0, 0, 0) #=> nil
+ * ary = [[:A, [:B, {first: "Pat", last: "Jones"}]]
+ *
+ * ary.dig(0, 1, 0) #=> :B
+ * ary.dig(0, 0, 0) #=> nil
+ * ary.dig(0, 1, :first) #=> nil
+ * ary.dig(0, 1, 1, :first) #=> "Pat"
+ *
+ * See Hash#dig for more information.
*/
VALUE
diff --git a/hash.c b/hash.c
index 717a548..9d82b2c 100644
--- a/hash.c
+++ b/hash.c
@@ -2693,15 +2693,53 @@ rb_hash_any_p(VALUE hash)
/*
* call-seq:
- * hsh.dig(key, ...) -> object
+ * hsh.dig(key, keys...) -> object
*
- * Extracts the nested hash value specified by the sequence of key
- * objects.
+ * Extracts a nested value by navigating the given +key+
+ * (and keys, recursively). This is useful for navigating
+ * parsed JSON or other nested data. Nested data may be any
+ * object that implements the +dig+ method.
*
- * h = { foo: {bar: {baz: 1}}}
+ * Calls the +[]+ operator to look up the key so that
+ * subclasses may provide their own implementation.
*
- * h.dig(:foo, :bar, :baz) #=> 1
- * h.dig(:foo, :zot) #=> nil
+ * Returns the nested value, or nil if a key is not found
+ * at any level, or if a nested key navigates to an object that
+ * does not implement +dig+. Does not raise exceptions.
+ *
+ * == The dig Protocol
+ *
+ * The +dig+ method behaves like this at each level:
+ *
+ * def dig(key, *keys)
+ * value = self[key] rescue nil
+ * if keys.empty? || value.nil?
+ * value
+ * elsif value.respond_to?(:dig)
+ * value.dig(*keys)
+ * else
+ * nil
+ * end
+ * end
+ *
+ * == Example Usage
+ *
+ * Address = Struct.new(:street, :city, :state, :country)
+ *
+ * hash = {ceo: {name: "Pat", email: "pat@example.com"},
+ * managers: [
+ * {name: "Jose", email: "jose@example.com"},
+ * {name: "Sally", email: "sally@example.com"}
+ * {name: "Bob", email: "bob@example.com"}
+ * ],
+ * office: Address.new("9 Oak St", "New York", "NY", "USA")
+ * }
+ *
+ * hash.dig(:ceo, :name) #=> "Pat"
+ * hash.dig(:ceo, 0, :email) #=> nil
+ * hash.dig(:managers, 1, :name) #=> "Sally"
+ * hash.dig(:managers, :name) #=> nil
+ * hash.dig(:office, :city) #=> "New York"
*/
VALUE