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

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

38 голосов
/ 23 апреля 2010

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

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

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

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

Ответы [ 2 ]

68 голосов
/ 23 апреля 2010

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

['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']

Кроме того, Symbol # 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 голосов
/ 28 июля 2018

inject принимает символ в качестве параметра, этот символ должен быть именем метода или оператора, что в данном случае равно :+

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...