Ruby Data Type Classes: Numbers, Arrays, Symbols, & Hashes
Tags: ruby, tutorial, beginners
Published: 2020-05-25 19:29:07

Before we dive deeper into some more of the basics of Ruby, I felt it necessary to explain more about classes. We'll discuss the different classes above, and give some light examples this week, before diving more in-depth in our following lessons. If you think classes sound a little advanced for you, fear not! We've already covered a few classes in previous lessons: the `String` class & the Boolean classes `TrueClass` & `FalseClass`. EZPZ!

<h1>What is a Class?</h1>
In Ruby, a class is basically the blueprint for building an object. While Ruby provides you the freedom to define your own classes (covered in a later lesson), the classes we will be discussing are the basic classes that already come built into Ruby. The main ones we will cover (in addition to the ones we already have) are:
<ul>
<li>TrueClass & FalseClass - Creates an instance of a `true` or `false` object.</li>
<li>String Class - A string is a sequence of characters, denoted in programming with quotation marks.</li>
<li>Number Classes - "Number" is not a class itself, but is a reference to several number-based classes.</li>
<li>Array Class - An array is an ordered, integer-indexed collection of any objects. </li>
<li>Symbol class - Symbols are generally used to identify a specific resource such as a method, variable, hash key, etc.</li>
<li>Hash Class - A collection of `keys` and their `values`.</li>
</ul>

The benefits of being a part of a `class` in Ruby, is that each class provides the blueprint as well as various built-in methods that every instance of that class will have access to. When dealing with a certain data type, you can use the `methods` method to view what methods are available to you for that data type. For instance:

```ruby
x = "Hello, world!"
#x would be an instance of String class

puts x.methods
#=> to_h
#=>include?
#=>at
#=>fetch
#=>last
#=>union
#=>difference
#=>push
#=>...

#Lists all String class methods
```
Whereas

```ruby
x = 1
#x would be an instance of Integer class

puts x.methods
#=> -@
#=> **
#=> <=>
#=> upto
#=> <<
#=> <=
#=> >=
#=> ==
#=>...

#Lists all Integer class methods
```
You can see from the list we have different methods available to `x` depending on what class its `value` is classified as. Knowing what methods are available to you is paramount as a developer.

<h1>Numbers Classes</h1>
Ruby uses quite a few different classes for numbers, each one meant to capture certain unique features different types of numbers could have. Numbers can become a very hefty topic very quickly, so I'll keep it quick and only mention `Integer` and `Float` classes, as those are by far the most frequent you will be using.

<h3>Integer Class</h3>
The `Integer` class is simple and straightforward: it holds whole numbers. Anything with a decimal, fraction, or some other demarkation of partial value does not fit into the `Integer` class.

<h3>Float Class</h3>
Used to identify decimal numbers. `Pi` would be an example of a `Float` class instance.

```ruby
puts Math::PI.class 
#=> Float
```
On a side note, when using math in Ruby such as `1/2` (the `/` stands for 'divided by' in Ruby), by default Ruby will try to force the solution to be an an `Integer` since both the dividend and divisor fall under the `Integer` class. By contrast, `1.5/3` would naturally fall under the `Float` class since 1.5 is a `Float`. When using math in Ruby with whole numbers that *could* lead to a decimal value, it's good practice to convert to float with the `.to_f` method to prevent Ruby from rounding to the nearest `Integer`.

```ruby
x = 1/2

puts x 
puts x.class

#=> 0
#=> Integer

y = 1/2.to_f

puts y 
puts y.class

#=> 0.5
#=> Float
```

<h1>Array Class</h1>
As stated earlier, an array is an ordered, integer-indexed collection of any objects. You would denote an `array` in Ruby with brackets `[]`. You separate each object in an array with a `,`. A few examples of an array are:

```ruby
numbers_array = [1, 2, 3, 4, 5]
#This is an array of 5 different Integers.

words_array = ["words", "to", "fill", "this", "array"]
#This is an array of 5 different Strings.

single_array = ["this, looks, like, a, lot, of, different, words, but, a, syntax, error, makes, this, a, one, string, array"]
#This is an array with only 1 String.
```
You can immediately see the value in arrays as storage containers. An array can give us access to multiple objects in a single location! 

