SlideShare a Scribd company logo
HIJACKING RUBY SYNTAX
IN RUBY
RubyConf 2018 LA
2018/11/15 (Thu)
@joker1007 & @tagomoris
Self-Intro Joker
▸ id: joker1007
▸ Repro inc. CTO
▸ I’m familiar with Ruby/Rails/Fluentd/ECS/Presto.
▸ This talk is my first speech abroad!!
Satoshi Tagomori (@tagomoris)
Fluentd, MessagePack-Ruby, Norikra, Woothee, ...
Arm Ltd.
Hijacking Ruby Syntax in Ruby (RubyConf 2018)
Agenda
▸ Ruby Features
▸ binding
▸ Tracepoint
▸ method hook
▸ Hacks
▸ finalist, overrider, abstriker
▸ with_resources, deferral
Ruby Features: Binding
Binding
▸ Context object, includes:
▸ Kernel#binding receiver
▸ local variables
▸ For template engines (?)
▸ Methods:
▸ #receiver, #eval,

#local_variables,

#local_variable_get,

#local_variable_defined?,

#local_variable_set
Binding creates new object per call
Setting variables are ignored on binding
Overwriting existing variable is effective!
Ruby Features: Binding
Binding#local_variable_set
▸ Method to
▸ add a variable only in a binding instance
▸ overwrite values of existing variables in original
context
Ruby Features: TracePoint
TracePoint
▸ Tracing events in VM
▸ and call hook block
▸ For various events:
▸ :line , :raise
▸ :class , :end
▸ :call , :return , :c_call , :c_return , :b_call , :b_return
▸ :thread_begin , :thread_end , :fiber_switch
▸ "We can use TracePoint to gather information specifically for
exceptions:" (from Ruby doc)
▸ This is COMPLETELY WRONG statement...
Ruby Features: TracePoint
TracePoint interrupted the argument (stringified) and return value (upcased)
Hijacking Ruby Syntax in Ruby (RubyConf 2018)
Ruby Features: TracePoint
TracePoint Methods
▸ Methods:
▸ Control: disable, enable, enabled?
▸ Event what/where: event, defined_class, path, lineno
▸ Method names: method_id, callee_id
▸ Event special: raised_exception, return_value
▸ And: binding
▸ So what?
▸ We can use TracePoint 
▸ to gather information
▸ to overwrite everything
テキスト
Break (10min)
Ruby Features: Refinements
▸ Refinements provide a way to extend a class locally
▸ Useful use case. (Safety monkey patching)
Ruby Features: Refinements
Another use case
▸ Super private method
Ruby Features: Refinements
Ruby Features: Method Hooks
▸ Ruby has six method hooks
▸ Module#method_added
▸ Module#method_removed
▸ Module#method_undefined
▸ BasicObject#singleton_method_added
▸ BasicObject#singleton_method_removed
▸ BasicObject#singleton_method_undefined
Ruby Features: method hooks
Sample: #method_added
Ruby Features: method hooks
Method hook provides a way to implement method modifier.
Hacks: Method modifiers
▸ final (https://github.com/joker1007/finalist)
▸ forbid method override
▸ override (https://github.com/joker1007/overrider)
▸ enforce method has super method
▸ abstract (https://github.com/joker1007/abstriker)
▸ enforce method override
These method modifiers work when Ruby defines class.
It is runtime, but in most case, before main logic.
Hacks: method modifiers
Sample code: finalist
Hacks: method modifiers
Hacks: method modifiers
Sample code: abstriker
Hacks: method modifiers
How to implement method modifiers
I use so many hook methods.
#included, #extended, #method_added, and TracePoint.
And I use Ripper.
In other words, I use the power of many black magics !!
Hacks: method modifiers
Use case of method_added in finalist
Ruby Features: method hooks
MyObject
Finalist
def method_added
def verify_final_method
▸ #method_added checks violations
call
Limitation of Method Hooks
▸ But it is not enough to implement “finalist” actually
▸ Ruby has so many cases of method definition
▸ def or #define_method
▸ #include module
▸ #extend, #prepend
▸ Each case has dedicated hooks
Ruby Features: method hooks
#include changes only chain of method discovering
Foo
Object
Bar
Insert module to hierarchy
It is different from method adding
Class#ancestors displays class-module hierarchy
Ruby Features: method hooks
Hooks in finalist gem
hook method override event by
method_added subclass
singleton_method_added subclass class methods
included included modules
extended extended moduled
And I talk about TracePoint too
overrider and abstriker use TracePoint
▸ #inherited and #included to start TracePoint
Tracepoint in overrider, abstriker
MyObject
Overrider/Abstriker
def included(or inherited)
TracePoint.trace(:end, :c_return, :raise)
call
Tracepoint in overrider, abstriker
TracePoint Hook
Overrider
self.override_methods = [
:method_a,
:method_b,
]
▸ Use Method#super_method method to check method
existence (ex. method(:method_a).super_method)
Why use TracePoint?
▸ In order to verify method existence at the end of class
definition.
▸ Ruby interpreter needs to wait until the end of class
definition to know a method absence.
▸ override and abstract cannot detect violation just when
they are called.
▸ In ruby, The only way to detect the violation is
TracePoint.
Advanced TracePoint: Detect particular class end
Advanced Tracepoint
:end event cannot trace definition by `Class.new`.
Use :c_return and return_value

to detect particular class end
Advanced TracePoint: Ripper combination
Advanced Tracepoint
▸ Ripper:
▸ a standard library, a parser for Ruby code
▸ outputs token list and S-expression
▸ S-expression is similar to AST
▸ has token string and token position
▸ Future option: RubyVM::AbstractSyntaxTree (2.6.0 or later)
Ripper sample:
Advanced Tracepoint
Advanced TracePoint: Ripper combination
Advanced Tracepoint
Detect target Sexp node by TracePoint#lineno
Sexp node type expresses the style of method cal
Ripper empowers TracePoint
▸ Conclusion:
▸ TracePoint detects events and where it occurs
▸ Ripper.sexp provides how methods were called
▸ Other use case
▸ power_assert gem also uses this combination
Advanced Tracepoint
Black Magic is dangerous actually,
but it is very fun,
and it extends Ruby potential
These gems are proof of concepts,
But these are decent practical.
Ruby Quiz
Break (25-30min)
What the difference between:
- #undef_method
- #remove_method
RUBY QUIZ
class Foo
def foo
class Foo
def foo
class Bar < Foo
def foo
class Bar < Foo
def foo
Bar.new.foo()
RUBY QUIZ
class Foo
def foo
class Foo
def foo
class Bar < Foo
class Bar < Foo
Bar.new.foo()
remove_method(:foo)
def foo
NoMethodError
undef_method(:foo)
Hack: with_resources
Add "with" Statement to Ruby
▸ Safe resource allocate/release
▸ Ensure to release resources
▸ at the end of a lexical scope
▸ in reverse order of allocation
▸ Idioms used very frequently
▸ Other languages:
▸ Java:

try-with-resources
▸ Python: with
▸ C#: using
Hack: with_resources
Safe Resource Allocation/Release Statement in Ruby
▸ Open method with blocks
▸ File.open(path){|f| ... }
▸ Ruby way (?)
▸ More indentation
▸ Not implemented sometimes

(e.g., TCPSocket)
Hack: with_resources
with_resources.gem
▸ Safe resource allocation
▸ Top level #with
▸ by Kernel refinement
▸ Resource allocation as lambda
▸ Multi statements to allocate resources
▸ to release first resource

if second resource allocation raises exception
▸ Block to define scope for resources
https://github.com/tagomoris/with_resources
Hack: with_resources
Implementing #with in Ruby
▸ TracePoint
▸ "b_return": pass allocated resources to block arguments
▸ "line": identify allocated resources in lambda
▸ Binding
▸ detect newly defined

local variables

in allocation lambda
▸ Refinements
▸ introduce #with

in top-level without side effects
https://github.com/tagomoris/with_resources
Hack: deferral
Alternative: defer?
▸ Multi-step resource

allocation in a method
▸ Nesting! w/ #with
▸ not so bad
▸ many nesting looks

a bit messy :(
▸ Alternative?
▸ defer in golang
Hack: deferral
Adding #defer to Ruby
▸ Block based #defer
▸ Should work
▸ Requires 1-level

nesting *always*
▸ Defer.start, end (+ nesting)

look too much (than golang)
▸ Abnormal case:

reassigning variables
Hack: deferral
deferral.gem
▸ Safe resource release
▸ Top level #defer
▸ by Kernel refinements
▸ Deferred processing to release resources
▸ at the end of scope (method, block)
▸ or exception raised
Hack: deferral
Implementing "defer" in Ruby
▸ #defer
▸ Enable TracePoint if not yet
▸ Initialize internal stack frame
▸ TracePoint
▸ Monitor method call stack
▸ Get the snapshot of local variables in defer block
▸ Call release blocks at the end of scope
▸ Binding
▸ save/restore local variables of release block
▸ Refinements
▸ introduce #defer in top-level without side effects
stack level 0
stack level 1
The Hard Thing
in Magical World:
Debugging!
"Give yourself to the dark side.
It is the only way you can save
your (Ruby)friends." - Darth vader
Thank You!
@joker1007 & @tagomoris

More Related Content

What's hot (20)

PDF
How to distribute Ruby to the world
Hiroshi SHIBATA
 
PDF
Dependency Resolution with Standard Libraries
Hiroshi SHIBATA
 
PDF
The Future of Dependency Management for Ruby
Hiroshi SHIBATA
 
PDF
How to distribute Ruby to the world
Hiroshi SHIBATA
 
PDF
The Future of Bundled Bundler
Hiroshi SHIBATA
 
PDF
OSS Security the hard way
Hiroshi SHIBATA
 
PDF
Gems on Ruby
Hiroshi SHIBATA
 
PDF
The Future of library dependency management of Ruby
Hiroshi SHIBATA
 
PDF
Gemification for Ruby 2.5/3.0
Hiroshi SHIBATA
 
PDF
Roadmap for RubyGems 4 and Bundler 3
Hiroshi SHIBATA
 
PDF
An introduction and future of Ruby coverage library
mametter
 
PDF
How to Begin Developing Ruby Core
Hiroshi SHIBATA
 
PDF
Gemification for Ruby 2.5/3.0
Hiroshi SHIBATA
 
PDF
Gemification plan of Standard Library on Ruby
Hiroshi SHIBATA
 
PDF
The Future of library dependency manageement of Ruby
Hiroshi SHIBATA
 
PDF
Ruby Security the Hard Way
Hiroshi SHIBATA
 
PDF
How to test code with mruby
Hiroshi SHIBATA
 
PDF
The secret of programming language development and future
Hiroshi SHIBATA
 
ODP
Deploying Perl apps on dotCloud
daoswald
 
PDF
JRuby 9000 - Taipei Ruby User's Group 2015
Charles Nutter
 
How to distribute Ruby to the world
Hiroshi SHIBATA
 
Dependency Resolution with Standard Libraries
Hiroshi SHIBATA
 
The Future of Dependency Management for Ruby
Hiroshi SHIBATA
 
How to distribute Ruby to the world
Hiroshi SHIBATA
 
The Future of Bundled Bundler
Hiroshi SHIBATA
 
OSS Security the hard way
Hiroshi SHIBATA
 
Gems on Ruby
Hiroshi SHIBATA
 
The Future of library dependency management of Ruby
Hiroshi SHIBATA
 
Gemification for Ruby 2.5/3.0
Hiroshi SHIBATA
 
Roadmap for RubyGems 4 and Bundler 3
Hiroshi SHIBATA
 
An introduction and future of Ruby coverage library
mametter
 
How to Begin Developing Ruby Core
Hiroshi SHIBATA
 
Gemification for Ruby 2.5/3.0
Hiroshi SHIBATA
 
Gemification plan of Standard Library on Ruby
Hiroshi SHIBATA
 
The Future of library dependency manageement of Ruby
Hiroshi SHIBATA
 
Ruby Security the Hard Way
Hiroshi SHIBATA
 
How to test code with mruby
Hiroshi SHIBATA
 
The secret of programming language development and future
Hiroshi SHIBATA
 
Deploying Perl apps on dotCloud
daoswald
 
JRuby 9000 - Taipei Ruby User's Group 2015
Charles Nutter
 

Similar to Hijacking Ruby Syntax in Ruby (RubyConf 2018) (20)

PPT
Ruby for C# Developers
Cory Foy
 
PDF
Rapid Development with Ruby/JRuby and Rails
elliando dias
 
PPT
Ruby on Rails 3 Day BC
Northwest Independent Ruby Development
 
PDF
Low-Maintenance Perl
Perrin Harkins
 
PDF
Pourquoi ruby et rails déchirent
Nicolas Ledez
 
PPT
Ruby Hell Yeah
Anupom Syam
 
PDF
Hacking with ruby2ruby
Marc Chung
 
ODP
Debugging Rails 3 Applications
Nathan Broadbent
 
PDF
Ruby — An introduction
Gonçalo Silva
 
PDF
Ruby Programming Introduction
Anthony Brown
 
KEY
Ruby on Rails Training - Module 1
Mark Menard
 
PDF
Jruby a Pi and a database
Philipp Fehre
 
PPTX
Random Ruby Tips - Ruby Meetup 27 Jun 2018
Kenneth Teh
 
PPT
Ruby for Perl Programmers
amiable_indian
 
PPT
ppt30
callroom
 
PPT
ppt21
callroom
 
PPT
name name2 n
callroom
 
PPT
ppt9
callroom
 
PPT
test ppt
callroom
 
Ruby for C# Developers
Cory Foy
 
Rapid Development with Ruby/JRuby and Rails
elliando dias
 
Low-Maintenance Perl
Perrin Harkins
 
Pourquoi ruby et rails déchirent
Nicolas Ledez
 
Ruby Hell Yeah
Anupom Syam
 
Hacking with ruby2ruby
Marc Chung
 
Debugging Rails 3 Applications
Nathan Broadbent
 
Ruby — An introduction
Gonçalo Silva
 
Ruby Programming Introduction
Anthony Brown
 
Ruby on Rails Training - Module 1
Mark Menard
 
Jruby a Pi and a database
Philipp Fehre
 
Random Ruby Tips - Ruby Meetup 27 Jun 2018
Kenneth Teh
 
Ruby for Perl Programmers
amiable_indian
 
ppt30
callroom
 
ppt21
callroom
 
name name2 n
callroom
 
ppt9
callroom
 
test ppt
callroom
 
Ad

More from SATOSHI TAGOMORI (20)

PDF
Ractor's speed is not light-speed
SATOSHI TAGOMORI
 
PDF
Good Things and Hard Things of SaaS Development/Operations
SATOSHI TAGOMORI
 
PDF
Maccro Strikes Back
SATOSHI TAGOMORI
 
PDF
Invitation to the dark side of Ruby
SATOSHI TAGOMORI
 
PDF
Make Your Ruby Script Confusing
SATOSHI TAGOMORI
 
PDF
Lock, Concurrency and Throughput of Exclusive Operations
SATOSHI TAGOMORI
 
PDF
Data Processing and Ruby in the World
SATOSHI TAGOMORI
 
PDF
Planet-scale Data Ingestion Pipeline: Bigdam
SATOSHI TAGOMORI
 
PDF
Technologies, Data Analytics Service and Enterprise Business
SATOSHI TAGOMORI
 
PDF
Ruby and Distributed Storage Systems
SATOSHI TAGOMORI
 
PDF
Perfect Norikra 2nd Season
SATOSHI TAGOMORI
 
PDF
Fluentd 101
SATOSHI TAGOMORI
 
PDF
To Have Own Data Analytics Platform, Or NOT To
SATOSHI TAGOMORI
 
PDF
The Patterns of Distributed Logging and Containers
SATOSHI TAGOMORI
 
PDF
How To Write Middleware In Ruby
SATOSHI TAGOMORI
 
PDF
Modern Black Mages Fighting in the Real World
SATOSHI TAGOMORI
 
PDF
Open Source Software, Distributed Systems, Database as a Cloud Service
SATOSHI TAGOMORI
 
PDF
Fluentd Overview, Now and Then
SATOSHI TAGOMORI
 
PDF
How to Make Norikra Perfect
SATOSHI TAGOMORI
 
PDF
Distributed Logging Architecture in Container Era
SATOSHI TAGOMORI
 
Ractor's speed is not light-speed
SATOSHI TAGOMORI
 
Good Things and Hard Things of SaaS Development/Operations
SATOSHI TAGOMORI
 
Maccro Strikes Back
SATOSHI TAGOMORI
 
Invitation to the dark side of Ruby
SATOSHI TAGOMORI
 
Make Your Ruby Script Confusing
SATOSHI TAGOMORI
 
Lock, Concurrency and Throughput of Exclusive Operations
SATOSHI TAGOMORI
 
Data Processing and Ruby in the World
SATOSHI TAGOMORI
 
Planet-scale Data Ingestion Pipeline: Bigdam
SATOSHI TAGOMORI
 
Technologies, Data Analytics Service and Enterprise Business
SATOSHI TAGOMORI
 
Ruby and Distributed Storage Systems
SATOSHI TAGOMORI
 
Perfect Norikra 2nd Season
SATOSHI TAGOMORI
 
Fluentd 101
SATOSHI TAGOMORI
 
To Have Own Data Analytics Platform, Or NOT To
SATOSHI TAGOMORI
 
The Patterns of Distributed Logging and Containers
SATOSHI TAGOMORI
 
How To Write Middleware In Ruby
SATOSHI TAGOMORI
 
Modern Black Mages Fighting in the Real World
SATOSHI TAGOMORI
 
Open Source Software, Distributed Systems, Database as a Cloud Service
SATOSHI TAGOMORI
 
Fluentd Overview, Now and Then
SATOSHI TAGOMORI
 
How to Make Norikra Perfect
SATOSHI TAGOMORI
 
Distributed Logging Architecture in Container Era
SATOSHI TAGOMORI
 
Ad

Recently uploaded (20)

PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PDF
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
PDF
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
PDF
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
DOCX
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PDF
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
DOCX
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
PDF
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
PDF
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
PDF
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
PDF
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
LOOPS in C Programming Language - Technology
RishabhDwivedi43
 
Achieving Consistent and Reliable AI Code Generation - Medusa AI
medusaaico
 
Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Cryptography Quiz: test your knowledge of this important security concept.
Rajni Bhardwaj Grover
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
Transcript: Book industry state of the nation 2025 - Tech Forum 2025
BookNet Canada
 
Python coding for beginners !! Start now!#
Rajni Bhardwaj Grover
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
“Voice Interfaces on a Budget: Building Real-time Speech Recognition on Low-c...
Edge AI and Vision Alliance
 
What’s my job again? Slides from Mark Simos talk at 2025 Tampa BSides
Mark Simos
 
Smart Trailers 2025 Update with History and Overview
Paul Menig
 
The Rise of AI and IoT in Mobile App Tech.pdf
IMG Global Infotech
 
Automating Feature Enrichment and Station Creation in Natural Gas Utility Net...
Safe Software
 

Hijacking Ruby Syntax in Ruby (RubyConf 2018)

  • 1. HIJACKING RUBY SYNTAX IN RUBY RubyConf 2018 LA 2018/11/15 (Thu) @joker1007 & @tagomoris
  • 2. Self-Intro Joker ▸ id: joker1007 ▸ Repro inc. CTO ▸ I’m familiar with Ruby/Rails/Fluentd/ECS/Presto. ▸ This talk is my first speech abroad!!
  • 3. Satoshi Tagomori (@tagomoris) Fluentd, MessagePack-Ruby, Norikra, Woothee, ... Arm Ltd.
  • 5. Agenda ▸ Ruby Features ▸ binding ▸ Tracepoint ▸ method hook ▸ Hacks ▸ finalist, overrider, abstriker ▸ with_resources, deferral
  • 6. Ruby Features: Binding Binding ▸ Context object, includes: ▸ Kernel#binding receiver ▸ local variables ▸ For template engines (?) ▸ Methods: ▸ #receiver, #eval,
 #local_variables,
 #local_variable_get,
 #local_variable_defined?,
 #local_variable_set
  • 7. Binding creates new object per call
  • 8. Setting variables are ignored on binding
  • 10. Ruby Features: Binding Binding#local_variable_set ▸ Method to ▸ add a variable only in a binding instance ▸ overwrite values of existing variables in original context
  • 11. Ruby Features: TracePoint TracePoint ▸ Tracing events in VM ▸ and call hook block ▸ For various events: ▸ :line , :raise ▸ :class , :end ▸ :call , :return , :c_call , :c_return , :b_call , :b_return ▸ :thread_begin , :thread_end , :fiber_switch ▸ "We can use TracePoint to gather information specifically for exceptions:" (from Ruby doc) ▸ This is COMPLETELY WRONG statement...
  • 13. TracePoint interrupted the argument (stringified) and return value (upcased)
  • 15. Ruby Features: TracePoint TracePoint Methods ▸ Methods: ▸ Control: disable, enable, enabled? ▸ Event what/where: event, defined_class, path, lineno ▸ Method names: method_id, callee_id ▸ Event special: raised_exception, return_value ▸ And: binding ▸ So what? ▸ We can use TracePoint  ▸ to gather information ▸ to overwrite everything
  • 17. Ruby Features: Refinements ▸ Refinements provide a way to extend a class locally ▸ Useful use case. (Safety monkey patching) Ruby Features: Refinements
  • 18. Another use case ▸ Super private method Ruby Features: Refinements
  • 19. Ruby Features: Method Hooks ▸ Ruby has six method hooks ▸ Module#method_added ▸ Module#method_removed ▸ Module#method_undefined ▸ BasicObject#singleton_method_added ▸ BasicObject#singleton_method_removed ▸ BasicObject#singleton_method_undefined Ruby Features: method hooks
  • 21. Method hook provides a way to implement method modifier.
  • 22. Hacks: Method modifiers ▸ final (https://github.com/joker1007/finalist) ▸ forbid method override ▸ override (https://github.com/joker1007/overrider) ▸ enforce method has super method ▸ abstract (https://github.com/joker1007/abstriker) ▸ enforce method override These method modifiers work when Ruby defines class. It is runtime, but in most case, before main logic. Hacks: method modifiers
  • 23. Sample code: finalist Hacks: method modifiers
  • 25. Sample code: abstriker Hacks: method modifiers
  • 26. How to implement method modifiers I use so many hook methods. #included, #extended, #method_added, and TracePoint. And I use Ripper. In other words, I use the power of many black magics !! Hacks: method modifiers
  • 27. Use case of method_added in finalist Ruby Features: method hooks MyObject Finalist def method_added def verify_final_method ▸ #method_added checks violations call
  • 28. Limitation of Method Hooks ▸ But it is not enough to implement “finalist” actually ▸ Ruby has so many cases of method definition ▸ def or #define_method ▸ #include module ▸ #extend, #prepend ▸ Each case has dedicated hooks Ruby Features: method hooks
  • 29. #include changes only chain of method discovering Foo Object Bar Insert module to hierarchy It is different from method adding Class#ancestors displays class-module hierarchy Ruby Features: method hooks
  • 30. Hooks in finalist gem hook method override event by method_added subclass singleton_method_added subclass class methods included included modules extended extended moduled
  • 31. And I talk about TracePoint too
  • 32. overrider and abstriker use TracePoint ▸ #inherited and #included to start TracePoint Tracepoint in overrider, abstriker MyObject Overrider/Abstriker def included(or inherited) TracePoint.trace(:end, :c_return, :raise) call
  • 33. Tracepoint in overrider, abstriker TracePoint Hook Overrider self.override_methods = [ :method_a, :method_b, ] ▸ Use Method#super_method method to check method existence (ex. method(:method_a).super_method)
  • 34. Why use TracePoint? ▸ In order to verify method existence at the end of class definition. ▸ Ruby interpreter needs to wait until the end of class definition to know a method absence. ▸ override and abstract cannot detect violation just when they are called. ▸ In ruby, The only way to detect the violation is TracePoint.
  • 35. Advanced TracePoint: Detect particular class end Advanced Tracepoint :end event cannot trace definition by `Class.new`. Use :c_return and return_value
 to detect particular class end
  • 36. Advanced TracePoint: Ripper combination Advanced Tracepoint ▸ Ripper: ▸ a standard library, a parser for Ruby code ▸ outputs token list and S-expression ▸ S-expression is similar to AST ▸ has token string and token position ▸ Future option: RubyVM::AbstractSyntaxTree (2.6.0 or later)
  • 38. Advanced TracePoint: Ripper combination Advanced Tracepoint Detect target Sexp node by TracePoint#lineno Sexp node type expresses the style of method cal
  • 39. Ripper empowers TracePoint ▸ Conclusion: ▸ TracePoint detects events and where it occurs ▸ Ripper.sexp provides how methods were called ▸ Other use case ▸ power_assert gem also uses this combination Advanced Tracepoint
  • 40. Black Magic is dangerous actually, but it is very fun, and it extends Ruby potential These gems are proof of concepts, But these are decent practical.
  • 41. Ruby Quiz Break (25-30min) What the difference between: - #undef_method - #remove_method
  • 42. RUBY QUIZ class Foo def foo class Foo def foo class Bar < Foo def foo class Bar < Foo def foo Bar.new.foo()
  • 43. RUBY QUIZ class Foo def foo class Foo def foo class Bar < Foo class Bar < Foo Bar.new.foo() remove_method(:foo) def foo NoMethodError undef_method(:foo)
  • 44. Hack: with_resources Add "with" Statement to Ruby ▸ Safe resource allocate/release ▸ Ensure to release resources ▸ at the end of a lexical scope ▸ in reverse order of allocation ▸ Idioms used very frequently ▸ Other languages: ▸ Java:
 try-with-resources ▸ Python: with ▸ C#: using
  • 45. Hack: with_resources Safe Resource Allocation/Release Statement in Ruby ▸ Open method with blocks ▸ File.open(path){|f| ... } ▸ Ruby way (?) ▸ More indentation ▸ Not implemented sometimes
 (e.g., TCPSocket)
  • 46. Hack: with_resources with_resources.gem ▸ Safe resource allocation ▸ Top level #with ▸ by Kernel refinement ▸ Resource allocation as lambda ▸ Multi statements to allocate resources ▸ to release first resource
 if second resource allocation raises exception ▸ Block to define scope for resources https://github.com/tagomoris/with_resources
  • 47. Hack: with_resources Implementing #with in Ruby ▸ TracePoint ▸ "b_return": pass allocated resources to block arguments ▸ "line": identify allocated resources in lambda ▸ Binding ▸ detect newly defined
 local variables
 in allocation lambda ▸ Refinements ▸ introduce #with
 in top-level without side effects https://github.com/tagomoris/with_resources
  • 48. Hack: deferral Alternative: defer? ▸ Multi-step resource
 allocation in a method ▸ Nesting! w/ #with ▸ not so bad ▸ many nesting looks
 a bit messy :( ▸ Alternative? ▸ defer in golang
  • 49. Hack: deferral Adding #defer to Ruby ▸ Block based #defer ▸ Should work ▸ Requires 1-level
 nesting *always* ▸ Defer.start, end (+ nesting)
 look too much (than golang) ▸ Abnormal case:
 reassigning variables
  • 50. Hack: deferral deferral.gem ▸ Safe resource release ▸ Top level #defer ▸ by Kernel refinements ▸ Deferred processing to release resources ▸ at the end of scope (method, block) ▸ or exception raised
  • 51. Hack: deferral Implementing "defer" in Ruby ▸ #defer ▸ Enable TracePoint if not yet ▸ Initialize internal stack frame ▸ TracePoint ▸ Monitor method call stack ▸ Get the snapshot of local variables in defer block ▸ Call release blocks at the end of scope ▸ Binding ▸ save/restore local variables of release block ▸ Refinements ▸ introduce #defer in top-level without side effects stack level 0 stack level 1
  • 52. The Hard Thing in Magical World: Debugging!
  • 53. "Give yourself to the dark side. It is the only way you can save your (Ruby)friends." - Darth vader Thank You! @joker1007 & @tagomoris