"We have always been at war with Eurasia": Class Variables in Ruby
Class variables! What are they, even.
Class variables are variables whose value changes across instances! You can recognize them because they are prepended with @@
.
But that definition is pretty opaque. Let’s use an example of a time when information gets uniformly (and rapidly) changed!
With apologies to anyone who’s read 1984 more recently than – aw geez – almost 20 years ago, here’s a spoiler-less summary of what you need to know to follow along:
In 1984 there’s this concept called Doublethink, wherein the people manage to basically avoid contradictory thought. The government fights a perpetual war alongside or against one of two other states – Eurasia and Eastasia. The history books are re-written every time an alliance changes, hence the doublethink-inspired idiom, “We have always been at war with Eastasia.”
We can imagine this rewriting of history with Ruby’s class variables because changing the value of a class variable changes across all instances of that class. You see:
class Doublethink
@@always_at_war_with = "Eurasia"
# returns the value of @@always_at_war_with
# when we begin, it's Eurasia
def always_at_war_with()
@@always_at_war_with
end
# sets the value of @@always_at_war_with
# we can change this arbitrarily,
# as you will see
def enemy(them)
@@always_at_war_with = them
end
end
# let's write a history book
history_book = Doublethink.new
history_book.always_at_war_with # => "Eurasia"
# what do the newspapers say?
newspaper = Doublethink.new
newspaper.always_at_war_with # => "Eurasia"
# oh but wait
newspaper.enemy("Eastasia")
# now who are we always at war with?
# let's ask the newspaper
newspaper.always_at_war_with # => "Eastasia"
# and what does our history book tell us?
history_book.always_at_war_with # => "Eastasia"
# what about a new history book we just wrote?
new_history_book = Doublethink.new
new_history_book.always_at_war_with # => "Eastasia"
# and if our new history book determines
# we've always been at war with Eurasia, guess what?
new_history_book.enemy("Eurasia")
new_history_book.always_at_war_with # => "Eurasia"
history_book.always_at_war_with # => "Eurasia"
newspaper.always_at_war_with # => "Eurasia"
We can go back and forth like this indefinitely. (It’s a perpetual war, after all.) There isn’t a single instance of the class Doublethink that won’t have a uniform value for the class variable @@always_at_war_with
. Cool, right?
You can also do some Doublethink with instance variables, but that’s for another day:
class Doublethink
attr_reader :twoplustwo
def initialize()
@twoplustwo = 5
end
end
Thanks to Richo for helping me understand class variables (finally)