Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Solution
3.
Frequently Asked Questions
3.1.
What distinguishes a class from an instance in Ruby?
3.2.
Ruby allows modules to inherit from classes?
3.3.
In Ruby, what distinguishes a module from a class?
3.4.
How do Ruby classes function?
4.
Conclusion
Last Updated: Mar 27, 2024

Listening for Changes to a Class

Author Mayank Goyal
0 upvote

Introduction

You wish to be informed if a class' definition changes. Keep a record of any new methods that are introduced to the class, as well as any existing methods that are changed or become undefined. It can also be helpful to be informed when a module is added to a class.

Solution

The class methods method added, method removed, and method undefined should be defined.

Ruby will pass the class's symbol into the relevant callback function whenever a method is added, removed, or left undefined.

The following sample emits a message each time a method is created, removed, or declared undefined. It throws an exception if the method essential is deleted, redefined, or left undefined:

class Tracker
 def important
 "This is an important method!"
 end
 def self.method_added(sym)
 if sym == :important
 raise 'The "important" method has been redefined!'
 else
 puts %{Method "#{sym}" was (re)defined.}
 end
 end
 def self.method_removed(sym)

raise 'The "important" method has been removed!'
 else
 puts %{Method "#{sym}" was removed.}
 end
 end
 def self.method_undefined(sym)
 if sym == :important
 raise 'The "important" method has been undefined!'
 else
 puts %{Method "#{sym}" was removed.}
 end
 end
end


When a new method is added to the class, the following message is printed:

class Tracker
 def new_method
 'This is a new method.'
 end
end
# Method "new_method" was (re)defined.


You can make a stink (more accurately, an exception) if someone modifies the required method, but you can't stop someone from doing so without freezing the class:

class Tracker
 undef: important
end
# RuntimeError: The "important" method has been undefined!


We've defined the class methods (method added, method removed, and method undefined) in the Tracker class are hook methods. When specific criteria are met, some other piece of code (in this case, the Ruby interpreter) knows to call any methods with that name. Nothing extraordinary typically occurs when a method is created, withdrawn, or left undefined because the Module class specifies these methods with empty bodies.

Because of the previous code, if our Tracker class later mixes in a module, we won't be informed. We won't learn anything about the module itself or the new techniques made possible by its inclusion:

class Tracker
 include Enumerable
end
# Nothing!


Detecting module inclusion is trickier. Every time a module is combined with a class in Ruby, the hook function Module#included is invoked on the module. On the other hand, we desire a hook method that is called on a specific class each time it includes a module. We must define our hook function because Ruby doesn't have one for module inclusion. To accomplish this, we must modify Module#include directly:

class Module
alias_method :include_no_hook, :include
def include(*modules)
 # Run the old implementation.
 include_no_hook(*modules)
 # Then run the hook.
 modules.each do |mod|
 self.include_hook mod
 end
end
def include_hook
 # Do nothing by default, just like Module#method_added et al.
 # This method must be overridden in a subclass to do something useful.
end
end


When a module is added to a class, Ruby will invoke the include hook method of that class. If we create a Tracker#include hook method, Ruby will alert us when an inclusion occurs:

class Tracker
 def self.include_hook(mod)
 puts %{"#{mod}" was included in #{self}.}
 end
end
class Tracker
 include Enumerable
end
# "Enumerable" was included in Tracker.

Frequently Asked Questions

What distinguishes a class from an instance in Ruby?

A method in Ruby gives an Object functionality. While an instance method only functions for one class instance, a class method provides functionality to the entire class. The class itself and a method on an instance cannot be called directly from a class method.

Ruby allows modules to inherit from classes?

The Ruby class Class provides features like instantiation, attributes, and other things you would typically imagine a class would have by inheriting from Module. Modules can be seen in some respects like classes because they are figuratively an ancestor of Class.

In Ruby, what distinguishes a module from a class?

What differentiates a class from a module? Methods and constants are gathered in modules. They are unable to produce instances. Classes have a per-instance state and can produce instances (objects) (instance variables).

How do Ruby classes function?

A class in Ruby is an object that specifies a template for building other objects. Its classes define the methods that can be used in any class. A method on a class is turned into an instance method when it is defined inside. Any subsequent instances of that class will be able to use that method.

Conclusion

In this article, we learned about how to make changes within a class and how to get notified. That’s all from the article. I hope you all like it.

If you want to learn more, check out our articles on Object Marshalling in RubyTainting Objects in RubyCopying Objects In RubyHow To Invoke Global Functions In Ruby?, and Object References in Ruby.

Do upvote our blogs if you find them helpful and engaging!

Happy Learning, Ninjas!

Live masterclass