Fork, clone, branch (training), bundle install
By the end of this, students should be able to:
- Constrast Ruby Hashes with JavaScript dictionaries.
- Create a Ruby Hash using both the implicit (
{}
) andnew
constructors. - Assign a value to or modify a value in a Ruby Hash using a specified key.
- Access a value in a Ruby Hash using a specified key.
- Obtain an Array of keys from a Ruby Hash.
- Explain why Symbols are preferred over Strings as keys in a Ruby Hash.
In Ruby, "A Hash is a dictionary-like collection of unique keys and their values". In sharp contrast to JavaScript, Ruby Hashes are not the most general object in the language, but are instances of a specialized class for key/value storage.
A Symbol is a sequence of characters that is stored at most once in any instance of the Ruby interpreter.
In Ruby, strings are compared a character at a time, but symbols are compared by object_id
. This makes comparing symbols fast and therefore much more performant than strings when used as keys in a Hash
.
Each of the following pairs of operations are equivalent:
> 'bob'.equal? 'bob'
=> false
> 'bob'.object_id == 'bob'.object_id
=> false
> 'bob'.eql? 'bob'
=> true
> 'bob' == 'bob'
=> true
But all of the following operations are equivalent:
> :bob.equal? :bob
=> true
> :bob.object_id == :bob.object_id
=> true
> :bob.eql? :bob
=> true
> :bob == :bob
=> true
We can create a symbol with arbitrary characters if we surround the characters with quotes (either :'<characters>'
or '<characters>'.to_sym
):
> :'&foo'.equal? '&foo'.to_sym
=> true
How does this compare to keys in JavaScript?
Let's look at different ways to create a Hash.
> consultant = {}
=> {}
> consultant = Hash.new
=> {}
> consultant = Hash.new('')
=> {}
> consultant[:surname]
=> ""
> consultant
=> {}
> consultant = Hash.new {|hash, key| hash[key] = ''}
=> {}
> consultant[:surname]
=> ""
> consultant
=> {:surname=>""}
> consultant = { given_name: 'Antony', surname: 'Donovan', height: 76}
=> {:given_name=>"Antony", :surname=>"Donovan", :height=>76}
> consultant[:weight] += 10
NoMethodError: undefined method ``+'' for nil:NilClass
from (pry):2:in ``__pry__''
> consultant = Hash.new(0).merge({ given_name: 'Antony', surname: 'Donovan', height: 76})
=> {:given_name=>"Antony", :surname=>"Donovan", :height=>76}
> consultant[:weight] += 10
=> 10
Picking sensible defaults may not always be easy.
Let's use the different forms of Hash::new to create some hashes in bin/code_along.rb
.
In bin/lab.rb
use Hash.new
to create a Ruby Hash that has []
as the default for the keys :experience
and :education
. These defaults should be assigned to the appropriate key on access or assignment.
> consultant[:weight]
=> 0
> consultant[:weight] = 185
=> 185
> consultant[:weight] += 5
=> 190
> consultant[:surname]
=> "Donovan"
> consultant[:surname].prepend 'O\''
=> "O'Donovan"
> consultant[:surname]
=> "Donovan"
> consultant[:surname] = consultant[:surname].prepend 'O\''
=> "O'Donovan"
> consultant[:surname]
=> "O'Donovan"
To get an Array of the keys that have been set in a hash, use Hash#keys
.
> consultant.keys
=> [:given_name, :surname, :height, :weight]
A quick look at access and assignment in bin/code_along.rb
.
Append "GA WDI" to both :experience
and :education
in the hash in bin/lab.rb
. Append one or more item of your choosing to the values at each of these keys.
Source code distributed under the MIT license. Text and other assets copyright General Assembly, Inc., all rights reserved.