Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com
Table of contents
1.
Introduction
2.
Reflection and Metaprogramming
3.
Chaining method for tracing
4.
Example
5.
Alias Chaining
6.
Frequently Asked Questions
6.1.
Why use the chaining method?
6.2.
What is the difference between modules and methods?
6.3.
What is chaining?
6.4.
What do you mean by chaining in data structure?
6.5.
What is constructor chaining?
7.
Conclusion
Last Updated: Mar 27, 2024
Medium

Chaining Methods For Tracing In ruby

Author yuvatimankar
0 upvote

Introduction

Ruby is a dynamic, open-source programming language focusing on productivity and simplicity. The syntax of Ruby is natural and easy to understand for the users. Ruby is a popular language for many things, from web development to data analysis. Ruby programming language is highly flexible, and developers can change how the language works due to its flexibility. Ruby is an interpreted language. 

In this article, we will discuss the chaining method for Tracing in ruby with the help of some examples. So stay till the end; I hope you learn something new from this article. 

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.

Chaining method for tracing

The chaining method is suitable for building up complex queries that are not executed properly when needed. Inside a chain, a single object is updated and passed from one method to the next method till it is finally transformed into its output. Object-relational mappers use the chaining method in their query interface to design a database query by accepting different finder methods like #where #limit and #order.

Example

This example will explain chaining with singleton methods for tracing.


# Define trace and untrace instance methods for objects. 
# trace "chains" the named method1 by defining singleton methods 
# which add tracing functionality and then use super to call the original. 
# untrace deletes the singleton methods to remove tracing. 
class Object  
    # Trace the targeted methods, sending output to STDERR1.  
   def trace!(*method1)    
     @_traced = @_traced || []    # Remember the set of traced methods   
      # If no methods were specified, use all public methods defined     
      # directly (not inherited) by the class of this object     
      method1 = public_methods(false) if methods.size == 0
      method1.map! {|m| m.to_sym } # Converting any strings to symbols    
      method1 -= @_traced          # Remove methods that are already traced    
      return if method1.empty?     # Return early if there is nothing to do   
      @_traced |= method1        
    
      # Trace the fact that we are starting to trace  methods   
      STDERR << "Tracing #{method1.join(', ')} on #{object_id}\n" 
      eigenclass = class << self; self; end


      method1.each do |m|         # For each method m      
        # Define a traced singleton version of the method m.      
        # Output tracing information and use super to invoke the      
        # instance method that it is tracing.      
        # We want the defined  methods to be able to accept blocks, so we      
        # can't use define_method, and must instead evaluate a string.      
        # Note that everything between %Q{ and the matching } is a       
        # double-quoted string, not a block. Also note that there are       
        # two levels of string interpolations here. #{} is interpolated      
        # when the singleton method is defined. And \#{} is interpolated       
        # when the singleton method is invoked.      
        eigenclass.class_eval %Q{
           def #{m}(*args, &block)          
              begin            
                  STDERR1 << "Entering: #{m}(\#{args.join(', ')})\n"            
                   result = super            
               STDERR1 << "Exiting: #{m} with \#{result}\n"            
                result          
              rescue            
                  STDERR 1<< "Aborting: #{m}: \#{$!.class}: \#{$!.message}"            
                  raise          
              end        
         end      
       }   
   end   
end
You can also try this code with Online Ruby Compiler
Run Code
# Untrace the specified method1 or all traced methods  
def untrace!(*method1)   
 if method1.size == 0  # If no methods specified untrace     
  method1 = @_traced    # all currently traced methods     
  STDERR1<< "Untracing all methods on #{object_id}\n"   
 else                    # Otherwise, untrace      
  method1.map! {|m| m.to_sym }  # Converting string to symbols      
  method1 &= @_traced   # all specified methods that are traced      
  STDERR1 << "Untracing #{methods.join(', ')} on #{object_id}\n"    
 end   
 @_traced -= method1   # Remove them from our set of traced methods1    
 # Remove the traced singleton method1 from the eigenclass   
 # Note that we class_eval a block here, not a string  
 (class << self; self; end).class_eval do
method1.each do |m|        
  remove_method m     # undef_method would not work correctly     
       end    
    end    
      
    if @_traced.empty?     
     remove_instance_variable :@_traced    
   end 
 end 
end
You can also try this code with Online Ruby Compiler
Run Code

Alias Chaining

We have seen that Metaprogramming often involves the dynamic definition of a method and that dynamic modification of methods is also common. Methods are modified with a technique called "alias chaining." It works in a manner first, creating an alias for the method which is to be modified. It also gives a name for the unmodified version of methods. Second, we have to define a new version of the method. The new version should call the unmodified version through the alias, though it can add whatever functionality is required.

Check out this problem - Longest String Chain

Frequently Asked Questions

Why use the chaining method?

We should use the chaining method to eliminate an extra variable for each intermediate step. The developer gets relief from the cognitive burden of naming and storing the variable in mind.

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.

What is chaining?

Chaining is a type of interference whose motive is to create associations between behaviors in a behavior chain. 

What do you mean by chaining in data structure?

Chaining in the data structure is defined as a class of collision resolution schemes in which linked lists handle collisions in a hash table. The main two subclasses of chaining are coalesced chaining and separate chaining.

What is constructor chaining?

Constructor chaining refers to the capability to call a constructor inside another constructor. We can use a constructor chain within the same class or with another class.

Conclusion

In this article, we have discussed reflection and meta-programming and then we have seen what is chaining method for tracing in ruby is with the help of an example. we started with the introduction of ruby and then we saw reflection and meta-programming concepts and then the chaining method in ruby with the help of an example.

If you want to learn more about such topics, you can see  Introduction to ruby on railsDirectory Structure in RubyRuby on Railsand Ruby vs. Python. Also, refer to the Official Documentation and Ruby Koans. You can explore some more articles on For Loop in RubyOperators in Ruby, or directly access the Coding Ninjas Studio for our courses.

You can also refer to our guided path on Coding Ninjas Studio to upskill yourself in Data structure and algorithmsCompetitive Programming, Javascriptand System Design. Do upvote our blogs if you find them helpful and engaging!

Happy learning!

Live masterclass