You seem to be confusing two concepts. One is if a variable is defined, and another is if a Hash key is defined. Since a hash is, at some point, a variable, then it must be defined.
defined?(a)
# => nil
a = { }
# => {}
defined?(a)
# => "local-variable"
a.key?('one')
# => false
a['one'] = 'hello'
# => 'hello'
a.key?('one')
# => true
Something can be a key and nil
at the same time, this is valid. There is no concept of defined or undefined for a Hash. It is all about if the key exists or not.
The only reason to test with .nil?
is to distinguish between the two possible non-true values: nil
and false
. If you will never be using false
in that context, then calling .nil?
is unnecessarily verbose. In other words, if (x.nil?)
is equivalent to if (x)
provided x
will never be literally false
.
What you probably want to employ is the ||=
pattern that will assign something if the existing value is nil
or false
:
# Assign an array to this Hash key if nothing is stored there
a['one']['hello'] ||= [ ]
Update: Edited according to remarks by Bruce.