Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

404
Views
Does Ruby's reduce return the accumulator with curly braces?

I tried to implement reduce using curly braces, but was unable to get it to work. The function is supposed to take an array of words (symbols or strings) and create a hash where the keys are the words and the values are the length of the words. Here is my curly braces attempt:

def find_word_lengths(word_list)
  word_list.reduce(Hash.new(0)) { |hash,word| hash[word] = word.length}
end

I keep getting the error undefined method '[]=' for 3:Integer.

When I implement it with do instead of curly braces, it works, but only when I return the accumulator at the end of the reduce block.

def find_word_lengths(word_list)
  word_list.reduce(Hash.new(0)) do |hash,word| 
    hash[word] = word.length
    hash
  end
end

I can see why the second one works, but I don't understand why the first one doesn't. My understanding of reduce is that it returns the accumulator implicitly after running through the array it's called on. At least, when I write a reduce function call that reduces to a number, it automatically returns the sum

my_numbers = [5, 6, 7, 8]

my_numbers.reduce(1000) { |sum, number| sum + number }
#=>1026

Does reduce behave differently depending on the type of the accumulator?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

In your first example, you return the result of assigning word.length to the hash[word], i.e. word.length itself. Thus, the seciond iteration of the loop will retrieve the length of the first word of your word_list as its argument.

In your second example, you are explicitly return the hash in the block (which then works).

An equivalent one-liner version with curly braces to your working multi-line version is

word_list.reduce(Hash.new(0)) { |hash, word| hash[word] = word.length; hash }

Instead of using reduce, you could also use each_with_object instead which will always yield the original object to each iteration:

word_list.each_with_object(Hash.new(0)) { |hash, word| hash[word] = word.length }
over 4 years ago · Santiago Trujillo Report

0

The accumulator is NOT returned implicitly. This is the assumption which breaks the rest of your analysis.

The is stated in the docs if you read carefully:

... In either case, the result becomes the new value for memo. ..

What this is talking about is the result of the execution of the block, whether curly braces or do/end, becomes the new value for memo on the next round.

So both curly braces and do/end work exactly the same, it was just that you assumed the memo was returned implicitly, when it isn't.

If you analyze your code now with this new knowledge, you should hopfully understand why some of the examples worked while others did not.

Remember, the last statement inside the block will be the value of the memo on the next iteration.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!