¿Cómo uso `Array # dig` y` Hash # dig` introducidos en Ruby 2.3?

Ruby 2.3 introduce un nuevo método en Array y Hash llamado dig . Los ejemplos que he visto en publicaciones de blog sobre el nuevo lanzamiento están diseñados y enrevesados:

 # Hash#dig user = { user: { address: { street1: '123 Main street' } } } user.dig(:user, :address, :street1) # => '123 Main street' # Array#dig results = [[[1, 2, 3]]] results.dig(0, 0, 0) # => 1 

No estoy usando matrices planas de triple nested. ¿Cuál es un ejemplo realista de cómo esto sería útil?

ACTUALIZAR

Resulta que estos métodos resuelven una de las preguntas de Ruby más frecuentes. Las siguientes preguntas tienen algo así como 20 duplicados, todos los cuales se resuelven utilizando dig :

¿Cómo evitar NoMethodError para los elementos que faltan en hashes nesteds, sin repetidas comprobaciones nulas?

Ruby Style: cómo verificar si existe un elemento hash nested

En nuestro caso, los errores más comunes que vemos en nuestros entornos de producción son los errores de NoMethodError debido a que no tienen NoMethodError referencia.

El nuevo Hash#dig permite omitir cheques nil al acceder a elementos nesteds. Dado que los hashes se utilizan mejor cuando la estructura de los datos es desconocida, o volátil, tener mucho apoyo tiene soporte oficial para esto.

Tomemos tu ejemplo. El seguimiento:

 user.dig(:user, :address, :street1) 

No es equivalente a:

 user[:user][:address][:street1] 

En el caso de que el user[:user] o el user[:user][:address] sea nil , se producirá un error de tiempo de ejecución.

Más bien, es equivalente a lo siguiente, que es el idioma actual:

 user[:user] && user[:user][:address] && user[:user][:address][:street1] 

Observe cómo es trivial pasar una lista de símbolos que se creó en otro lugar en Hash#dig , mientras que no es muy sencillo recrear el último constructo a partir de dicha lista. Hash#dig permite hacer un acceso dynamic fácilmente sin tener que preocuparse por las referencias nil .

Claramente, Hash#dig es también mucho más corto.


Un punto importante a tener en cuenta es que Hash#dig devuelve nil si alguna de las claves resulta ser, lo que puede llevar a la misma clase de errores un paso por la línea, por lo que puede ser una buena idea proporcionar una por defecto sensible (Esta forma de proporcionar un objeto que siempre responde a los métodos esperados se denomina Patrón de objeto nulo ).

Nuevamente, en su ejemplo, una cadena vacía o algo como “N / A”, dependiendo de lo que tenga sentido:

 user.dig(:user, :address, :street1) || "" 

Una forma sería en conjunto con la lectura del operador splat de un modelo de documento desconocido.

 some_json = JSON.parse( '{"people": {"me": 6, ... } ...}' ) # => "{"people" => {"me" => 6, ... }, ... } a_bunch_of_args = response.data[:query] # => ["people", "me"] some_json.dig(*a_bunch_of_args) # => 6