Ruby Intro

SENG2021

Hash & Symbols

Maps in the data structure sense is referred to in Ruby as Hashes. Map in Ruby is used in its functional programming definition.

Construction

1
2
3
4
5
6
7
8
9
a = { "a" => "b", 3 => "d" }
# {"a"=>"b", 3=>"d"}
b = Hash("a" => "b", 3 => "d")
# {"a"=>"b", 3=>"d"}

c = {}
d = Hash.new

e = Hash.new(0)

Testing for Equality

1
2
3
4
5
6
7
8
9
a==b
# true
a.equal? b
# false

c==d
# true
c.equal? d
# false

Retrieving from Hash

1
2
3
4
5
6
7
8
9
a["a"]
# "b"
a[3]
# "d"

a[4]
# nil
e[4]
# 0

Adding values to the Hash

1
2
3
a[5] = 6
puts a
# {"a"=>"b", 3=>"d", 5=>6}

Other useful functions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
b.clear
puts b
# {}

a.empty?
# false
b.empty?
# true

a.length
# 3

a.keys
# ["a", 3, 5]
a.values
# ["b", "d", 6]

Iterating through the hash

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a.each { |k,v| puts "The value for #{k} is #{v}" }
# The value for a is b
# The value for 3 is d
# The value for 5 is 

a.each_key { |k| puts "The value for #{k} is #{a[k]}" }
# The value for a is b
# The value for 3 is d
# The value for 5 is 6

a.each_value { |v| puts v }
# b
# d
# 6

a.each do |k,v|
  puts "The value for #{k} is #{v}"
end
# The value for a is b
# The value for 3 is d
# The value for 5 is 6

Symbols

Fixnum always have the same object_id, and we can tell Ruby to do that to Strings too – it’s what we call a Symbol. While a new string will be created every time the same String literal is used, the same symbol will always point to the same object in memory. This also means that Ruby’s automatic garbage collection will not recycle symbols.

1
2
3
4
5
6
7
8
9
"abc".object_id
# 70139181776180
"abc".object_id
# 70139181819060

:abc.object_id
# 1024808
:abc.object_id
# 1024808

Because of this, Symbols are the preferred way to set and get Hash elements.

Ruby Cookbook attributes this quote to Jim Weirich:

If the contents (the sequence of characters) of the object are important, use a string. If the identity of the object is important, use a symbol.

Do this..

1
2
3
4
h = Hash.new
h[:abc] = "xyz"
puts h[:abc]
# xyz

but don’t do this..

1
2
3
4
h = Hash.new
h["abc"] = :xyz
puts h["abc"]
# xyz