8. Maccro: register
• Register rules with "before" and "after" matchers
• "before"/"after": code in Ruby, with DSL for code placeholders
• Placeholders (N: integer, >= 1):
• eN: expressions which returns a value or values
• vN: a single value (e.g., variable, constant, literal, etc)
9. Maccro: Apply on Methods
• Macro rules applied to methods
• manually: apply(ModName,
ModName.method(:method_name)
• automatically: using TracePoint (:end)
14. • Matched tree:
• rewrite original method code
with updated "after" code
def foo(v)
if bar(v) < 1
# ...
elsif bar(v) == 1
# ...
elsif 1 < bar(v) < 2
# ...
else
# ...
end
end
e1 < e2 && e2 < e3
"After" code
1 < bar(v) && bar(v) < 2
"After" code for this method
"Before" code
e1 < e2 < e3
Original code of this method
Maccro: Rewrite code (3)
15. Maccro: Rewrite code (3)
• Matched tree:
• rewrite original method code
with updated "after" code
1 < bar(v) && bar(v) < 2
"After" code for this method
def foo(v)
if bar(v) < 1
# ...
elsif bar(v) == 1
# ...
elsif 1 < bar(v) && bar(v) < 2
# ...
else
# ...
end
end
Updated code of this method
e1 < e2 && e2 < e3
"After" code
"Before" code
e1 < e2 < e3
16. • Rewritten method source:
• call Modue#module_eval to replace the method
definition
def foo(v)
if bar(v) < 1
# ...
elsif bar(v) == 1
# ...
elsif 1 < bar(v) < 2
# ...
else
# ...
end
end
def foo(v)
if bar(v) < 1
# ...
elsif bar(v) == 1
# ...
elsif 1 < bar(v) && bar(v) < 2
# ...
else
# ...
end
end
Overwrite the method definition
by Module#module_eval
Maccro: Rewrite Method
17. Nice stuffs
• Less performance penalty
• Macro processor works only when methods are defined
• Ruby version independent Macro rules
• Compatible between Ruby versions
• Because of rules written in Ruby code
• Built-in rules, useful for some cases
• Continuous inequality operators (<=, <, >, >=)
• ActiveRecord utilities
18. • Supported only on Ruby 2.6 or later
• Only code in def in module/class are rewritable
• Calling class method just after definition can't be updated
• Same method can't be rewritten twice
• Non-idempotent methods causes unexpected result
• Updating Lambda and local variable name matching is not implemented yet
• Stack trace of updated methods would be confusing
• Source from STDIN or command line (and irb/pry) cause errors
• Rule-order-dependent issues will be caused
• Method visibility are not taken care right now
• Non-self singleton method definition causes errors
• Placeholder validations are not implemented yet
Limitations
Just Few Limitations
at April (RubyKaigi 2019)
19. Limitations
• Supported only on Ruby 2.6 or later
• Calling class method just after definition can't be updated
• Non-idempotent methods causes unexpected result
• Stack trace of updated methods would be confusing
• Source from STDIN or command line (and irb/pry) cause errors
• Rule-order-dependent issues will be caused
• Method visibility are not taken care right now
• Non-self singleton method definition causes errors
• Placeholder validations are not implemented yet
Just Few Limitations (now)
20. Maccro v0.2.0
• Support to rewrite (+call) any lambda/proc code
• Support new placeholders
for strings, symbols, numbers and regexps