Spec-Zone.ru › Ruby 4.0

Методы 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: первый аргумент — индекс типа Integer.

  • Hash#dig: первый аргумент — ключ.

  • Struct#dig: первый аргумент — ключ.

В стандартной библиотеке:

  • OpenStruct#dig: первый аргумент — имя типа String.

  • CSV::Table#dig: первый аргумент — индекс типа Integer или заголовок типа String.

  • CSV::Row#dig: первый аргумент — индекс типа Integer или заголовок типа String.

Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API