From: colin@... Date: 2015-12-08T04:03:04+00:00 Subject: [ruby-core:71935] [Ruby trunk - Bug #11762] Array#dig can raise TypeError: no implicit conversion of Symbol/String into Integer Issue #11762 has been updated by Colin Kelley. File 11762.patch added Here is my suggested documentation on how `Hash#dig` should behave as part of a general `dig` protocol. The patch includes equivalent changes to the documentation for `Array#dig`. ~~~ * 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. * * Calls the +[]+ operator to look up the key so that * subclasses may provide their own implementation. * * 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" ~~~ This example is designed to call attention to the common case where you intended to access a hash but an array was there: ~~~ * hash.dig(:managers, :name) #=> nil ~~~ I feel the `dig` method would be much less useful if a surprise as shown above were to raise an exception. (That would force a rescue wrapper. Furthermore, note that the exception would be of limited value since it would be ambiguous as to what level it occurred at.) ---------------------------------------- Bug #11762: Array#dig can raise TypeError: no implicit conversion of Symbol/String into Integer https://bugs.ruby-lang.org/issues/11762#change-55340 * Author: Colin Kelley * Status: Open * Priority: Normal * Assignee: Yukihiro Matsumoto * ruby -v: 2.3.0-preview1 * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN ---------------------------------------- If you try to `dig` in an Array using a symbol or string, a `TypeError` exception will be raised: irb> ['zero', 'one', 'two'].dig(:first) TypeError: no implicit conversion of Symbol into Integer from (irb):1:in `dig' from (irb):1 I think it should return `nil` in this case. The most typical use case for `dig` is to dig through parsed JSON and either find the result we expected or else `nil`. Wouldn't it defeat the purpose of `dig` if we had to wrap calls to it in a `rescue` to handle the case that an Array was present where we expected a Hash? Can we clarify the desired behavior for this case, then update the documentation and tests to reflect that? ---Files-------------------------------- 11762.patch (3.19 KB) -- https://bugs.ruby-lang.org/