SlideShare a Scribd company logo
Metaprogramming Rails
@JustusEapen
What is “metaprogramming”?
Metaprogramming Rails
Metaprogramming is fun.
(dangerous)
Metaprogramming is usually
introspective or generative.
Introspection is code that tells you about code.
Generation is code that writes code.
When is this useful?
Introspection is useful all of the times.
Where is this method defined?
What classes inherit from this class?
What classes does this class inherit
from?
What classes include this module or
concern?
method(:method_name).source_locat
ion
Class.descendants
Class.ancestors
Oh crap. How do I do this again?
# How to get all the classes that include a module
concern :MyDopeModule do
def self.dope_classes
Rails.application.eager_load! # why is this important?
ActiveRecord::Base.descendants.select do |c|
c.included_modules.include?(MyDopeModule)
end
end
end
QUIZ:
Why should you not do that in
production?
Generative Methods be like...
Generative Methods are useful sometimes
I need to create many similar methods
I need to call methods dynamically
I need to dynamically set variables
I need to write a gem...
define_method(:foo) { do_something(foo) }
send(:method)
instance_variable_set(‘@var’, value):
# Getters and setters for an array attribute
# given an activerecord model with an array attribute
(1..5).each do |i|
define_method("attr_#{i}=".to_sym) do |val|
array[i] = val
save
end
define_method("attr_#{i}".to_sym) { take_aways[n] }
end
# File activerecord/lib/active_record/scoping/named.rb, line 143
def scope(name, body, &block)
unless body.respond_to?(:call)
raise ArgumentError, "The scope body needs to be callable."
end
if dangerous_class_method?(name)
raise ArgumentError, "You tried to define a scope named "#{name}" " "on the
model "#{self.name}", but Active Record already defined " "a class method with
the same name."
end
valid_scope_name?(name)
extension = Module.new(&block) if block
…
end
# File activerecord/lib/active_record/scoping/named.rb, line 143
def scope(name, body, &block)
...
if body.respond_to?(:to_proc)
singleton_class.send(:define_method, name) do |*args|
scope = all.scoping { instance_exec(*args, &body) }
scope = scope.extending(extension) if extension
scope || all
end
else
singleton_class.send(:define_method, name) do |*args|
scope = all.scoping { body.call(*args) }
scope = scope.extending(extension) if extension
scope || all
end
end
end
ActiveRecord be like:
Metaprogramming Rails
We can even get meta-meta
# To DRY on scoping by a virtual attribute on active record models
# Add this to a VirtualScopableConcern
def self.virtual_scope_by(*virtual_attrs)
virtual_attrs.each do |virtual_attr|
scope "by_#{virtual_attr}".to_sym, -> {
all.to_a.sort_by(&virtual_attr) }
end
end
virtual_scope_by [:virtual_attribute_1, :virtual_attribute_2]
QUIZ:
Why should you not do that in
production?
What else can I do with metaprogramming?
1. Write a DSL for markup
2. Modify classes on the fly
3. Make ridiculously long method calls
a. String.method(:new).call
4. Catch undefined methods
a. Method_missing
5. Binding.pry
6. Penetrate scopes (defy encapsulation)
7. What else?
Where can I learn more?
● Metaprogramming Ruby and Antipatterns in Rails by Eugene Wang
● Metaprogramming in Ruby: It's All About the Self by Yehuda Katz
● Metaprogramming Ruby (book) by Paolo Perrotta
● In IRB, write some code, run it.
Conclusions:
Recursion is the source of all power
and...
Danger can be fun!

More Related Content

ODP
OOP java
ODP
Beginners Guide to Object Orientation in PHP
PPT
Java Simple Notes
PPTX
Polymorphism presentation in java
PPTX
Polymorphism in java
DOCX
Java interview questions and answers for cognizant By Data Council Pune
PPSX
Java Object Oriented Programming
PPTX
Java(Polymorphism)
OOP java
Beginners Guide to Object Orientation in PHP
Java Simple Notes
Polymorphism presentation in java
Polymorphism in java
Java interview questions and answers for cognizant By Data Council Pune
Java Object Oriented Programming
Java(Polymorphism)

What's hot (20)

PDF
Polymorphism in Java
PPT
Super and final in java
PPTX
Java interview questions 1
PPTX
Php oop presentation
PPTX
2- Introduction to java II
PPTX
Learn To Code: Diving deep into java
PPTX
Std 12 computer chapter 8 classes and object in java (part 2)
PPTX
Inheritance and Polymorphism Java
PPTX
java - oop's in depth journey
PPTX
Object Oriented Programing JAVA presentaion
PPTX
oops concept in java | object oriented programming in java
PDF
Java OOP Programming language (Part 6) - Abstract Class & Interface
PPTX
5- Overriding and Abstraction In Java
PDF
Java basic concept
PPTX
Object oriented programming in java
DOCX
Static keyword u.s ass.(2)
PPT
An Introduction to C# and .NET Framework (Basic)
DOCX
Interview Questions and Answers for Java
PDF
6 class and methods
PPTX
Interface in java ,multiple inheritance in java, interface implementation
Polymorphism in Java
Super and final in java
Java interview questions 1
Php oop presentation
2- Introduction to java II
Learn To Code: Diving deep into java
Std 12 computer chapter 8 classes and object in java (part 2)
Inheritance and Polymorphism Java
java - oop's in depth journey
Object Oriented Programing JAVA presentaion
oops concept in java | object oriented programming in java
Java OOP Programming language (Part 6) - Abstract Class & Interface
5- Overriding and Abstraction In Java
Java basic concept
Object oriented programming in java
Static keyword u.s ass.(2)
An Introduction to C# and .NET Framework (Basic)
Interview Questions and Answers for Java
6 class and methods
Interface in java ,multiple inheritance in java, interface implementation
Ad

