Подтвердить что ты не робот

Безопасная навигация, эквивалентная Rails, пытается использовать хэши

В Rails вы можете сделать hash.try(:[], :key), который помогает, если hash потенциально nil. Существует ли эквивалентная версия для использования нового безопасного навигационного оператора Ruby 2.3 &. с []?

4b9b3361

Ответ 1

&. не эквивалентен Rails 'try, но вы можете использовать &. для хэшей. Просто используйте его, ничего особенного.

hash[:key1]&.[](:key2)&.[](:key3)

Хотя я бы этого не сделал.

Ответ 2

Pre Ruby 2.3

У меня обычно было что-то вроде этого, помещенного в мой intializer:

Class Hash
    def deep_fetch *args
      x = self
      args.each do |arg|
        x = x[arg]
        return nil if x.nil?
      end
      x
    end
end

а затем

response.deep_fetch 'PaReqCreationResponse', 'ThreeDSecureVERes', 'Message', 'VERes', 'CH', 'enrolled'

в одном дурацком случае.

Общий консенсус в сообществе, по-видимому, заключается в том, чтобы избежать как попыток, так и одинокого оператора &.

Ruby 2.3 и более поздние версии

Теперь метод Hash#dig, который делает именно это:

Несколько раз возвращает объект значения, соответствующий каждому объекту.

h = { foo: {bar: {baz: 1}}}

h.dig(:foo, :bar, :baz)           #=> 1
h.dig(:foo, :zot)                 #=> nil

http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig

Ответ 3

Принятый ответ не учитывается, когда hash равен нулю...

Вы можете переписать то, что у вас есть, с помощью оператора безопасной навигации до .try, и это сработает

hash&.try(:[], :key)

но вы также можете использовать:

http://ruby-doc.org/core-2.3.0_preview1/Hash.html#method-i-dig

Вы можете сделать это с помощью хэша...

hash&.dig(:key1, :key2 ...)

который вернет ноль, если какая-либо ключевая выборка отсутствует.

{ key1: { key2: 'info' } } 

вернет "информация"

{ key1: { wrong_key: 'info' } } 

вернется nil

Ответ 4

В то время как hash&.[](:key) является элегантным для обученного рубиста, я бы просто использовал hash && hash[:key], поскольку он читает лучше и интуитивно для программиста, идущего за мной, который, возможно, не так хорошо знаком с тонкостями рубина. Некоторые дополнительные символы в кодовой базе иногда могут сэкономить много раз для кого-то другого.

(Учитывая контекст, который вы хотите использовать, это, конечно, в условном выражении.)

Ответ 5

Более удобный способ использования оператора безопасной навигации, чем использование &.[](:slug), заключается в использовании метода fetch:

&.fetch(:slug)

Если ваш ключ не может быть определен, вы можете использовать второй аргумент по умолчанию:

&.fetch(:slug, nil)