SlideShare a Scribd company logo
1 of 46
Download to read offline
refinements
the worst feature you ever loved
paolo @nusco perrotta
obvious
“Obvious” problems are those that you can solve yourself, if you have some time and knowledge.
non-obvious
“Non-obvious” problems require more effort. You might not know how to solve them at first.
deep
“Deep” problems might not even have an optimal solution. You have to experiment.
-1-
why refinements
Let’s look at the problem that refinements are designed to solve.
class String
def shout
upcase + "!"
end
end
"hello".shout # => "HELLO!"
monkeypatching
In Ruby, you can do this.
three use cases
Three of the most important use cases for monkeypatching.
describe Fixnum do
it "can be added" do
(2 + 2).should == 4
end
end
domain specific languages
require "active_support/all"
1.hour + 20.minutes # => 4800 seconds
convenience methods
method wrappers
class String
alias_method :old_length, :length
def length
old_length > 5 ? "long" : "short"
end
end
"War and Peace".length # => "long"
class String
alias_method :old_length, :length
def length
old_length > 5 ? "long" : "short"
end
end
"War and Peace".length # => "long"
!This example also shows why monkeypatches are dangerous: because they are global.
local monkeypatches
This is what we want, and what Refinements are.
-2-
refinements
Let’s look at Refinements, the way they were originally conceived.
module StringExtensions
refine String do
def shout
upcase + "!"
end
end
end
defining a refinement
module ModuleThatUsesTheRefinement
using StringExtensions
"hello".shout # => "HELLO!"
end
using a refinement
Refinement in a class/module. Only active in the marked area.
using StringExtensions
"hello".shout # => "HELLO!"
# EOF
using a refinement
Refinement at the top level. Only active in the marked area.
class C
using StringExtensions
"hello".shout # => "HELLO!"
end
class C
"hello".shout # => ?
end
…but will it work here?
class C
using StringExtensions
"hello".shout # => "HELLO!"
end
class D < C
"hello".shout # => ?
end
…or here?
class C
using StringExtensions
"hello".shout # => "HELLO!"
end
C.class_eval do
"hello".shout # => ?
end
…or here?
class C
using StringExtensions
"hello".shout # => "HELLO!"
end
C.class_eval do
"hello".shout # => "HELLO!"
end
dynamic scope
The original proposal (Dynamically Scoped Refinements) says yes, in all three cases.
-3-
refinement gotchas
But people found potential problems with this.
confusing code
def add(x, y)
x + y
end
SomeClass.class_eval do
add(1, 1) # => 2
end
SomeOtherClass.class_eval do
add(1, 1) # => "11"
end
using FloatPointMath # refines Fixnum#+
add(1, 1) # => 2.0
You need to look at the implementations to understand the interface.
slows down the language
def add(x, y)
x + y
end
SomeClass.class_eval do
add(1, 1) # => 2
end
SomeOtherClass.class_eval do
add(1, 1) # => "11"
end
using FloatPointMath # refines Fixnum#+
add(1, 1) # => 2.0
The interpreter also needs to do the same, so Refinements can slow down the entire interpreter.
security threat
def add(x, y)
x + y
end
SomeClass.class_eval do
add(1, 1) # => 2
end
SomeOtherClass.class_eval do
add(1, 1) # => "11"
end
using FloatPointMath # refines Fixnum#+
add(1, 1) # => 2.0
Less understanding potentially means less security.
surprising corner cases
def add(x, y)
x + y
end
SomeClass.class_eval do
add(1, 1) # => 2
end
SomeOtherClass.class_eval do
add(1, 1) # => "11"
end
using FloatPointMath # refines Fixnum#+
add(1, 1) # => 2.0
Some things might not work as you expect. (For example, the last line doesn’t work in irb).
•they fix monkeypatches
refinements: the good
The good of Dynamically Scoped Refinements.
•they make Ruby code potentially confusing
•they impact performance
•they impact security
•they have weird corner cases
refinements: the bad_
The bad of Dynamically Scoped Refinements.
are dynamically scoped
refinements worth it?
no.
This is what the core team decided right before Ruby 2.0.
-4-
refinements today
So we have a different versions of Refinements instead.
module StringExtensions
refine String do
def shout
upcase + "!"
end
end
end
module ModuleThatUsesTheRefinement
using StringExtensions
"hello".shout # => "HELLO!"
end
This stuff is the same…
class C
using StringExtensions
"hello".shout # => "HELLO!"
end
C.class_eval do
"hello".shout # => NoMethodError
end
…but this doesn’t work.
lexical scope
class C
using StringExtensions
"hello".shout # => "HELLO!"
end
C.class_eval do
"hello".shout # => NoMethodError
end
No matter how you change the scope, Refinements *only* work in the lexical scope.
(almost) no confusion
def add(x, y)
x + y
end
SomeClass.class_eval do
add(1, 1) # => 2
end
SomeOtherClass.class_eval do
add(1, 1) # => 2
end
using FloatPointMath # refines Fixnum#+
add(1, 1) # => 2
(Note that the very last line might still surprise you, until you wrap your head around lexical scoping).
the three use cases again
But how do these new Refinements apply to the three main use cases of Monkeypatching?
describe Fixnum do
it("can be added") do
(2 + 2).should == 4
end
end
# => NoMethodError (undefined method 'it')
domain specific languages
This doesn’t work anymore.
class MyClass < ActiveRecord::Base
2.hours
end
# => NoMethodError (undefined method 'hours')
convenience methods
Neither does this.
class MyClass < ActiveRecord::Base
using ActiveSupport::CoreExtensions
2.hours # => 7200 seconds
end
convenience methods
(Unless I use using() in each and every class where I want the refinements - not very DRY).
module StringExtensions
refine String do
def length
super > 5 ? "long" : "short"
end
end
end
using StringExtensions
"War and Peace".length # => "long"
method wrappers
This one does work, thans to the way “super” works in Refinements.
•they don’t fix monkeypatches in general
•they still have weird corner cases
refinements today: the bad_
The bad of Lexically Scoped Refinements.
•they do fix some monkeypatching cases
•they don’t make the code confusing
•they don’t impact performance or security
•…and besides, they open the road for more
refinements today: the good
The good of Lexically Scoped Refinements.
-5-
a deep problem
describe Fixnum do
it "can be added" do
(2 + 2).should == 4
end
end
This code relies on multiple features that do not seem to make much sense (singleton classes, optional parentheses), but ended up being “abused” by the
community. It is hard to plan for this.
language design
is a deep problem
The point of this entire speech: we cannot plan. We need to experiment.
thank you
Buy this book. ;)