Similar to Metaprogramming Rails (20)

PPTX
Only oop
PPT
Intro Java Rev010
DOCX
Java notes
PDF
Java scjp-part1
DOCX
Viva file
PPT
Oops concepts in php
PDF
Understanding And Using Reflection
PDF
Java programming basics
PPTX
Object oreinted php | OOPs
PDF
Ruby tricks2
PPTX
Modules 333333333³3444444444444444444.pptx
PPT
SMI - Introduction to Java
PDF
1669617800196.pdf
PPTX
Application package
PPT
Andy On Closures
PPT
InheritanceAndPolymorphismprein Java.ppt
PPT
06 InheritanceAndPolymorphism.ppt
PPTX
L04 Software Design 2
PDF
Metaprogramming 101
PPTX
OOP-Advanced Programming with c++
Only oop
Intro Java Rev010
Java notes
Java scjp-part1
Viva file
Oops concepts in php
Understanding And Using Reflection
Java programming basics
Object oreinted php | OOPs
Ruby tricks2
Modules 333333333³3444444444444444444.pptx
SMI - Introduction to Java
1669617800196.pdf
Application package
Andy On Closures
InheritanceAndPolymorphismprein Java.ppt
06 InheritanceAndPolymorphism.ppt
L04 Software Design 2
Metaprogramming 101
OOP-Advanced Programming with c++
Ad

Recently uploaded (20)

PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Advanced IT Governance
PPTX
MYSQL Presentation for SQL database connectivity
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
PPTX
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Unlocking AI with Model Context Protocol (MCP)
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Approach and Philosophy of On baking technology
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
Advanced methodologies resolving dimensionality complications for autism neur...
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Diabetes mellitus diagnosis method based random forest with bat algorithm
Advanced IT Governance
MYSQL Presentation for SQL database connectivity
NewMind AI Monthly Chronicles - July 2025
solutions_manual_-_materials___processing_in_manufacturing__demargo_.pdf
breach-and-attack-simulation-cybersecurity-india-chennai-defenderrabbit-2025....
Dropbox Q2 2025 Financial Results & Investor Presentation
Chapter 3 Spatial Domain Image Processing.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Big Data Technologies - Introduction.pptx
Network Security Unit 5.pdf for BCA BBA.
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Unlocking AI with Model Context Protocol (MCP)
The AUB Centre for AI in Media Proposal.docx
Approach and Philosophy of On baking technology
Mobile App Security Testing_ A Comprehensive Guide.pdf
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
“AI and Expert System Decision Support & Business Intelligence Systems”

Metaprogramming Rails

  • 6. Introspection is code that tells you about code.
  • 7. Generation is code that writes code.
  • 8. When is this useful?
  • 9. Introspection is useful all of the times. Where is this method defined? What classes inherit from this class? What classes does this class inherit from? What classes include this module or concern? method(:method_name).source_locat ion Class.descendants Class.ancestors Oh crap. How do I do this again?
  • 10. # How to get all the classes that include a module concern :MyDopeModule do def self.dope_classes Rails.application.eager_load! # why is this important? ActiveRecord::Base.descendants.select do |c| c.included_modules.include?(MyDopeModule) end end end
  • 11. QUIZ: Why should you not do that in production?
  • 13. Generative Methods are useful sometimes I need to create many similar methods I need to call methods dynamically I need to dynamically set variables I need to write a gem... define_method(:foo) { do_something(foo) } send(:method) instance_variable_set(‘@var’, value):
  • 14. # Getters and setters for an array attribute # given an activerecord model with an array attribute (1..5).each do |i| define_method("attr_#{i}=".to_sym) do |val| array[i] = val save end define_method("attr_#{i}".to_sym) { take_aways[n] } end
  • 15. # File activerecord/lib/active_record/scoping/named.rb, line 143 def scope(name, body, &block) unless body.respond_to?(:call) raise ArgumentError, "The scope body needs to be callable." end if dangerous_class_method?(name) raise ArgumentError, "You tried to define a scope named "#{name}" " "on the model "#{self.name}", but Active Record already defined " "a class method with the same name." end valid_scope_name?(name) extension = Module.new(&block) if block … end
  • 16. # File activerecord/lib/active_record/scoping/named.rb, line 143 def scope(name, body, &block) ... if body.respond_to?(:to_proc) singleton_class.send(:define_method, name) do |*args| scope = all.scoping { instance_exec(*args, &body) } scope = scope.extending(extension) if extension scope || all end else singleton_class.send(:define_method, name) do |*args| scope = all.scoping { body.call(*args) } scope = scope.extending(extension) if extension scope || all end end end
  • 19. We can even get meta-meta
  • 20. # To DRY on scoping by a virtual attribute on active record models # Add this to a VirtualScopableConcern def self.virtual_scope_by(*virtual_attrs) virtual_attrs.each do |virtual_attr| scope "by_#{virtual_attr}".to_sym, -> { all.to_a.sort_by(&virtual_attr) } end end virtual_scope_by [:virtual_attribute_1, :virtual_attribute_2]
  • 21. QUIZ: Why should you not do that in production?
  • 22. What else can I do with metaprogramming? 1. Write a DSL for markup 2. Modify classes on the fly 3. Make ridiculously long method calls a. String.method(:new).call 4. Catch undefined methods a. Method_missing 5. Binding.pry 6. Penetrate scopes (defy encapsulation) 7. What else?
  • 23. Where can I learn more? ● Metaprogramming Ruby and Antipatterns in Rails by Eugene Wang ● Metaprogramming in Ruby: It's All About the Self by Yehuda Katz ● Metaprogramming Ruby (book) by Paolo Perrotta ● In IRB, write some code, run it.
  • 24. Conclusions: Recursion is the source of all power and...