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

227
Views
Why do I get this Error in ruby: block in find_word_lengths': undefined method `[]=' for 3:Integer (NoMethodError)

the following code return this error:

block in find_word_lengths': undefined method `[]=' for 3:Integer (NoMethodError)

animals = ['cat', 'horse', 'rabbit', 'deer']

def find_word_lengths(word_list)
  word_list.reduce(Hash.new()) do |result, animal|
    result[animal] = animal.length
  end 
end

puts find_word_lengths(animals)
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

The return value of the block is the accumulator value for the next iteration. That is how a fold works.

Assignments in Ruby evaluate to the right-hand side. So, in the first iteration of reduce, the block evaluates to 3 (the length of 'cat'). Which means that in the second iteration of reduce, result is 3, and you are essentially running

3['horse'] = 5
# which is equivalent to
3.[]=('horse', 5)

Which is why you are getting the error message that the Integer 3 does not respond to the message []=.

So, you need to make sure that your block always returns the value that you want to use for the accumulator in the next iteration. Something like this:

word_list.reduce(Hash.new()) do |result, animal|
  result.tap {|result| result[animal] = animal.length }
end

This would be the obvious solution, although somewhat cheating.

word_list.reduce(Hash.new()) do |result, animal|
  result.merge(animal => animal.length)
end

Would be more idiomatic.

However, when you want to fold into a mutable object, it makes more sense to use Enumerable#each_with_object instead of Enumerable#reduce. each_with_object ignores the result of the block, and simply passes the same object every time. Note that somewhat confusingly, the order of the block parameters is swapped in each_with_object compared to reduce.

word_list.each_with_object(Hash.new()) do |animal, result|
  result[animal] = animal.length
end

But I guess the most idiomatic solution would be something like this:

word_list.map {|word| [word, word.length] }.to_h

By the way, in Ruby, it is idiomatic to leave out the parentheses for the argument list if you are not passing any arguments, so Hash.new() should be Hash.new instead. Even more important than being idiomatic is to be consistent – confusingly, you leave out the parentheses for animal.length, but not for Hash.new

Even more idiomatically, you would use the Hash literal notation instead of the Hash::new method, i.e. you should use {} instead of Hash.new.

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!