Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

221
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda