KEMBAR78
Metaprogramming in Ruby | PPTX
Volodymyr Byno
github.com/vbyno
volodymyr.byno@gmail.com
domain lead engineer at
Metaprogramming
What?
Writing code that writes code
Writing code that manipulates
language constructs at runtime
• write own DSL
• remove duplications in the code
• enhance basic Ruby
Why?
Object Model
Class is an object, Object is a class
class is a keyword, class is a method
method is a method, Method is a class
Object Model
Class is an Object
Module is an Object
Module Hooks
Class vs Module
Statement vs Method
method
statement
Singleton Method/Class
class A singleton class
Lookup
new?
Methods
unbound method
What does
«everything»
mean?
Everything
is an
object
Open class
NOT Objects
• comments (# comment, =begin =end)
• punctuation marks (, ; ( .)
• statements (if while for defined? yield super)
• operators (&. || && =)
• blocks (do..end, {..})
• methods (not method objects)
Methods are a fundamental part of Ruby's syntax, but they are not values that Ruby
programs can operate on. That is, Ruby's methods are not objects in the way that strings,
numbers, and arrays are. It is possible, however, to obtain a Method object that represents a
given method, and we can invoke methods indirectly through Method objects.
(c) The Ruby Programming Language. D. Flanagan; Y. Matsumoto
operators table
Open Class
Open Class
method already exists
Monkeypatching
Test: Ruby or Rails?
ActiveSupport
3 Ways to Monkey-Patch
why is nobody using refinements
Refinements
• Applicable only for classes
• Works in the current lexical scope
(module/class definition, EOF)
Dynamic
Method
Dynamic Dispatch
Dynamic Method
Comment it out!
Remove Method
Ghost
Method
Ghost Method
respond_to?
Rules:
• Redefine respond_to_missing?(name)
• Call super
respond_to? vs respond_to_missing?
Dynamic vs Ghost
use Dynamic Methods if you can
use Ghost Methods if you have to
Alias
Method
Alias Method
alias vs alias_method
Block
Proc
Lamda
Block
Reccomendation: 1 line - curly braces, multiple
lines - do..end
& operator
yield is not enough:
• pass block to another method
• convert block to Proc
Proc
LambdaProc
returns fom the scope
where it is defined returns from itself
checks the aritydoes not check the arity
Lambdas vs Methods
lambda is evaluated in the scope it is defined,
method is evaluated in the scope of object
Lexical
Scope
Lexical Scope
Flat
Scope
Scope
Gates
scope in ruby
*eval methods
*eval vs *exec methods
def current_user
def user_signed_in?
def authenticate_user!
def user_session
Variable Setter/Getter
Statements / Methods
• BasicObject#__send__
• BasicObject#method_missing
• Kernel#send
• Kernel#public_send
• Kernel#method
• Kernel#class
• Kernel#define_singleton_method
• Kernel#block_given?
• Kernel#respond_to_missing?
• Kernel#respond_to?
• Kernel#eval
• yield
• defined?
• alias
• super
• class
• module
• def
• Module#module_eval
• Module#define_method
• Module#alias_method
• Module#included
• Module#refine
• Module#using
Summary
• Avoid metaprogramming if it is possible!
• Be smart in monkeypatching
• Statements are not methods
• Prefer lambdas over procs
• Use super in method_missing
• Keep scope in mind
• Comment out!
1. Metaprogramming Ruby 2.0
(book)
2. The Ruby Programming Language
(book, Reflection and Metaprogramming section)
3. Ruby Under a Microscope
(Objects and Classes, Constants Lookup)
4. Codebases lessons
Investigate Further

Metaprogramming in Ruby