Методы Dig
Методы dig в Ruby полезны для доступа к вложенным структурам данных.
Рассмотрим эти данные:
item = {
id: "0001",
type: "donut",
name: "Cake",
ppu: 0.55,
batters: {
batter: [
{id: "1001", type: "Regular"},
{id: "1002", type: "Chocolate"},
{id: "1003", type: "Blueberry"},
{id: "1004", type: "Devil's Food"}
]
},
topping: [
{id: "5001", type: "None"},
{id: "5002", type: "Glazed"},
{id: "5005", type: "Sugar"},
{id: "5007", type: "Powdered Sugar"},
{id: "5006", type: "Chocolate with Sprinkles"},
{id: "5003", type: "Chocolate"},
{id: "5004", type: "Maple"}
]
}
Без метода dig, вы можете написать:
item[:batters][:batter][1][:type] # => "Chocolate"
С методом dig, вы можете написать:
item.dig(:batters, :batter, 1, :type) # => "Chocolate"
Без метода dig, вы можете написать (ошибочно, вызывает NoMethodError (undefined method `[]' for nil:NilClass)):
item[:batters][:BATTER][1][:type]
С методом dig, вы можете написать (по-прежнему с ошибкой, но избегая исключения):
item.dig(:batters, :BATTER, 1, :type) # => nil
Почему метод dig лучше?
-
В нём меньше синтаксических элементов (чтобы не ошибиться).
-
Он лучше читается.
-
Он не генерирует исключение, если элемент не найден.
Как работает метод dig?
Последовательность вызовов:
obj.dig(*identifiers)
Методы identifiers определяют «путь» в вложенные структуры данных:
-
Для каждого идентификатора в
identifiers, вызывается метод #dig над получателем с этим идентификатором. -
Первый получатель —
self. -
Каждый последующий получатель — значение, возвращаемое предыдущим вызовом
dig. -
В конечном итоге возвращаемое значение — значение, возвращённое последним вызовом
dig.
Метод dig генерирует исключение, если какой-либо получатель не отвечает на вызов #dig:
h = { foo: 1 }
# Raises TypeError (Integer does not have #dig method):
h.dig(:foo, :bar)
Что ещё?
В структуре выше есть объекты Hash и Array, оба из которых имеют метод dig.
В целом, существует шесть встроенных классов Ruby, имеющих метод dig, три в основных классах и три в стандартной библиотеке.
В основных классах:
-
Array#dig: первый аргумент — целочисленный индекс. -
Hash#dig: первый аргумент — ключ. -
Struct#dig: первый аргумент — ключ.
В стандартной библиотеке:
-
OpenStruct#dig: первый аргумент — строковое имя. -
CSV::Table#dig: первый аргумент — целочисленный индекс или строковый заголовок. -
CSV::Row#dig: первый аргумент — целочисленный индекс или строковый заголовок.
Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.