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

Что такое: + и &: + в Ruby?

Я видел это несколько раз, но я не могу понять, как их использовать. Пикап говорит, что это специальные ярлыки, но я не смог найти синтаксическое описание.

Я видел их в таких контекстах:

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

для вычисления суммы, например.

4b9b3361

Ответ 1

Начнем с более простого примера. Скажем, у нас есть массив строк, которые мы хотим иметь в шапках:

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

Кроме того, вы можете создать так называемые объекты Proc (закрытие):

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

Вы можете передать такой процесс методу с синтаксисом:

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

Что это значит, это вызов to_proc на блоке, а затем вызывает это для каждого блока:

some_object = Object.new
def some_object.to_proc
  proc { |e| e.upcase }
end

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

Теперь Rails сначала добавила метод to_proc к Symbol, который позже был добавлен в библиотеку ядра ruby:

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

Поэтому вы можете сделать это:

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

Кроме того, символ # to_proc еще более умный, поскольку он на самом деле делает следующее:

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

Это означает, что

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

равно

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

Ответ 2

инъекция принимает символ как параметр, этот символ должен быть именем метода или оператора, который является следующим :+

поэтому [1,2,3].inject(:+) передает каждое значение методу, указанному символом, поэтому суммирует все элементы в массиве.

источник: https://ruby-doc.org/core-2.5.1/Enumerable.html