More Related Content

What's hot

Refactoring
RefactoringRefactoring
Refactoring
nkaluva
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Mario Fusco
 
Python data structures
Python data structuresPython data structures
Python data structures
Harry Potter
 

What's hot (16)

Python quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung FuPython quickstart for programmers: Python Kung Fu
Python quickstart for programmers: Python Kung Fu
 
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
Lucio Floretta - TensorFlow and Deep Learning without a PhD - Codemotion Mila...
 
The Error of Our Ways
The Error of Our WaysThe Error of Our Ways
The Error of Our Ways
 
Refactoring
RefactoringRefactoring
Refactoring
 
Python Programming Essentials - M16 - Control Flow Statements and Loops
Python Programming Essentials - M16 - Control Flow Statements and LoopsPython Programming Essentials - M16 - Control Flow Statements and Loops
Python Programming Essentials - M16 - Control Flow Statements and Loops
 
Rust Intro
Rust IntroRust Intro
Rust Intro
 
PythonOOP
PythonOOPPythonOOP
PythonOOP
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
R Debugging
R DebuggingR Debugging
R Debugging
 
Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...Laziness, trampolines, monoids and other functional amenities: this is not yo...
Laziness, trampolines, monoids and other functional amenities: this is not yo...
 
Fog City Ruby - Triple Equals Black Magic with speaker notes
Fog City Ruby - Triple Equals Black Magic with speaker notesFog City Ruby - Triple Equals Black Magic with speaker notes
Fog City Ruby - Triple Equals Black Magic with speaker notes
 
Notes on assignment in r
Notes on assignment in rNotes on assignment in r
Notes on assignment in r
 
Unit vii wp ppt
Unit vii wp pptUnit vii wp ppt
Unit vii wp ppt
 
Python basics
Python basicsPython basics
Python basics
 
Python data structures
Python data structuresPython data structures
Python data structures
 
10 Recursion
10 Recursion10 Recursion
10 Recursion
 

Similar to Ruby Refinements: the Worst Feature You Ever Loved

Uses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & StubsUses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & Stubs
PatchSpace Ltd
 
cs3157-summer06-lab1
cs3157-summer06-lab1cs3157-summer06-lab1
cs3157-summer06-lab1
tutorialsruby
 
cs3157-summer06-lab1
cs3157-summer06-lab1cs3157-summer06-lab1
cs3157-summer06-lab1
tutorialsruby
 

Similar to Ruby Refinements: the Worst Feature You Ever Loved (20)

Test First Teaching
Test First TeachingTest First Teaching
Test First Teaching
 
Ruby Gotchas
Ruby GotchasRuby Gotchas
Ruby Gotchas
 
The Ring programming language version 1.8 book - Part 7 of 202
The Ring programming language version 1.8 book - Part 7 of 202The Ring programming language version 1.8 book - Part 7 of 202
The Ring programming language version 1.8 book - Part 7 of 202
 
Test First Teaching and the path to TDD
Test First Teaching and the path to TDDTest First Teaching and the path to TDD
Test First Teaching and the path to TDD
 
Erlang And ActorDB
Erlang And ActorDB Erlang And ActorDB
Erlang And ActorDB
 
Ruby Intro {spection}
Ruby Intro {spection}Ruby Intro {spection}
Ruby Intro {spection}
 
Elixir and OTP Apps introduction
Elixir and OTP Apps introductionElixir and OTP Apps introduction
Elixir and OTP Apps introduction
 
