As we already know, Ruby is a dynamic programming language, which means we can insert new methods into classes at runtime and define methods on individual objects. Also, it has a rich API for Reflection. Reflection means a program can evaluate its state and its structure. So we will discuss these topics in detail, in this article. I hope you can learn something new from this article. Let's get started with Types, Classes, and Modules in Ruby.
Reflection and Metaprogramming
Reflection simply means that a program can evaluate its state and its structure. The reflection API allows a program to change its state and structure. The ruby's reflection API, its dynamic nature, and control structures make it a perfect language for Metaprogramming. Metaprogramming is defined as writing programs or frameworks that help us to write programs. Metaprogramming connects closely to the idea of writing domain-specific languages(DSLs). The domain-specific language uses method invocations and blocks like they were keywords in a task-specific extension to the language.
Class is nothing but a blueprint of objects in an object programming language. An object is also known as an instance of a class. The most widely used methods are those for identifying the type of objects, which means what Class it is an instance of and in which methods it responds. Types of classes present in ruby are as follows:
Method
Explanation
o.class
This class returns the class of an object o.
c.superclass
This class returns the superclass of class c.
o.instance_of? c
This class determines whether the object o.class == c.
o.is_a? c
This class determines whether o is an instance of either c or any subclasses of c. And if c is a module, these methods examine whether o.class includes the modules.
o.kind_of? c
In this class, kind_of? Is it a thesaurus of is_a?
c === o
This class for any modules or class identifies if 0.is_a? (c).
o.respond_to? name
This class determines whether the object o has a protected or public method with the specified name.
Defining Classes and Modules
We can create Classes and Modules dynamically. Classes and modules are instances of the Class and Module classes. We will create classes and modules dynamically below:
M = Module.new # Define a new module M
C = Class.new # Define a new class C
D = Class.new(C) { # Define a subclass of C include M # that includes module M
}
D.to_s # => "D": class gets the constant name by magic
You can also try this code with Online Ruby Compiler
One great feature of Ruby programming language is that when we assign a constant to a dynamically created anonymous Module or Class, the name of that constant is used as the name of the Module or Class.
Modules in ruby
Modules are a collection of methods, constants, and class variables. The thing to keep in mind about modules is that we cannot inherit modules, or we cant create a subclass of a module. Also, All the classes are modules, but all the modules are not classes.
Syntax:
module Module_name
. . . code
end
You can also try this code with Online Ruby Compiler
module Ninja
C = 7;
# Prefix with name of Module
# module method
def Ninja.portal
puts "Welcome to Coding Ninjas Portal!"
end
# Prefix with the name of Module
# module method
def Ninja.tutorial
puts "Ruby Tutorial!"
end
# Prefix with the name of Module
# module method
def Ninja.topic
puts "Topic - modules in ruby"
end
end
# displaying the value of
# module constant
puts Ninja::C
# calling the methods of the module
Ninja.portal
Ninja.tutorial
Ninja.topic
You can also try this code with Online Ruby Compiler
7
Welcome to Coding Ninjas Portal!
Ruby Tutorial!
Topic - modules in ruby
Ancestry and Modules
In addition to the above methods, there are few related reflective methods to determining the ancestors of a class or module and for determining which modules are included by a class or module. These methods are easy to understand when demonstrated:
module X; end # Empty module
module Y; include X; end; # Module Y includes X
class Z; include Y; end; # Class Z includes module Y
Z < Y # => true: Z includes Y
Y < X # => true: Y includes X
Z < X # => true
Fixnum < Integer # => true: all fixnums are integers
Integer < comparable # => true: integers are comparable
Integer < Fixnum # => false: not all integers are fixnums
String < Numeric # => nil: strings are not numbers
X.ancestors # => [X]
B.ancestors # => [B, X]
Z.ancestors # => [Z, Y, X, Object, Kernel]
String.ancestors # => [String, Enumerable, Comparable, Object, Kernel]
# Note: Ruby 1.9 String is no longer Enumerable
Z.include?(B) # => true
Z.include?(X) # => true
Y.include?(X) # => true
X.include?(X) # => false
X.include?(B) # => false
X.included_modules # => []
Y.included_modules # => [X]
Z.included_modules # => [Y, X, Kernel]
You can also try this code with Online Ruby Compiler
Modules are collections of constants and methods; they cannot generate instances. while Class may generate instances or objects and also have instance variables.
Can a module include a module Ruby?
Yes, a module can be included in the other modules or classes; we have to just use some keywords such as include, prepend and extend.
What is the difference between an object and a class in Ruby?
The difference between an object and a class is that an object is a unit of data while a class is what kind of data it is.
What is class self in Ruby?
A class self method in ruby is a method that refers only to that Class in all contexts but not to any individual objects of that class.
What is the difference between modules and methods?
The method is a function that is related to an object or class, while a module is a group of defined functions, classes, constants, etc.
Conclusion
In this article, we discussed Reflection and Metaprogramming, types, classes, and modules in ruby. We started with the introduction of Reflection and Metaprogramming, and then we have seen types, classes, and modules in ruby with the help of some examples.