Metaprogramming in Ruby
Mayuri Pachpande
Software Developer
Neosoft Technologies
Ruby Features:
1. Object-Oriented
2. DRY
3. Metaprogramming
What is Metaprogramming?
Code that writes code
Metaprogramming is the writing of computer programs with the ability to treat programs as their data.
It means that a program could be designed to read, generate, analyze, or transform other programs
and even modify itself while running.
Aspects of Metaprogramming
1. Introspection
2. Sending Messages
3. Classes are always open
4. Dynamic Methods
Introspection
Introspection - Ask questions about or look inward
In ruby, we can ask questions to our code during runtime: Some methods are as
listed below:
1. respond_to?
2. ancestors
3. instance_variables
4. Methods
5. inspect
Sending Messages
We often invoke a method on an object in Ruby
“Ruby on Rails”.upcase
Here as we invoke ‘upcase’ method on String object we actually are sending a
message to the object
Here we can break as below:
1. The string “Ruby on Rails” is the object which will receive the message.
2. The dot (‘.’) tells the string object that we will be sending some message.
3. ‘Upcase’ is the message.
Sending Messages
Types of dynamic method calls:
1. send
2. method().call
3. eval
Above ways of calling a method allows us to call a method dynamically.
Classes are always open
1. Classes are never closed.
2. Applies to the classes you write as well as the standard, built-in classes.
3. It’s simple - Open up a class definition for an existing class, and add the new
contents.
Using instance_eval and class_eval
1. Class statements within a method - Not allowed.
2. instance_eval / class_eval take a block or a string of code to be evaluated.
3. Has self set to that of the object you’re operating on.
4. Opens the class in method definition.
instance_eval
1. Defined methods - added inside singleton class of the object.
2. Does not allow to declare anything else than instance methods.
class_eval
1. Methods are added to the class
2. Allow attr_accessor etc
Dynamic Methods
Ruby provides us a method named ‘define_method’ from Module class.
The method accepts two arguments:
1. String / Symbol
2. Block
Dynamic Methods
When a particular method is not defined, ruby invokes ‘method_missing’ method
We can define this method in our class to define the required methods
dynamically.
method_missing accepts three arguments:
1. Method name
2. Arguments
3. Block
remove_method & undef_method
To remove existing methods
1. remove_method - removes method within the scope of a given class. If a
method with the same name is defined for an ancestor of that class, the
ancestor class method is not removed.
2. undef_method - prevents the specified class from responding to a method
call even if a method with the same name is defined in one of its ancestors.
Conclusion
1. Fantastic but only when it is used sparingly.
2. Helps to keep your code DRY.
3. Generate code based on user inputs.
4. Mock test data.
5. Helps in debugging.
References
https://www.sitepoint.com/ruby-metaprogramming-part-i/
https://www.sitepoint.com/ruby-metaprogramming-part-ii/
https://www.toptal.com/ruby/ruby-metaprogramming-cooler-than-it-sounds
https://blog.codeship.com/metaprogramming-in-ruby/