Jak używać Array # dig i Hash # dig wprowadzonych w Rubim 2.3?


Ruby 2.3 wprowadza nową metodę
Array
i
Hash
o nazwie
dig
. Przykłady, które widziałem na blogach o nowej wersji, są wymyślone i mylące:
# 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

Nie używam potrójnie zagnieżdżonych płaskich tablic. Jaki jest realistyczny przykład tego, jak mogłoby to być pomocne?

UPDATE

Okazuje się, że te metody rozwiązują jedno z najczęściej zadawanych pytań dotyczących Rubiego. Poniższe pytania mają około 20 duplikatów, z których wszystkie są rozwiązywane za pomocą
dig
:
Jak uniknąć NoMethodError w przypadku brakujących elementów w zagnieżdżonych hashach bez wielokrotnych sprawdzeń wartości null?
https://coderoad.ru/4371716/
Styl Ruby: Jak sprawdzić, czy istnieje element zagnieżdżony
https://coderoad.ru/1820451/
hash
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W naszym przypadku,
NoMethodError
z powodu odwołań
nil
są zdecydowanie najczęstszymi błędami, jakie widzimy w naszych środowiskach produkcyjnych.
Nowy parametr
Hash # dig
umożliwia pominięcie kontroli
nil
podczas uzyskiwania dostępu do zagnieżdżonych elementów. Ponieważ skrótów najlepiej używać, gdy struktura danych jest nieznana lub niestabilna, bardzo sensowne jest posiadanie oficjalnego wsparcia.
Weźmy twój przykład. Następujący:
user.dig(:user, :address, :street1)

Nie


równoważny:
user[:user][:address][:street1]

Jeśli
user [: user]
lub
user [: user] [: address]
ma wartość
nil
, spowoduje to błąd w czasie wykonywania.
Jest to raczej równoważne z następującym, które jest obecnym idiomem:
user[:user] && user[:user][:address] && user[:user][:address][:street1]

Zwróć uwagę, jak trywialne jest przekazanie listy symboli, które zostały utworzone gdzie indziej do
Hash # dig
, podczas gdy odtworzenie ostatniej konstrukcji z takiej listy nie jest łatwe.
Hash # dig
pozwala na łatwy dynamiczny dostęp bez martwienia się o linki
nil
. [/code]Oczywiście
Hash # dig
jest również znacznie krótszy.
Jedną ważną kwestią, na którą należy zwrócić uwagę, jest to, że
Hash # dig
sam zwraca
nil
, jeśli którykolwiek z kluczy okaże się taki, co może powodować tę samą klasę błędu, to jeden krok w dół, więc dobrym pomysłem może być podanie rozsądnej wartości domyślnej. (Ten sposób dostarczania obiektu, który zawsze spełnia oczekiwane metody, jest wywoływany

szablon obiektu
https://en.wikipedia.org/wiki/ ... 3Ruby
Null .)
W naszym przykładzie jest to pusty ciąg lub coś w rodzaju „Nie dotyczy”, w zależności od tego, co ma sens:
user.dig(:user, :address, :street1) || ""
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jednym ze sposobów jest połączenie z operatorem splat odczytującym dane z nieznanego modelu dokumentu.
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
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jest to przydatne do pracy z głęboko zagnieżdżonymi skrótami/tablicami, które mogą być na przykład tym, co otrzymujesz z wywołania API.

W teorii

oszczędza to mnóstwo kodu, który w przeciwnym razie sprawdzałby na każdym poziomie, czy istnieje inny poziom, bez którego ryzykujesz trwałymi błędami.

Na treningu

nadal możesz potrzebować dużo tego kodu, ponieważ
dig
nadal będzie generował błędy w niektórych przypadkach (na przykład, jeśli coś w łańcuchu jest obiektem niebędącym kluczem).
Z tego powodu Twoje pytanie jest naprawdę poprawne -
dig
nie widział zastosowania, jakiego moglibyśmy się spodziewać. Jest to komentowane tutaj, na przykład:

dlaczego nikt nie mówi o wykopaliskach
http://anamaria.martinezgomez. ... .html
.
Aby uniknąć tych błędów, spróbuj
dig
KeyDial
https://github.com/Convincible ... _dial
gem Napisałem, aby zawijać
dig
i zwracać nil/default, jeśli wystąpi jakiś błąd.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się