dig
- не единственный метод, а семейство из четырех методов, каждый из которых дебютировал в Ruby v2.3: Array # dig , Hash # dig , Struct # dig и OpenStruct # dig .
Например,
h = { a: [1, { c: 2, d: 3 }], b: 2 }
h.dig(:a, 1, :d)
#=> 3
использует Hash#dig
, поскольку получатель dig
является хэшем.Более того, можно ожидать, что когда в промежуточном расчете dig
раскопал [1, { c: 2, d: 3 }]
, он передаст лопату в Array#dig
для дальнейших раскопок.
Предположим,
h = { a: [1, 2] }
Тогда
h.dig(:a, 1) #=> 2
h.dig(:a).dig(1) #=> 2
Означает ли это, что два эквивалентны?Попробуйте это:
h.dig('cat', 1) #=> nil
h.dig('cat').dig(1) #=> NoMethodError: undefined method `dig' for nil:NilClass
Исключение связано с тем, что h.dig('cat') #=> nil
и NilClass не имеют метода экземпляра dig
, поэтому nil.dig(1)
вызывает исключение.Нет, два выражения не эквивалентны.
Если значение переменной result
является хэшем OP, мы имеем (как указано @Isaiah) следующее.
result.dig(:result, :'1', 0, :"5", :"1", :"1")
#=> "1.0.0"
result.dig(:result, :'1', 0, :cat, :"1", :"1")
#=> nil
Обратите внимание, что dig
будет вызывать исключение, если используется неправильный тип данных:
[1, 2].dig(:a)
#=> TypeError: no implicit conversion of Symbol into Integer
Для поддержки версий Ruby до 2.3 (где dig
недоступно) мы можем написать следующее, используя Enumerable # уменьшите (он же inject
).
arr = [:result, :'1', 0, :"5", :"1", :"1"]
arr.reduce(result) { |memo, obj| memo && memo[obj] }
#=> "1.0.0"
arr = [:result, :'1', 0, :cat, :"1", :"1"]
arr.reduce(result) { |memo, obj| memo && memo[obj] }
#=> nil