método “tentar” – você precisa dele?

O que é “tentar”?

Você já acabou com esse código?

@person && @person.name

Estamos fazendo isso porque não sabemos aqui se @personé nilvalor. No entanto, podemos refatorar essa linha com try:

@person.try(:name)

Que é equivalente a

@person.nil? ? nil : @person.name

Portanto, nenhuma exceção é levantada e o namemétodo é chamado se @personfor nil. Nós estamos felizes:)

Cenário

Argumentos

O primeiro argumento é o nome do método e outros argumentos são passados ​​como argumentos para o método chamado.

@people.take(5)

pode ser escrito como:

@people.try(:take, 5)

Encadeamento de Método

tryo método retorna sempre nilse chamado no nilobjeto:

nil.try(:foo) # => nil

Graças a isso, podemos refatorar isso:

@person && @person.name && @person.name.downcase == "Kavinsky"

para isso:

@person.try(:name).try(:downcase) == "Kavinsky"

Cenário

Você pode ir ainda mais longe para evitar a repetiçãotry :

"Don'tRepeatYourselfs ".try_chain(:underscore, :capitalize, :chop!, :chop!)

De onde vem a tentativa ?

trymétodo é definido em Objectclasse e NilClassclasse em Rails e não faz parte do Ruby em si. No entanto, se você quiser usá-lo sem Rails, pode instalar activesupportapenas o gem e chamar:

require 'active_support/core_ext/object/try'

Você realmente precisa tentar?

Estou me perguntando se você precisa usar o try . Tive um grande problema em encontrar um exemplo real, então peguei no código-fonte do Rails. Vamos dar uma olhada em alguns exemplos de outra postagem do blog que descreve como tentar evitartry

@manufacturer.products.first.try(:enough_in_stock?, 32) # => "Yes"

Por que diabos você faria essa consulta?

@manufacturer.products.try(:collect) { |p| p.name } # => ["3DS", "Wii"]

Aqui você pode usar since retornará um array que responde a (se você usar associação no modelo).@manufacturer.products.collectproductscollecthas_many

Que tal este? É tryrealmente necessário aqui?

if current_user.try(:is_admin?)

Não temos que usar tryse representarmos um caso especial como outro objeto (como na seção 2.2 do livro Confident Ruby). O problema tryquer resolver é que nós não queremos para obter NoMethodError chamando no objeto. Portanto, o que podemos fazer é fazer o objeto responder ao método desejado , definindo o método. O método pode realmente retornar uma instância da seguinte classe se o usuário não estiver conectado:is_admin?nilis_admin?current_user

class GuestUser
def is_admin?
false
end
end

Agora você pode usar:

if current_user.is_admin?

Conclusão

trypode tornar seu código mais curto quando você está lidando com objetos nulos em potencial. No entanto, eu sempre pensaria no redesenho do código primeiro, antes de injetar tryem seu código.

Nota:

Apenas por uma questão de integridade, o método try aceita um bloco.
Mais sobre isso aqui http://api.rubyonrails.org/classes/Object.html#method-i-try

2.0.0p195, Rails 3.2