Hash inside another Hash always returns empty if no key is used

Asked

Viewed 109 times

0

Well I created a method to group all one user’s commits per month into one 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 recovering the data by month the data appears, but the variable rank is empty as you can see in the debug below

[1] pry(main)> rank[month]
=> {"user1"=>4, "user2"=>1}
[2] pry(main)> rank
=> {}

1 answer

1


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

That is, whenever you try to access a key that does not exist in the rank you end up accessing a new hash (Hash.new(0)), and the problem is that this new hash is getting the assignment value rank[month][commit[:user_name]] += 1, and the hash rank ends up not fearing this assignment internally -- it’s kind of complicated explain this, and to tell the truth even I don’t know how it works internally XD.

But you can check all the values as follows:

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

Read more on 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:

Browser other questions tagged

You are not signed in. Login or sign up in order to post.