Ruby under a microscope - Objects and classes
In Ruby every value is an object and all Ruby programs consist of a set of objects and the messages sent between them.
Ruby saves custom objects in a C structure called RObject. Internally Ruby always refers to any value with a VALUE pointer. RObject contains a RBasic structure. In RObject Ruby saves an array of instance variables that each object contains using numiv and ivptr a pointer to an array of values.
2.7.2 :001 > class Mathematician 2.7.2 :002 > attr_accessor :first_name 2.7.2 :003 > attr_accessor :last_name 2.7.2 :004 > end => nil 2.7.2 :005 > euler = Mathematician.new => #<Mathematician:0x00007fb8411230a8> 2.7.2 :006 > euler = Mathematician.new => #<Mathematician:0x00007fb8410c8860> 2.7.2 :007 > euler = Mathematician.new => #<Mathematician:0x00007fb841062010> 2.7.2 :008 > euler.first_name = 'Leonhard' => "Leonhard" 2.7.2 :009 > euler.last_name = 'Euler' => "Euler" 2.7.2 :010 > euler => #<Mathematician:0x00007fb841062010 @first_name="Leonhard", @last_name="Euler">
IRB also displays the instance array and the VALUE pointer.
Every Ruby value including basic data types as integers, strings and symbols is a value. The Ruby source code refers to this internally as a generic types. This are not using RObject structure. They use different structures such as RString, RArray, RRegex. RObject is used only to save the custom object classes
Simple Ruby vales like small integers or symbols don’t require a structure at all, they are placed inside the VALUE pointer. In fact these are not pointers are values themselves.
RClass structure stores a list of all methods defined in a class in method table and an attribute name.
A Ruby class is a Ruby object that also contains method definitions and attribute names.
Ruby implements single inheritance by allowing to optimally specify a superclass. If there is none defined Ruby assigns the Object class as a superclass.
Class Instance Variables vs Class Variables
Creating a class instance variable using @ in context of a class rather than an object
class Mathematician @type = "General" def self.type @type end end puts Mathematician.type => General
Creating a class variable using @@ notation.
class Mathematician @@type = "General" def self.type @@type end end puts Mathematician.
When we create a class variable Ruby creates a single value for use in that class and any subclasses. Using a class instance variable causes Ruby to create a separate value for each class or subclass.
Internally Ruby saves both in the same table in RClass structure. The extra @ symbol allows Ruby to make the difference between 2 types of variables.
Constants must start with capital letters and they are valid in the scope of the current class. Ruby allows you to change a constant value but will display a warning.
Each time we create a new class Ruby creates two classes. The first class is the new class created, Ruby creates a new RClass structure to represent the class. Internally Ruby creates a second class hidden, called metaclass, in order to save any class methods that might be added later. Ruby sets the metaclass to be the class of the new class. Sets the klass pointer of the new RClass structure to point to the metaclass.