The Ring programming language version 1.9 book - Part 48 of 210
The Ring programming language version 1.9 book - Part 48 of 210The Ring programming language version 1.9 book - Part 48 of 210
The Ring programming language version 1.9 book - Part 48 of 210
 
The Ring programming language version 1.9 book - Part 7 of 210
The Ring programming language version 1.9 book - Part 7 of 210The Ring programming language version 1.9 book - Part 7 of 210
The Ring programming language version 1.9 book - Part 7 of 210
 
Ruby Basics
Ruby BasicsRuby Basics
Ruby Basics
 
Uses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & StubsUses & Abuses of Mocks & Stubs
Uses & Abuses of Mocks & Stubs
 
00_Introduction to Java.ppt
00_Introduction to Java.ppt00_Introduction to Java.ppt
00_Introduction to Java.ppt
 
The Ring programming language version 1.5.3 book - Part 6 of 184
The Ring programming language version 1.5.3 book - Part 6 of 184The Ring programming language version 1.5.3 book - Part 6 of 184
The Ring programming language version 1.5.3 book - Part 6 of 184
 
Dutch PHP Conference 2013: Distilled
Dutch PHP Conference 2013: DistilledDutch PHP Conference 2013: Distilled
Dutch PHP Conference 2013: Distilled
 
Ruby basics
Ruby basicsRuby basics
Ruby basics
 
Language supports it
Language supports itLanguage supports it
Language supports it
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
The Ring programming language version 1.5.4 book - Part 6 of 185
The Ring programming language version 1.5.4 book - Part 6 of 185The Ring programming language version 1.5.4 book - Part 6 of 185
The Ring programming language version 1.5.4 book - Part 6 of 185
 
cs3157-summer06-lab1
cs3157-summer06-lab1cs3157-summer06-lab1
cs3157-summer06-lab1
 
cs3157-summer06-lab1
cs3157-summer06-lab1cs3157-summer06-lab1
cs3157-summer06-lab1
 

Recently uploaded

+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
shinachiaurasa2
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
VishalKumarJha10
 

Recently uploaded (20)

Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdfPayment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
Payment Gateway Testing Simplified_ A Step-by-Step Guide for Beginners.pdf
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...Chinsurah Escorts ☎️8617697112  Starting From 5K to 15K High Profile Escorts ...
Chinsurah Escorts ☎️8617697112 Starting From 5K to 15K High Profile Escorts ...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
The title is not connected to what is inside
The title is not connected to what is insideThe title is not connected to what is inside
The title is not connected to what is inside
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park %in ivory park+277-882-255-28 abortion pills for sale in ivory park
%in ivory park+277-882-255-28 abortion pills for sale in ivory park
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 

Ruby Refinements: the Worst Feature You Ever Loved

Editor's Notes

  1. “Obvious” problems are those that you can solve yourself, if you have some time and knowledge.
  2. “Non-obvious” problems require more effort. You might not know how to solve them at first.
  3. “Deep” problems might not even have an optimal solution. You have to experiment.
  4. Let’s look at the problem that refinements are designed to solve.
  5. In Ruby, you can do this.
  6. Three of the most important use cases for monkeypatching.
  7. This example also shows why monkeypatches are dangerous: because they are global.
  8. This is what we want, and what Refinements are.
  9. Let’s look at Refinements, the way they were originally conceived.
  10. Refinement in a class/module. Only active in the marked area.
  11. Refinement at the top level. Only active in the marked area.
  12. …but will it work here?
  13. …or here?
  14. …or here?
  15. The original proposal (Dynamically Scoped Refinements) says yes, in all three cases.
  16. But people found potential problems with this.
  17. You need to look at the implementations to understand the interface.
  18. The interpreter also needs to do the same, so Refinements can slow down the entire interpreter.
  19. Less understanding potentially means less security.
  20. Some things might not work as you expect. (For example, the last line doesn’t work in irb).
  21. The good of Dynamically Scoped Refinements.
  22. The bad of Dynamically Scoped Refinements.
  23. This is what the core team decided right before Ruby 2.0.
  24. So we have a different versions of Refinements instead.
  25. This stuff is the same…
  26. …but this doesn’t work.
  27. No matter how you change the scope, Refinements *only* work in the lexical scope.
  28. (Note that the very last line might still surprise you, until you wrap your head around lexical scoping).
  29. But how do these new Refinements apply to the three main use cases of Monkeypatching?
  30. This doesn’t work anymore.
  31. Neither does this.
  32. (Unless I use using() in each and every class where I want the refinements - not very DRY).
  33. This one does work, thans to the way “super” works in Refinements.
  34. The bad of Lexically Scoped Refinements.
  35. The good of Lexically Scoped Refinements.
  36. This code relies on multiple features that do not seem to make much sense (singleton classes, optional parentheses), but ended up being “abused” by the community. It is hard to plan for this.
  37. The point of this entire speech: we cannot plan. We need to experiment.
  38. Buy this book. ;)