Ruby hash equivalent to Python dict setdefault Ruby hash equivalent to Python dict setdefault ruby ruby

Ruby hash equivalent to Python dict setdefault


A Hash can have a default value or a default Proc (which is called when a key is absent).

h = Hash.new("hi")puts h[123] #=> hi# change the default:h.default = "ho"

In above case the hash stays empty.

h = Hash.new{|h,k| h[k] = []}h[123] << "a"p h # =>{123=>["a"]}

Hash.new([]) would not have worked because the same array (same as identical object) would be used for each key.


Not to beat a dead horse here, but setDefault acts more like fetch does on a hash. It does not act the same way default does on a hash. Once you set default on a hash, any missing key will use that default value. That is not the case with setDefault. It stores the value for only the one missing key and only if it fails to find that key. That whole stores the new key value pair piece is where it differs from fetch.

At the same time, we currently just do what setDefault does like this:

h = {}h['key'] ||= 'value'

Ruby continued to drive point home:

h.default = "Hey now"h.fetch('key', 'default')                       # => 'value'h.fetch('key-doesnt-exist', 'default')          # => 'default'# h => {'key' => 'value'}h['not your key']                               # => 'Hey now'

Python:

h = {'key':'value'}h.setdefault('key','default')                   # => 'value'h.setdefault('key-doesnt-exist','default')      # => 'default'# h {'key': 'value', 'key-doesnt-exist': 'default'}h['not your key']                               # => KeyError: 'not your key'


There is no equivalent to this function in Python. You can always use monkey patching to get this functionality:

class Hash  def setdefault(key, value)    if self[key].nil?      self[key] = value    else      self[key]    end  endendh = Hash.newh = { 'key' => 'value' }h.setdefault('key', 'default')# => 'value'h.setdefault('key-doesnt-exist', 'default')# => 'default'

But keep in mind that monkey patching is often seen as a taboo, at least in certain code environments.

The golden rule of monkey patching applies: just because you could, doesn’t mean you should.

The more idiomatic way is to define default values through the Hash constructor by passing an additional block or value.