O método yield_self
funciona de forma similar ao tap
. Ambos são métodos comumente utilizados para executar blocos de ações sobre um mesmo objeto, mas, ao contrário do tap
, o yield_self
retorna o resultado da operação executada em vez do objeto. Vamos ver como isso funciona com um exemplo simples:
"hello".tap { |w| "#{w} world" }
=> "hello"
"hello".yield_self { |w| "#{w} world" }
=> "hello world"
Note como o tap
retorna o objeto, modificado ou não pela ação executada no bloco. Já o yield_self
retorna o resultado da operação. Isso pode ser útil quando estamos interessados somente na resposta que um objeto gera, mas não no objeto em si. Por exemplo, quando usamos a gem Faraday para intermediar o processo de requisição e resposta. Observe o código abaixo:
def self.all
url = 'http://localhost:3000/api/v1/product_types'
response = Faraday.get(url)
json = JSON.parse(response.body, symbolize_names: true)
result = [ ]
json.each do |item|
result << new(item[:id], item[:product_key])
end
return result
end
Acima, definimos um método all
dentro da classe Product
para retornar a lista de todos os product_types
(tipos de produtos) acessando a url de uma API e usamos Faraday para criar o objeto de resposta dessa requisição. Em seguida, lê-se o json gerado e é montado o array que compõe a resposta adequada. Usando o método yield_self
, poderíamos escrever:
def self.all
url = 'http://localhost:3000/api/v1/product_types'
result = [ ]
url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response, symbolize_names: true) }
.map { |item| result << new(item[:id], item[:product_key]) }
return result
end
Essa é uma possível aplicação para o método yield_self
. Os ganhos em clareza de leitura ou em economia de linhas de código são discutíveis, mas certamente existem outras aplicações interessantes para esse método.
A partir da versão de Ruby 2.6, também está disponível o método then
, que é sinônimo do yield_self
.
"hello".then { |w| "#{ w } world" }
=> "hello world"
Referências
- https://ruby-doc.org/core-2.7.0/Object.html#method-i-yield_self
- https://www.assertnotmagic.com/2017/12/29/tap-and-yield-self/
- https://zverok.github.io/blog/2018-01-24-yield_self.html