Hash
1. Except for strings and other built-in objects, most objects have a hash code equivalent to their internal object ID. As seen above, you can override Object#hash to change this, but the only time you should need to do this is if your class also overrides Object#==. If two objects are considered equal, they should also have the same hash code; otherwise, they will behave strangely when you put them into hashes. Code like the fragment below is a very good idea:
class StringHolder
attr_reader :string
def initialize(s)
@string = s
end
def ==(other)
@string == other.string
end
def hash
@string.hash
end
end
a = StringHolder.new("The same string.")
b = StringHolder.new("The same string.")
a == b # => true
a.hash # => -1007666862
b.hash # => -1007666862
Except for strings and other built-in objects, most objects have a hash code equivalent to their internal object ID. As seen above, you can override Object#hash to change this, but the only time you should need to do this is if your class also overrides Object#==. If two objects are considered equal, they should also have the same hash code; otherwise, they will behave strangely when you put them into hashes. Code like the fragment below is a very good idea:
class StringHolder
attr_reader :string
def initialize(s)
@string = s
end
def ==(other)
@string == other.string
end
def hash
@string.hash
end
end
a = StringHolder.new("The same string.")
b = StringHolder.new("The same string.")
a == b # => true
a.hash # => -1007666862
b.hash # => -1007666862
Using Symbols as Hash Keys
While 'name' and 'name' appear exactly identical, they're actually different. Each time you create a quoted string in Ruby, you create a unique object. You can see this by looking at the object_id method.
'name'.object_id # => -605973716
'name'.object_id # => -605976356
'name'.object_id # => -605978996
By comparison, each instance of a symbol refers to a single object.
:name.object_id # => 878862
:name.object_id # => 878862
'name'.intern.object_id # => 878862
'name'.intern.object_id # => 878862
Using symbols instead of strings saves memory and time. It saves memory because there's only one symbol instance, instead of many string instances. If you have many hashes that contain the same keys, the memory savings adds up.
Using symbols as hash keys is faster because the hash value of a symbol is simply its object ID. If you use strings in a hash, Ruby must calculate the hash value of a string each time it's used as a hash key.