DEV Community

loading...

Ruby Variables & Objects, as a Python Dev

vickilanger profile image Vicki (she/her) ・3 min read

This is a continuation of Picking up Ruby Fast, as a Python Dev. Again, expect examples with minimal math


Everything is an object and there are so many different kinds of variables! Every day I look at Ruby I learn new things. I'm really enjoying it.

Objectification

Data Types == Instances of Classes

Each data type was created by a class. I guess this is probably the same in Python and other languages, but it's definitely not something I've thought about. So, somewhere there is a class that says what an int is. This feels very existential. It reminds me of this question I got from a student last month:

How did we program an editor to write programs if we didn't have a program to program programs?

Anyway, we can use the .class method to find out what each item is.

irb(main):189:0> 1.class
=> Integer
irb(main):190:0> 34.6.class
=> Float
irb(main):191:0> "Mouse".class
=> String
Enter fullscreen mode Exit fullscreen mode

The same works for variables.

irb(main):192:0> cat = 78
=> 78
irb(main):193:0> cat.class
=> Integer

irb(main):194:0> dog = "Wiley"
=> "Wiley"
irb(main):195:0> dog.class
=> String
Enter fullscreen mode Exit fullscreen mode

Variable Types

Turns out, Ruby has 4 types of variables. Who knew? Okay, I'm sure lots of people did, but I didn't.

local

These are variables that are likely to be used quickly. If created outside of a class, method, or block they cannot be pulled into a method or anywhere else for that matter. Most of the examples I've had were using local variables.

The iterator variables used in blocks are also local variables as they can't be used after the end of the block.

global

Global variables start with $. These variables can be created outside of a method, in a class, or anywhere and then it can be used anywhere.

Here's global variable that we are going to send to the method greet:

$language = "Ruby"  # hey look, a global var

def greet
  puts "we're learning " + $language
end

# running & output
irb(main):218:0> greet
we're learning Ruby
Enter fullscreen mode Exit fullscreen mode

class

Class variables start with @@. These variables can be used inside the class and by all instances of the class. These are for classes to save info about themselves. It seems these aren't used very often. Class variables are limited in usefulness because all instances of the class share that one variable.

class Player
    @@moves = 9

    def initialize(name, letter='x')
        @name = name
        @letter = letter
    end

    def mark_spot letter
        if @@moves > 0
            @@moves -= 1
            puts "drew an #{letter}! Moves left: #{@@moves}"
        else
            puts 'no more spells'
        end
    end
end

# running & output
irb(main):231:0> wiley = Player.new("Wiley", "x")
=> #<Player:0x00007fcee80dd838 @name="Wiley", @letter="x">
irb(main):232:0> cheeto = Player.new("Cheeto", "o")
=> #<Player:0x00007fcee8101cd8 @name="Cheeto", @letter="o">
irb(main):235:0> wiley.mark_spot "x"
drew an x! Moves left: 8
=> nil
irb(main):236:0> cheeto.mark_spot "o"
drew an o! Moves left: 7
=> nil
Enter fullscreen mode Exit fullscreen mode

The problem here is that both players are sharing the @@moves. It may work in this example, but it often won't.

instance

Instance variables start with @. Instance variables are seen inside the class and by all instances of the class. However, each instance of a class gets its very own copy of the variable. Each instance doesn't have to share with other instances.

In the class variable, I gave a total number of moves, but in reality, most games allow each person to take the same amount of move. So, player1 would have 5 moves and player2 would have 5 moves. Then, we'd go until the game ends. We wouldn't typically share a pool of movies.

class Player

    def initialize(name, letter='x')
        @name = name
        @letter = letter
        @moves = 5
    end

    def mark_spot letter
        if @moves > 0
            @moves -= 1
            puts "drew an #{letter}! Moves left: #{@moves}"
        else
            puts 'no more spells'
        end
    end
end

# running & output
irb(main):239:0> remmy = Player.new "Remmy", 'x'
=> #<Player:0x00007fcee40f9780 @name="Remmy", @letter="x", @moves=5>
irb(main):240:0> puppy = Player.new "Puppy", 'o'
=> #<Player:0x00007fcee4100058 @name="Puppy", @letter="o", @moves=5>
irb(main):241:0> puppy.mark_spot 'o'
drew an o! Moves left: 4
=> nil
irb(main):242:0> remmy.mark_spot 'x'
drew an x! Moves left: 4
=> nil
irb(main):243:0> puppy.mark_spot 'o'
drew an o! Moves left: 3
=> nil
Enter fullscreen mode Exit fullscreen mode

This works much better because now each player has their own set of moves.


If you missed the first post in this series, I've heard it's a good read and there's cats.

Discussion (0)

pic
Editor guide