wartość zwracana przez inject

Na tablicy obiektów wykonuje

arr.inject{|sum,obiekt| obiekt.value()}

Jeśli tablica zawiera tylko jeden element to zwracany jest element

obiekt

a nie wartość

obiekt.value()

Jak można sobie z tym poradzić, bo trochę to dla mnie dziwne.

Jeśli inject jest wywoływane bez parametru, to pierwszy element tablicy brany jest jako wartość początkowa. Żeby osiągnąć oczekiwany efekt napisz:

arr.inject(nil){|sum,object| object.value()}

Zastanawiam się jednak, czy rozumiesz semantykę inject, skoro w kodzie nie wykorzystujesz wcześniejszej wartości “sum”.

arr.inject(arr.shift.value()) {|sum,obiekt| sum + obiekt.value()}

lub

arr.inject(0) {|sum,obiekt| sum + obiekt.value()}

Enumerable#inject.

Combines all elements of enum by applying a binary operation, specified by a block or a symbol that names a method or operator.

If you specify a block, then for each element in enum the block is passed an accumulator value (memo) and the element. If you specify a symbol instead, then each element in the collection will be passed to the named method of memo. In either case, the result becomes the new value for memo. At the end of the iteration, the final value of memo is the return value fo the method.

If you do not explicitly specify an initial value for memo, then uses the first element of collection is used as the initial value of memo.

To jest “binary operation” czyli “działanie dwuargumentowe” - potrzebujesz przynajmniej 2 elementów, żeby operacja się wykonała. Czyli jeśli masz jednoelementową tablicę to memo ustawiane jest na pierwszy element tablicy, blok się nie wykonuje (bo potrzeba 2+ elementów) i zwracane jest memo.

Ten fragment implementacji Enumerable#inject z Rubiniusa pozwoli Ci to lepiej zrozumieć

dzieki, przyznam się, że znałem injecta bez parametrów, widać musiało mi gdzie to umknąć, jak przeglądałem dokumentacje.