Luiz Carvalho
Luiz Carvalho

Reputation: 1419

Creating a hash during a loop with strange behavior

this is my code, I try creating a hash with header as key and arrays of hashs with values, but result don't keep data after loop, in contrast result[key] works normaly.

  def programacao
    result = Hash.new([])
    header = nil
    csv_each_for(file_to('programacao/9')).each do |row|
      next if row[0].nil?

      if row[0].start_with?('#')
        header = row[0]
        next
      end
      # puts "HEADER #{header} / ROW: #{row[0]}"
      result[header] << ({
                            horario: row[0],
                            evento: row[1],
                            tema: row[2],
                            palestante: row[3],
                            instituicao: row[4],
                            local: row[5]
      })
      binding.pry
    end
    result
  end

FIRST ITERATION:

[1] pry(#<Programacao>)> result
=> {}

but result[reader]

[3] pry(#<Programacao>)> result[header]
=> [{:horario=>"09:00 - 9:50",
  :evento=>"Palestra",
  :tema=>"Reforma da Previdência",
  :palestante=>"Dr. Álvaro Mattos Cunha Neto",
  :instituicao=>"Advogado - Presidente da Comissão de Direito Previdenciário",
  :local=>"OAB"}]

SECOND ITERATION:

[1] pry(#<Programacao>)> result
=> {}

Header steel works normaly

[2] pry(#<Programacao>)> result[header]
=> [{:horario=>"09:00 - 9:50",
  :evento=>"Palestra",
  :tema=>"Reforma da Previdência",
  :palestante=>"Dr. Álvaro Mattos Cunha Neto",
  :instituicao=>"Advogado - Presidente da Comissão de Direito Previdenciário",
  :local=>"OAB"},
 {:horario=>"9:00 -10:00", :evento=>"Solenidade de abertura do Estande", :tema=>nil, :palestante=>"Direção/Coordenações", :instituicao=>nil, :local=>"Faculdade Católica do Tocantins"}]

Where is my mistake?

Upvotes: 0

Views: 55

Answers (1)

Tom Lord
Tom Lord

Reputation: 28305

I don't fully understand your question, because you have not provided a Minimal, Complete, and Verifiable example. (What is csv_each_for? What is file_to? What is your input CSV? If providing all of this information is unnecessary, then can you provide a minimal example?)

However, I believe the crux of your problem is in this line:

result = Hash.new([])

Instead, you should use:

result = Hash.new { |hash, key| hash[key] = [] }

This is because, as mentioned in the ruby docs, you need to create a new default object each time.

This is a common gotcha. It was because of this mistake that you were seeing the bizarre behaviour, where result == {} but result[something] == [{:horario=>"09:00 - 9:50", ...}].

Upvotes: 2

Related Questions