Perhaps I am missing something, but if all you care about is concise...why not:

@hash && @hash[:key1] && @hash[:key1][:key2]

or if you want to save a few characters

@hash && (h = @hash[:key1]) && h[:key2]

if any part of this fails, it returns nil otherwise it returns the value associated with :key2 or true.

The reason the defined? returns true even if :key2 is not there is because it just checks whether the object you are referencing exists, which in that case is the method [] which is an alias for the method fetch which does exist on the hash @hash[:key1] but if that were to return nil, there is no fetch method on nil and it would return nil. That being said, if you had to go n deep into an embedded hash, at some point it would become more efficient to call: