2011-12-17 3 views
1

Я читаю «язык рубинового программирования» и натолкнулся на следующий фрагмент кода.Передача нескольких аргументов блоку

a.inject do | sum, x | 
    sum + x 
end 

Я понимаю, что х содержит один элемент из, который будет передан Бок, но «сумма» часть является меня смущает, это какой-то оператор или функцию, или это просто еще одна переменная, как х. Я понимаю, что переменную x можно было бы назвать f или v, но если это так, как рубин знает, что x - это переменная, чтобы передать элемент в итератор, то он мог бы так же легко передать переменную в сумму (если она является даже переменной).

Надеюсь, это имеет смысл, так как всегда я нахожу, что это должно было положить мое замешательство в работу, как если бы я лучше понимал природу проблемы, я был бы более правдоподобным, чтобы иметь возможность найти свое решение.

Спасибо!

ответ

7

сумма является объектом аккумулятор, например, следующий код:

(1..10).inject(0) do |sum, num| #sum is initialized to 0 and passed in as the accumulator 
    sum + num #since sum is the accumulator, the result of this addition is stored in sum 
end 

Приведенный выше код такой же, как:

sum = 0 
(1..10).each do 
    |num| 
    sum = sum + num 
end 

Вы можете присвоить объекту ГИДРОАККУМУЛЯТОРОМ любое допустимое имя переменной, из Конечно, лучше со значимым именем в контексте.

+0

так в моем примере, как рубин знает, чтобы дать значение x, потому что его последний в списке, или это потому, что сумма - это какое-то ключевое слово? будет '| x, sum | 'делают то же самое? –

+0

ОК, так что (просто чтобы получить это прямо в моем маленьком мозгу), если бы я должен был это сделать '| a, b, c, val | ', тогда a, b и c будут переменными, которые я использую в блоках и val, потому что он был назван последним, будет где итератор передает другое значение каждому блоку –

+0

aaah, отлично, поэтому итератор определяет переменные, которые он ожидает, что очищает все! очень признателен! –

0

sum - просто имя параметра - в нем нет никакой магии. Вы можете выбрать любое имя для него, например:

a.inject do | accumulator, el | 
    accumulator + el 
end 

Сделал бы то же самое.

inject просто выполняет итерации через элементы accumulator и выполняет заданный блок для каждого элемента a. Важно, что результат каждой итерации становится доступным для следующей итерации как accumulator. Результат последней итерации становится результатом всего вызова inject.

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