O que são: + e &: + no Ruby?

Eu já vi isso várias vezes, mas não consigo descobrir como usá-las. A picareta diz que estes são atalhos especiais, mas não consegui encontrar a descrição sintática.

Eu os vi em tais contextos:

[1,2,3].inject(:+) 

calcular sum por exemplo.

Vamos começar com um exemplo mais fácil. Digamos que temos um array de strings que queremos ter em maiúsculas:

 ['foo', 'bar', 'blah'].map { |e| e.upcase } # => ['FOO', 'BAR', 'BLAH'] 

Além disso, você pode criar os chamados objects Proc (closures):

 block = proc { |e| e.upcase } block.call("foo") # => "FOO" 

Você pode passar tal proc para um método com a syntax:

 block = proc { |e| e.upcase } ['foo', 'bar', 'blah'].map(&block) # => ['FOO', 'BAR', 'BLAH'] 

O que isto faz, é chamar to_proc on block e depois chama isso para cada bloco:

 some_object = Object.new def some_object.to_proc proc { |e| e.upcase } end ['foo', 'bar', 'blah'].map(&some_object) # => ['FOO', 'BAR', 'BLAH'] 

Agora, o Rails primeiro adicionou o método to_proc ao Symbol, que mais tarde foi adicionado à biblioteca do ruby ​​core:

 :whatever.to_proc # => proc { |e| e.whatever } 

Portanto, você pode fazer isso:

 ['foo', 'bar', 'blah'].map(&:upcase) # => ['FOO', 'BAR', 'BLAH'] 

Além disso, o símbolo # to_proc é ainda mais inteligente, pois na verdade faz o seguinte:

 :whatever.to_proc # => proc { |obj, *args| obj.send(:whatever, *args) } 

Isso significa que

 [1, 2, 3].inject(&:+) 

é igual a

 [1, 2, 3].inject { |a, b| a + b } 

injeta aceita um símbolo como parâmetro, este símbolo deve ser o nome de um método ou operador, que neste caso é :+

então [1,2,3].inject(:+) está passando cada valor para o método especificado pelo símbolo, portanto, sumndo todos os elementos na matriz.

fonte: https://ruby-doc.org/core-2.5.1/Enumerable.html