Ruby Variables and Constants
Tags: ruby, variables, constants
Published: 2022-03-17 05:25:36


Variables and constants are locations which hold data to be used by a program. Constants are meant to declare values that we expect to be unchanged throughout our program. On the other hand, we use variables to declare values that we expect to change throughout our program. 

## Variables

There are four types of variables in ruby. They are 

1. Global Variables
2. Local Variables
3. Class Variables
4. Instance Variables

### Global Variables
Global Variables start with a dollar sign. They are assigned globally within the program and can also be accessed from anywhere within the program. 

In the example below, `$favorite_season` is a global variable and can be accessed by the `print_favorite_season` method.

```ruby
$favorite_season = "Summer"

def print_favorite_season
    puts "My favorite season is #{$favorite_season}."
end

print_favorite_season #=> "My favorite season is Summer."
```

In the example below, `$least_favorite_season` is a global variable that is not initialized (is not set to a value). In ruby, this returns `nil` instead of throwing an error.

```ruby
$least_favorite_season 

puts $least_favorite_season.inspect #=> `nil`
```

### Local Variables
Local Variables start with a lowercase or an underscore. Any local variable defined inside of a method is not available outside of that specific method. In the example below, we are able to access `favorite_season` only inside the method it is defined in but not outside of `print_favorite_season`.

```ruby
def print_favorite_season
    favorite_season = "Summer"
    puts "My favorite season is #{favorite_season}."
end

print_favorite_season #=> "My favorite season is Summer."

favorite_season #=> undefined local variable or method 
```

If a local variable is defined outside of a specific method, then it is also not accessible inside of the method. So in the example below, the method `print_favorite_season` is not able to access the local variable `favorite_season`.

```ruby
favorite_season = "Summer"

def print_favorite_season
    puts "My favorite season is #{favorite_season}."
end

print_favorite_season #=> undefined local variable or method 
```

In ruby, if a local variable is not initialized, it will returns `nil` instead of throwing an error. Here is an example.

```ruby
def _print_local_var
    uninitialized_local_var = 
    puts uninitialized_local_var.inspect
end

_print_local_var #=> nil
```

### Class Variables
Class Variables start with two at symbols. They are initialized inside the class before they can be used within the program. Once initialized, they are accessible anywhere within the program where the class they are related to is being used. 

In the example below, we see the class variable `@@num_of_todo_items` being accessed globally and locally within the context of the single class that it was assigned to.

```ruby
class Todo
    @@num_of_todo_items = 0

    def initialize
        @@num_of_todo_items += 1
    end

    def self.count
        puts @@num_of_todo_items
    end
     
end

to_do1 = Todo.new
to_do2 = Todo.new 

Todo.count #=> 2
```
If a class variable is uninitialized, then it will result in an error.

```ruby
class Test
    @@uninitialized_class_var
    puts @@uninitialized_class_var
end

#=> uninitialized class variable @@uninitialized_class_var
```

### Instance Variables
Instance Variables start with an at symbol. They are similar to class variables when it comes to scope. What makes them different is that their values are local to the instances of a certain class or object. 

In the example below, we are defining an instance variable called `@todo_item` and setting it to an instance of the `Todo` class called `todo_item`. We are able to access `@todo_item` in a new method called `display_todo_item`.

```ruby
class Todo
     
    @@num_of_todo_items = 0

    def initialize (todo_item)
        @todo_item = todo_item
    end

    def display_todo_item
        puts @todo_item
    end
end

to_do1 = Todo.new("clean house")
to_do2 = Todo.new("practice Ruby")

to_do1.display_todo_item #=> "clean house"
to_do2.display_todo_item #=> "practice Ruby"
```

Ruby does not require us to initialize instance variables and the instance variables will have a `nil` value when uninitialized. Here is an example.

```ruby
class TestInstanceVar
    @uninitialized_instance_var
    puts @uninitialized_instance_var.inspect #=> nil
end
```

## Constants
Constants are defined using all capital letters, are accessible globally, and are used to define values we expect to be constant (not change). If we try to re-assign the values of constants, ruby does not throw errors. However, it will give us a warning saying we are trying to re-assign the values of a constant. 

```ruby
SEASONS = ["spring", "summer", "fall", "winter"]
puts SEASONS #=> ["spring", "summer", "fall", "winter"]

SEASONS = "replacing the seasons array with a string"
puts SEASONS 
#=> warning: already initialized constant SEASONS 
#=> "replacing the seasons array with a string"
```
Similar to class variables, referencing an uninitialized constant produces an error.

```ruby
SEASON

puts SEASON.inspect #=> uninitialized constant SEASON
```

## Summary

Here is a quick way to identify constants and the different kinds of variables.

```
$global_variable

local_variable

_also_local_variable

@@class_variable

@instance_variable

CONSTANT
```