Ruby, SmallTalk, and Class Variables
The article is a translation of Pat Shaughnessy's note, originally sounding like Ruby, Smalltalk and Class Variables . Ernie Miller’s article a
couple of weeks ago led me to the question: how do class variables work in Ruby? After a little research, it turned out that class variables can be a potential source of problems. In fact, John Nunemaker has already written an article called Class and Instance Variables in Ruby , which dates from 2006 and remains relevant now. The fundamental problem with class variables is that they are shared between the class itself and all its subclasses - as John explained six years ago, and this can lead to confusion and strange code behavior.
For me, the main question is: “Why?”. Why does Ruby share this value between all subclasses? Why is there a difference between class variables and instance variables? Where do these ideas come from? It turns out the answer is simple: class variables work just as they did in a much older language called Smalltalk . Smalltalk was invented in the early 1970s by the renowned computer scientist Alan Kay and a group of colleagues working in the Xerox PARC lab. With the invention of Smalltalk, Allan did not just invent a programming language; he came up with the whole concept of Object Oriented Programming (OOP) and first implemented it. Although not widely distributed now, Smalltalk has influenced many other object-oriented languages that are widely distributed today - the most important of which are Objective C and Ruby.
Today I want to take a look at how class variables work in Smalltalk, and compare in contrast how they work in Ruby. You will see that the idea of class variables is not the only borrowing from Smalltalk. Most of Ruby's object model was also taken from Smalltalk.
First, let's take a look at what class variables are and how they work in Ruby, using the 2006 John Nunmaker example : here is a simple Ruby class
This example is pretty simple:
On a conceptual level, inside, Ruby associates a variable

Troubles begin when you define a subclass; another example of John:
Note that both class variables,