Arrays are indexed in order starting with 0. This means that the first object in an array will have an index number of 0, the second an index of 1, and so on. You can access a specific index in an array with the syntax `array_name[index#]`. Using the arrays above, try to guess the return value of `numbers_array[2]`, `single_array[1]`, `words_array[0]`.

If you guessed `numbers_array[2]` = 3`, `single_array[1]` = `nil` (means 'nothing'), & `words_array[0] = `words` you were right. Anything else means you were less right :). 

Comparing the above to our earlier lesson on variables, In addition to storing data in list form, think of the index number as also setting a variable to all the different pieces of data inside an array. 

<h1>Symbol Class</h1>
Symbols generally point to a specific resource in your program. You denote them in ruby with a `:` in front of the word you want as a symbol like `:brandon`. The key benefit of using symbols is that they are immutable and will always point to the same object. By comparison, a string even if totally identical, will always be a different object and take up more memory to account for mutability. The most basic way to understand this is to return multiple of the same data type with equal value:

```ruby
puts "Brandon".object_id
puts "Brandon".object_id
puts "Brandon".object_id
#=> 42553140
#=> 42552980
#=> 42552920
```
Note how all the `object_id`'s are different. 

Now the same thing but using the `Symbol` `:brandon`
```ruby
puts :brandon.object_id
puts :brandon.object_id
puts :brandon.object_id
#=> 1102428
#=> 1102428
#=> 1102428
```
Now all the id's are the same. This immutability is primarily why symbols make superior hash keys because they will point to the same value without using as much memory, hence making your program less bulky overall. More on `Hash` class right below, but note the two ways to make a symbol into a hash key:

```ruby
instructor = {:name => "Brandon Weygant"}
```
This first way is the native way to do it in Ruby. However, as of Ruby 1.9 and above, they simplified the syntax to make it look like a more classical `key:value` pairing like this:

```ruby
instructor = {name: "Brandon Weygant"}
```
`name:` will still read as a `Symbol` in this case, and this syntax is the preferable way to do it today. Note that if you use keys that aren't symbols inside a hash, you will have to continue to use the `=>` rocket syntax.

<h1>Hash Class</h1>
As stated earlier, a `Hash` is a collection of `keys` and their `values`. A `hash` is denoted with the curly brackets `{}`. Inside the `{}` you would have a key pointing to a value (like above in `Symbols`) and multiple entries would be separated with comma's, just like in arrays

A `Hash` has many similarities to an `Array`, but some key differences as well. Where an `array` is a list, `hashes` are dictionaries where we look up the value of a key by using the key directly. This means you aren't bound by knowing what index# an array list item has to call it, you simply have to remember the key you used. Example:

```ruby
todays_lessons = {number: "We learned about number classes.", 
    array: "We learned about number classes.", 
    symbol: "We learned about the Symbol class.", 
    hash: "We are currently learning about the hash class!"}
```
If we tried to `puts todays_lessons[1]`, instead of getting the `:array` value, we'd get `nil` instead. The correct syntax to return the `:array` value is:

```ruby
puts todays_lessons[:array]
```
Amazingly simple, right? If an Array is designed to be a list of your classes, a hash could be used as an equivalent to the notes you took while in class. 

<h1>Conclusion</h1>
This is a lot to unpack in a day, but the basics taught here will be vital to understanding as we dive deeper into Math, Array manipulation, iteration, and Hashes. There is a *ton* of information we haven't covered on each of these. I just hope this gives you a general idea of how Ruby uses different classes to organize and enhance the unique properties each data type brings to the table.   

For now take a break and happy Memorial Day!.

<h1>Ruby Data Types Lab</h1>
We've unpacked a lot in this lesson, covering several data types you may or may not already be familiar with. Let's embed that by completing the tasks found in the [Ruby Data Types Lab](https://github.com/BMWeygant/Ruby-Data-Types-Lab)!