Hash within another hash always returns empty if a key is not used

0

I've created a method to group all the commits of a user per month into a hash:

def calculate_month_ranking(commits)
  rank = Hash.new(Hash.new(0))  
  commits.each do |commit_yml|
    commit = YAML.load commit_yml.data

    commit[:commits].each do |local_commit|      
      time = Time.parse(local_commit[:timestamp])
      month = "#{time.month}/#{time.year}"
      rank[month][commit[:user_name]]+= 1
      binding.pry # para debug
    end

  end

  rank  
end

The result is that when retrieving data by month the data appears, but the rank variable is empty as you can see in the debug below

[1] pry(main)> rank[month]
=> {"user1"=>4, "user2"=>1}
[2] pry(main)> rank
=> {}
    
asked by anonymous 02.06.2015 / 15:16

1 answer

1

In this case you are changing the fallback of your hash to keys that do not exist (when you do: rank = Hash.new(Hash.new(0)) ).

That is, whenever you try to access a key that does not exist in rank you end up accessing a new hash ( Hash.new(0) ), and the problem is that this new hash is receiving the value of the rank[month][commit[:user_name]] += 1 , and the hash rank does not endorse this assignment internally - it's kind of complicated to explain this, and to be honest, I do not even know how this works internally XD.

But you can check all values as follows:

[1] pry(main)> rank.default
=> {"junho"=>{"user1"=>4, "user2"=>1}}

Read more in the API:

  

Hashes have a default value that is returned when accessing keys that do not exist in the hash. If no default is set nil is used. You can set the default value by sending it as an argument to :: new:

    
09.06.2015 / 20:38