I can write in more detail about the internal implementation of class variables in Ruby in the next post of my blog, but for now I will use the simplest diagrams. Instead, let's switch and learn a little more about Smalltalk ...
As I said above, Alan Kay invented Smalltalk at the same time as object-oriented programming when he worked at Xerox PARC in the early 1970s. This is the same laboratory that invented the personal computer, graphical user interface, and Ethernet and many many other things. Against this background, the invention of OOP seems the least important of the inventions!
At Smalltalk, Kay offered terminology and ideas for granted today. Each value in Smalltalk, including language constructs such as blocks, is an object. The Smalltalk program consists of these objects and their interaction paths; to call a specific function on Smalltalk, you 'send a message' to an object that implements this function. In Smalltalk, functions are called 'methods'. An object implements a series of methods. All this should sound very similar, of course.
From the very beginning, the OOP Kay concept included the idea of 'class' objects. Object classes have been described as a series of behaviors (methods), each instance of which could be called. Smalltalk also implemented the concept of polymorphism, which allows the developer to define 'subclasses' and inherit the behavior of their 'superclasses'. All of these concepts, which we often use today, were invented by Kay and his colleagues 40 years ago.
Smalltalk, however, more than a programming language, is a complete graphical development environment. I consider Smalltalk a harbinger of Visual Studio and Xcode, developed when Microsoft and Apple did not even exist, in a world where computers were used only for academic or government purposes. Another impressive goal of Alan Kay and the Smalltalk team, originally set, was to use their visual environment to educate children in schools. This is a truly amazing story!
To learn more about the history and origin of Smalltalk, I highly recommend reading the 'Early History of Smalltalk' ( html , or pdf , or pdf but without diagrams)), a retrospective review by Kay was written later in the 1990s. This is a fascinating story about how Kay and his colleagues borrowed ideas from even the earlier past, but their combination was hard work, creative, where pure talent managed to take a huge step forward and make a revolution in the computer science world of their days, as well as ours.
Alan Kay created the first working version of Smalltalk in 1972 - in his own words, this is how it happened:
I expected the new Smalltalk to be a symbolic language, and its development would take at least two years, but fate intervened in the plans. One fine day, during a typical male conversation in the hallway of PARC, Ted Koehler, Dan Ingalls and I stood and talked about programming languages. The time has come to discuss the power of the language and now they are interested in how to make the language super powerful. Drawing in front of them, I said that “the most powerful language in the world” they can capture “in the code pages”. Their cue was: "create or shut up." Ted went back to CMU, but Dan was still there and kept pushing me further. The next two weeks, I came to PARC at four in the morning and worked until eight, then Dan, together with Henry Fuchs, John Shoch, and Steve Purcell, began discussing morning work. I boasted in advance because the LISP interpreter by John McCarthy was written in LISP. It was about that same 'page with code', and over time, when the power of the language grew, it became everything for functional languages. I was absolutely sure that I could do the same for object-oriented languages.
Here Kay refers to John McCarthy , who invented LISP ten years earlier. It took Kay just eight mornings to complete the first version of Smalltalk:
The first few versions had flaws that were loudly criticized by the group. But by the eighth morning, or somewhere else, the code worked ...
I would like to be as creative, versatile and productive as Alan Kay and his colleagues in PARC were 40 years ago.
To find out how class variables directly work in Smalltalk, I installed GNU Smalltalk, a command line version of the language that is easy to download and run under Linux Box. At first, Smalltalk seemed very strange and unfriendly to me; its syntax is a bit strange at first glance. For example, remember every command to the end, and also, when defining a method, you need to specify only a list of arguments ... without a method name! I believe the first argument is the name of the method, or something like that. But after a couple of days I got used to a kind of syntax, and the language became more meaningful for me.
Here, the same Polygon class - Smalltalk code on the left, on Ruby on the right.
Further, a small explanation of what Smalltalk code does:
•
•
•
•
Besides the superficial syntax differences, if you take a step back and think, you will find how surprisingly similar Smalltalk and Ruby are! Both languages not only share the concept of class variables, but also write the Polygon class, declare a class variable and output the value in them the same. In fact, you can think of Ruby as the new version of Smalltalk with a simplified and more convenient syntax!
As I said above, Smalltalk shares class variables between subclasses, in the same way that Ruby does. Here is an example of how I declare a subclass of Triangle in Smalltalk and Ruby.
Here I declare a subclass of Triangle and its method to set the value of its class variable. Now, let's try changing its value from a subclass.
No surprises; By calling the set_slides class method (
Languages differ in one: Smalltalk allows you to create separate class variables for each subclass if you want to. If you continue to declare class variables and the method of accessing them in the parent class and its descendant, they will become separate variables. At least in GNU Smalltalk, which I use:
This is not so in Ruby. As we saw above, it
In Ruby, if you want to have separate values for each class, then you should use class instance variables instead of class variables. What does it mean? Let's take a look at another John Nunmaker example:
Now, when I use

Conceptually, there is no difference until I subclass the Triangle again:
Now the class owns its own copy of the meaning

Now, let's try the same in Smalltalk. In Smalltalk, to declare an instance variable, you call the instanceVariableNames method in the class:
In this example, I created a new class
Thus,
Once again, pay attention to two different code fragments (Ruby and Smalltalk), which execute the same commands in two different ways. In the Smalltalk, you write
Let's take another look at the lines of code that I used to create class instance variables in Smalltalk:
Translated from a programming language into Russian, this means:
• We take a class
• Send him a message called instanceVariableNames
• and pass the string

This is an example of how to create instance variables in Smalltalk. I will create instances of the class
As I explained above, to create a class instance variable in Smalltalk, you must use the 'class' keyword. For example, like this:
This code literally means the following: a method call
In the example, first, I infer a class object
Ah ... here it is. A class of a class is a metaclass. Above, when I called
The diagram below shows how all these classes relate in Smalltalk:

Now, it shouldn't come as a surprise that Ruby uses the same model. Here's how the classes are arranged inside Ruby:

In Ruby, whenever you create a class, Ruby creates an appropriate metaclass inside. Unlike Smalltalk, Ruby does not use this for class instance variables, but only for tracking class methods. Also, Ruby does not have a class
In Ruby, the metaclass is hidden, being a 'mysterious concept'. Ruby silently creates it without telling you this, and does not use it directly. In Smalltalk, however, metaclasses are not hidden and play a huge role in the language. Creating an instance variable of a class, as shown above, is just one example of using metaclasses in Smalltalk. Another good example is how you add class methods by calling
When you request a class for a class in Ruby, you simply get a Class. Ruby doesn't tell you anything about metaclasses:
To see Ruby's metaclass, try the following trick:
“#”- this is the metaclass of the Polygon class. This syntax denotes a `` Class instance for the Polygon class '' or a metaclass for Polygon.
couple of weeks ago led me to the question: how do class variables work in Ruby? After a little research, it turned out that class variables can be a potential source of problems. In fact, John Nunemaker has already written an article called Class and Instance Variables in Ruby , which dates from 2006 and remains relevant now. The fundamental problem with class variables is that they are shared between the class itself and all its subclasses - as John explained six years ago, and this can lead to confusion and strange code behavior.
For me, the main question is: “Why?”. Why does Ruby share this value between all subclasses? Why is there a difference between class variables and instance variables? Where do these ideas come from? It turns out the answer is simple: class variables work just as they did in a much older language called Smalltalk . Smalltalk was invented in the early 1970s by the renowned computer scientist Alan Kay and a group of colleagues working in the Xerox PARC lab. With the invention of Smalltalk, Allan did not just invent a programming language; he came up with the whole concept of Object Oriented Programming (OOP) and first implemented it. Although not widely distributed now, Smalltalk has influenced many other object-oriented languages that are widely distributed today - the most important of which are Objective C and Ruby.
Today I want to take a look at how class variables work in Smalltalk, and compare in contrast how they work in Ruby. You will see that the idea of class variables is not the only borrowing from Smalltalk. Most of Ruby's object model was also taken from Smalltalk.
Class Variables in Ruby
First, let's take a look at what class variables are and how they work in Ruby, using the 2006 John Nunmaker example : here is a simple Ruby class
Polygon
, which contains a single class variable @@sides
.class Polygon
@@sides = 10
def self.sides
@@sides
end
end
puts Polygon.sides
=>10
This example is pretty simple:
@@sides
- This is a variable that any class or class instance method has access to Polygon
. In the example, sides
is a class method that returns it. On a conceptual level, inside, Ruby associates a variable
@@sides
with the same piece of memory that the Polygon
class represents : 
Troubles begin when you define a subclass; another example of John:
class Triangle < Polygon
@@sides = 3
end
puts Triangle.sides
=>3
puts Polygon.sides
=>3
Note that both class variables,
Triangle.sides
and Polygon.sides
, have been changed to 3. In essence, Ruby creates the only variable within himself that both classes share: 
I can write in more detail about the internal implementation of class variables in Ruby in the next post of my blog, but for now I will use the simplest diagrams. Instead, let's switch and learn a little more about Smalltalk ...
What is Smalltalk?
As I said above, Alan Kay invented Smalltalk at the same time as object-oriented programming when he worked at Xerox PARC in the early 1970s. This is the same laboratory that invented the personal computer, graphical user interface, and Ethernet and many many other things. Against this background, the invention of OOP seems the least important of the inventions!
At Smalltalk, Kay offered terminology and ideas for granted today. Each value in Smalltalk, including language constructs such as blocks, is an object. The Smalltalk program consists of these objects and their interaction paths; to call a specific function on Smalltalk, you 'send a message' to an object that implements this function. In Smalltalk, functions are called 'methods'. An object implements a series of methods. All this should sound very similar, of course.
From the very beginning, the OOP Kay concept included the idea of 'class' objects. Object classes have been described as a series of behaviors (methods), each instance of which could be called. Smalltalk also implemented the concept of polymorphism, which allows the developer to define 'subclasses' and inherit the behavior of their 'superclasses'. All of these concepts, which we often use today, were invented by Kay and his colleagues 40 years ago.
Smalltalk, however, more than a programming language, is a complete graphical development environment. I consider Smalltalk a harbinger of Visual Studio and Xcode, developed when Microsoft and Apple did not even exist, in a world where computers were used only for academic or government purposes. Another impressive goal of Alan Kay and the Smalltalk team, originally set, was to use their visual environment to educate children in schools. This is a truly amazing story!
To learn more about the history and origin of Smalltalk, I highly recommend reading the 'Early History of Smalltalk' ( html , or pdf , or pdf but without diagrams)), a retrospective review by Kay was written later in the 1990s. This is a fascinating story about how Kay and his colleagues borrowed ideas from even the earlier past, but their combination was hard work, creative, where pure talent managed to take a huge step forward and make a revolution in the computer science world of their days, as well as ours.
Alan Kay created the first working version of Smalltalk in 1972 - in his own words, this is how it happened:
I expected the new Smalltalk to be a symbolic language, and its development would take at least two years, but fate intervened in the plans. One fine day, during a typical male conversation in the hallway of PARC, Ted Koehler, Dan Ingalls and I stood and talked about programming languages. The time has come to discuss the power of the language and now they are interested in how to make the language super powerful. Drawing in front of them, I said that “the most powerful language in the world” they can capture “in the code pages”. Their cue was: "create or shut up." Ted went back to CMU, but Dan was still there and kept pushing me further. The next two weeks, I came to PARC at four in the morning and worked until eight, then Dan, together with Henry Fuchs, John Shoch, and Steve Purcell, began discussing morning work. I boasted in advance because the LISP interpreter by John McCarthy was written in LISP. It was about that same 'page with code', and over time, when the power of the language grew, it became everything for functional languages. I was absolutely sure that I could do the same for object-oriented languages.
Here Kay refers to John McCarthy , who invented LISP ten years earlier. It took Kay just eight mornings to complete the first version of Smalltalk:
The first few versions had flaws that were loudly criticized by the group. But by the eighth morning, or somewhere else, the code worked ...
I would like to be as creative, versatile and productive as Alan Kay and his colleagues in PARC were 40 years ago.
Smalltalk Class Variables
To find out how class variables directly work in Smalltalk, I installed GNU Smalltalk, a command line version of the language that is easy to download and run under Linux Box. At first, Smalltalk seemed very strange and unfriendly to me; its syntax is a bit strange at first glance. For example, remember every command to the end, and also, when defining a method, you need to specify only a list of arguments ... without a method name! I believe the first argument is the name of the method, or something like that. But after a couple of days I got used to a kind of syntax, and the language became more meaningful for me.
Here, the same Polygon class - Smalltalk code on the left, on Ruby on the right.
|
|
Further, a small explanation of what Smalltalk code does:
•
Object subclass: Polygon
- this means sending a subclass of the message to the Object class and passing the name Polygon. This will create a new class, which is a subclass of the Object class. This is an analogy of the Ruby class Polygon <Object expression. Of course, in Ruby, specifying Object as a superclass is optional. •
Sides := 10.
- here a variable of the Sides class is declared, and a value is assigned to it. Ruby uses a different syntax: @@ sides. •
Polygon class extend
- here the Polygon class 'expands'; those. The Polygon class opens to give me the opportunity to add a class method. In Ruby, I use the construct: class Polygon; def self.sides •
printNl
The method displays the value to the console; this works in the same way as puts in Ruby, except that the printNl method is an object method Sides
. Imagine just a challenge @@sides.puts
in Ruby! Besides the superficial syntax differences, if you take a step back and think, you will find how surprisingly similar Smalltalk and Ruby are! Both languages not only share the concept of class variables, but also write the Polygon class, declare a class variable and output the value in them the same. In fact, you can think of Ruby as the new version of Smalltalk with a simplified and more convenient syntax!
As I said above, Smalltalk shares class variables between subclasses, in the same way that Ruby does. Here is an example of how I declare a subclass of Triangle in Smalltalk and Ruby.
|
|
Here I declare a subclass of Triangle and its method to set the value of its class variable. Now, let's try changing its value from a subclass.
|
|
No surprises; By calling the set_slides class method (
slides=
in Ruby), I can update the value. But since Triangle and Polygon share a class variable, this will change the Polygon class as well:
|
|
Languages differ in one: Smalltalk allows you to create separate class variables for each subclass if you want to. If you continue to declare class variables and the method of accessing them in the parent class and its descendant, they will become separate variables. At least in GNU Smalltalk, which I use:
Object subclass: Polygon [
Sides := 10.
]
Polygon class extend [
sides [ ^Sides ]
]
Polygon subclass: Triangle [
Sides := 3.
]
Triangle class extend [
sides [ ^Sides ]
]
Polygon sides printNl.
>= 10
Triangle sides printNl.
>= 3
This is not so in Ruby. As we saw above, it
@@sides
always refers to the same value.Class instance variables
In Ruby, if you want to have separate values for each class, then you should use class instance variables instead of class variables. What does it mean? Let's take a look at another John Nunmaker example:
class Polygon
def self.sides
@sides
end
@sides = 8
end
puts Polygon.sides
=> 8
Now, when I use
@sides
instead @@sides
, Ruby creates an instance variable of the class instead of the class variable: 
Conceptually, there is no difference until I subclass the Triangle again:
class Triangle < Polygon
@sides = 3
end
Now the class owns its own copy of the meaning
@sides
: 
Now, let's try the same in Smalltalk. In Smalltalk, to declare an instance variable, you call the instanceVariableNames method in the class:
|
|
In this example, I created a new class
Polygon
, a subclass of the class Object
. Then, I send a instanceVariableNames
message to this new class, telling Smalltalk to create a new instance variable called Sides
. And finally, I rediscover the class Polygon
and add the sides
method to it. Nearby, I wrote the corresponding code in Ruby. Thus,
Sides
they @sides
are instance variables of the Polygon class. To create a class variable in Smalltalk, you must send the class message to Polygon before calling instanceVariableNames
or extend
, as shown below:
|
|
Once again, pay attention to two different code fragments (Ruby and Smalltalk), which execute the same commands in two different ways. In the Smalltalk, you write
Polygon class extend [ sides
..., while in Ruby class Polygon; def self.sides
. Ruby seems to me to be a shorter form of Smalltalk.Metaclasses in Smalltalk and Ruby
Let's take another look at the lines of code that I used to create class instance variables in Smalltalk:
Polygon instanceVariableNames: 'Sides '!
Translated from a programming language into Russian, this means:
• We take a class
Polygon
• Send him a message called instanceVariableNames
• and pass the string
Sides
as a parameter. 
This is an example of how to create instance variables in Smalltalk. I will create instances of the class
Polygon
, and all of them will have a class instance variable Sides
. In other words, to create a class instance variable for each created polygon instance, I call the method on the class Polygon
. As I explained above, to create a class instance variable in Smalltalk, you must use the 'class' keyword. For example, like this:
Polygon class instanceVariableNames: 'Sides '!
This code literally means the following: a method call
instanceVariableNames
on the class class 'Polygon'. In a similar way, all instances of a class Polygon
will contain a class instance variable. But what does it mean: a 'Polygon class class' in Smalltalk? After spending a few moments in the GNU Smalltalk REPL, we find:$ gst
GNU Smalltalk ready
st> Polygon printNl.
=> Polygon
st> Polygon class printNl.
=> Polygon class
In the example, first, I infer a class object
Polygon
. Then, I try to find out what a class of the Polygon class is. And this is the 'Polygon class'. But what type of object is this? Let's call the class on it:st> Polygon class class printNl.
=> Metaclass
Ah ... here it is. A class of a class is a metaclass. Above, when I called
instanceVariableNames
to create a class instance variable, I actually used a metaclass Polygon
, an instance of the class Metaclass
. The diagram below shows how all these classes relate in Smalltalk:

Now, it shouldn't come as a surprise that Ruby uses the same model. Here's how the classes are arranged inside Ruby:

In Ruby, whenever you create a class, Ruby creates an appropriate metaclass inside. Unlike Smalltalk, Ruby does not use this for class instance variables, but only for tracking class methods. Also, Ruby does not have a class
Metaclass
, but instead of all metaclasses, creates instances of the class Class
.In Ruby, the metaclass is hidden, being a 'mysterious concept'. Ruby silently creates it without telling you this, and does not use it directly. In Smalltalk, however, metaclasses are not hidden and play a huge role in the language. Creating an instance variable of a class, as shown above, is just one example of using metaclasses in Smalltalk. Another good example is how you add class methods by calling
extend
. When you request a class for a class in Ruby, you simply get a Class. Ruby doesn't tell you anything about metaclasses:
$ irb
> class Polygon; end
> Polygon.class
Class
To see Ruby's metaclass, try the following trick:
$ irb
> class Polygon
> def self.metaclass
> class << self
> self
> end
> end
> end
=> nil
> Polygon.metaclass
=> #
“#