2010-08-11 3 views
5

Сегодня я видел фрагмент кода ruby.Как работает рубиновая инъекционная магия?

[1,2,3,4,5,6,7].inject(:+) 

=> 28

[1,2,3,4,5,6,7].inject(:*) 

=> 5040

Инъекция здесь довольно сильно отличается от тех, что я видел раньше, как

[1,2,3,4,5,6,7].inject {|sum, x| sum + x} 

Пожалуйста, объясните, как это работает?

+0

Я не знаю, есть ли для него специальное имя (если вы хотите сделать это для Google), кроме символа # to_proc. –

ответ

6

Нет волшебства, символ (метод) является лишь одним из возможных параметров. Это из документов:

# enum.inject(initial, sym) => obj 
    # enum.inject(sym)   => obj 
    # enum.inject(initial) {| memo, obj | block } => obj 
    # enum.inject   {| memo, obj | block } => obj 

Наш случай является вторым.

Вы также можете переписать его с традиционным блоком:

op = :+ # parameter of inject call 
[1,2,3,4,5,6,7].inject {|sum, x| sum.send(op, x)} # also returns 28 

(ответить «как это работает» часть)

+0

Невозможно найти информацию о символе в качестве параметров здесь, http://ruby-doc.org/core/classes/Enumerable.html. Документ слишком стар ... –

+0

@ Zifei Это ссылка на версию 1.8.6. Проверьте http://ruby-doc.org/ для ссылок на другие версии, раздел Core API –

+1

Получите его, http://ruby-doc.org/core-1.8.7/classes/Enumerable.html. Благодарю. –

1

Как вы можете видеть in the docs, inject может принимать блок (как вы» знакомый) или символ, который представляет имя двоичного оператора. Это полезная стенограмма для уже определенных опций.

+1

Спасибо, ruby ​​1.9 сладок :) –

3

The: + is symbol, представляющий сообщение с добавлением. Помните, что Ruby имеет стиль Smalltalk, где практически каждая операция выполняется путем отправки сообщения объекту.

Как обсуждалось подробно here, (1..100).inject(&:+) является допустимым синтаксисом в более ранних версиях, где Rails добавила расширение to_proc к символу.

Способность передавать только символ в инъекции была новой в 1.9 и backported into 1.8.7.

+0

И действительно, эта техника известна как «знаменитый символ (символ) >> значение: хак» (http://blog.3plus4.org/2007/03/27/selectors-as -блоки /) в сообществе Smalltalk: '(1..100) уменьшить: # +' –

Смежные вопросы