The definition of a class by the user is done with the "class" statement, followed by a block of statements containing the class body, with the class definitions. The class name is a constant, and must begin with an uppercase letter. The "class" statement is an expression and returns the last evaluated statement, usually a "def", returning: "nil".
When the statements defining the class are executed by the Ruby interpreter, the receiver, pointed by the keyword: "self" is the class itself, as an instance of "Class", but into the definition of instance methods "self" is the instance being created.
class Classname < Superclasse # class definition (inherits Superclasse) include Modulename,Othername # the class includes these modules include(OtherModulename) attr_accessor :x,:y # creation of accessor methods attr_reader :u,:w attr_reader "v","z" @@n=0 # a class variable def initialize(x,y=3) # class constructor @x,@y=x,y # instance variables # must initialized in the constructor super( a, b, c ) # calls the constructor of the parent end def self.classmethodname # definition of a class method ... end class << self # block containing class methods def nome(..) ... end end def metodo # definition of an instance method ..... end to_s # override of a function of a parent class "description class" end protected # section for protected methods here protected methods private # section for private methods here private methods end
The method named: "initialize" is the instance constructor; it is a special method, called in an automated way at the instance creation. In this method the variables needed by the instance are initialized.
In the example above the method "super" is used by "initialize" to call the constructor of the parent class, which is not automatically called at the instance creation.
The "<" symbol is for inheritance. Ruby has only single inheritance, but classes can include in their namespace functions and classes from modules (mixins). Each class inherits the class Object in an automated way, there is no need to specify this dependency.
The method: "super" can be used into a class function, to call the method of the parent with the same name of the function.
There are some methods to look at the structure of a class hierarchy:
Classname.superclass # show the inherited class Classname.ancestors # show all the inherited classes (ancestors) Classname.methods # show all the methods Classname.constants # show the constants defined in the class Classname.included_modules # list of the included modules Classname.include?(Nomemodulo) # tests if a module is included Classname.respond_to?("string") # tests if a method exists Classname.respond_to?(:symbol) # tests if a method exists, using a symbol
To instantiate a class the "new" method must be called; the "new" method has arguments that are passed to the class constructor: the "initialize" function.
instancename=Classname.new(argument, arg, arg2) instancename.instance_of? Classname # to test if instance of a class instancename.kind_of? Classname # to test if a class is among ancestors
each instance has an unique identifier, which can be obtained by the method: ".object_id".
In Ruby there are class methods and instance methods: class methods can only be called on classes and instance methods can only be called on an instance of a class.
But indeed, class methods also are instance methods: instance methods of that instance of Class which is the class definition.
The syntax for calling class and instance methods is:
Classname.classmethodname(..) # for class methods instance.methodname(..) # for instance methods
By default the methods are instance methods; in the class definition, class methods are prefixed with the keyword "self", or by the class name, but can also be defined in the class block, into a special block delimited by: "class << self ... end"
class Classe def Classe.func print("class method") end def self.func2 print("class method") end def func3 print("Instance method") end end class Classe2 class << self # other way to specify class methods def func class method end end end
The rule is that all variables defined in a class are private to the class and are not visible outside.
To make an instance variable accessible outside the class there are special function, (accessor functions) defined in a way similar to:
class A def var_a # read access ids done with: *A.var_a* return @var_a # using the function as the var_a name end def var_a=(v) # write access is done with: *A.var_a=123* @var_a=v # using the function as the var_a name, end # with omitted parenthesis end
The accessor statements automatically make these functions for the specified variables, allowing for a syntax like: "instancename.variable" , where "variable" is an accessor function which mimic the use of a instance attribute; but only functions and constants are visible outside a class instance, all variables are hidden.
Example of the accessor statement:
class Nomeclasse attr_accessor :x,:y # makes accessors for @x,@y attr_reader :z # makes a read accessor for @z def initialize(x,y) # constructor, called at object creation @x=x @y=y # initialization of instance variables end def to_s # used by print functions to obtain a "#@x,#@y" # string representing the instance end end # of class
Instance variables should be initialized in the constructor. The class itself (the class definition) is an instance of the object Class, and variables defined out of the constructor are instance variables of the class as an instance of the Class object.
To print an instance of a class one have to define a to_s method, that returns a textual representation of the instance. There are also a modules (PP, PrettyPrint) to print a class instance:
instancename= Nomeclasse.new(1,2) require 'pp' pp instancename # => 1,2
Methods can be added to a class outside the class block; to define a class method outside the class block the method has to be prefixed with the class name:
def Classname.classmethodname(..) .... end
A method belonging to a single instance of a class is named "singleton method, "numeric" and "symbols" can't have singleton methods. A singleton method can be added to a specific instance in the following way:
oggetto=Classname.new def oggetto.funzione(..) ... end
Also the following syntax can be used:
class << oggetto def func1(..) ... end def func2( ..) ... end end
In the following a simple example of definition and usage of a singleton method:
a="1" def a.nome print "uno" end a.nome => uno
The term singleton class is used in Ruby for class instances with singleton methods, which is not the same as the singleton classes of languages like C++, which are classes with a single instance ... here the term "singleton" is a bit confusing.
In Ruby, classes with a single instance are built with the "singleton" module, which, mixed into a class, changes the class method "new", which become private and impossible to call; the methods "instance" is used, instead of "new", to make, or refer to, the single instance of the class.