Metaprogramming is a programming technique in which computer programs have the ability to treat programs as their data. It means that a program can be designed to read, generate, analyze or transform other programs, and even modify itself while running.(wikipedia)
Using simple code samples let's give basic start to metaprogramming which helps to relate how code base can be simplified.
Considering the below class.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee | |
attr_accessor :emp_id, :emp_name, :emp_designation, :emp_department | |
end | |
emp_data = { emp_id: 1, emp_name: "Employee1", emp_designation: "Level1", emp_department: "Manufacturing"} | |
emp_obj = Employee.new | |
emp_obj.emp_id = emp_data[:emp_id] | |
emp_obj.emp_name = emp_data[:emp_name] | |
emp_obj.emp_designation = emp_data[:emp_designation] | |
emp_obj.emp_department = emp_data[:emp_department] | |
puts emp_obj.inspect | |
Output: | |
#<Employee:0x007f8bb0910b20 @emp_id=1, @emp_name="Employee1", @emp_designation="Level1", @emp_department="Manufacturing"> |
Now, using some metaprogramming concepts above code can be modified, notice the assign_attributes method used while the o/p in both the examples is same
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee | |
attr_accessor :emp_id, :emp_name, :emp_designation, :emp_department | |
def assign_attributes(emp_data) | |
emp_data.each do |k,v| | |
self.send("#{k}=", v) | |
end | |
end | |
end | |
emp_data = { emp_id: 1, emp_name: "Employee1", emp_designation: "Level1", emp_department: "Manufacturing"} | |
emp_obj = Employee.new | |
emp_obj.assign_attributes(emp_data) | |
puts emp_obj.inspect | |
Output: | |
#<Employee:0x007fb959904768 @emp_id=1, @emp_name="Employee1", @emp_designation="Level1", @emp_department="Manufacturing"> |
Adding some more examples, below simple code helps to generate methods on the fly instead of defining in individually
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee | |
attr_accessor :emp_id, :emp_name, :emp_designation, :emp_department | |
def assign_attributes(emp_data) | |
emp_data.each do |k,v| | |
self.send("#{k}=", v) | |
end | |
end | |
end | |
emp_data = { emp_id: 1, emp_name: "Employee1", emp_designation: "Level1", emp_department: "Manufacturing"} | |
emp_obj = Employee.new | |
emp_obj.assign_attributes(emp_data) | |
puts emp_obj.inspect | |
Output: | |
#<Employee:0x007fb959904768 @emp_id=1, @emp_name="Employee1", @emp_designation="Level1", @emp_department="Manufacturing"> |
Metaprogramming should be used with caution and not make the code complicated and difficult to read. It should be easy to understand and modular to change in future.
Comments
Post a Comment