Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
extremely defensive coding - rubyconf edition
Search
Penelope Phippen
November 16, 2015
Technology
0
250
extremely defensive coding - rubyconf edition
Penelope Phippen
November 16, 2015
Tweet
Share
More Decks by Penelope Phippen
See All by Penelope Phippen
Introducing Rubyfmt
penelope_zone
0
550
How RSpec Works
penelope_zone
0
6.5k
Quick and easy browser testing using RSpec and Rails 5.1
penelope_zone
1
79
Teaching RSpec to play nice with Rails
penelope_zone
2
130
Little machines that eat strings
penelope_zone
1
91
What is processor (brighton ruby edition)
penelope_zone
0
99
What is processor?
penelope_zone
1
350
Agile, etc.
penelope_zone
2
210
Extremely Defensive Coding
penelope_zone
0
92
Other Decks in Technology
See All in Technology
意思決定を支える検索体験を目指してやってきたこと
hinatades
PRO
0
290
地味にいろいろあった! 2025春のAmazon Bedrockアップデートおさらい
minorun365
PRO
1
480
SREからゼロイチプロダクト開発へ ー越境する打席の立ち方と期待への応え方ー / Product Engineering Night #8
itkq
2
1k
Spring Bootで実装とインフラをこれでもかと分離するための試み
shintanimoto
7
890
AWSのマルチアカウント管理 ベストプラクティス最新版 2025 / Multi-Account management on AWS best practice 2025
ohmura
4
340
watsonx.data上のベクトル・データベース Milvusを見てみよう/20250418-milvus-dojo
mayumihirano
0
130
Рекомендации с нуля: как мы в Lamoda превратили главную страницу в ключевую точку входа для персонализированного шоппинга. Данил Комаров, Data Scientist, Lamoda Tech
lamodatech
0
810
【Λ(らむだ)】最近のアプデ情報 / RPALT20250422
lambda
0
120
グループ ポリシー再確認 (2)
murachiakira
0
120
React ABC Questions
hirotomoyamada
0
560
2025-04-14 Data & Analytics 井戸端会議 Multi tenant log platform with Iceberg
kamijin_fanta
0
100
ガバクラのAWS長期継続割引 ~次の4/1に慌てないために~
hamijay_cloud
1
490
Featured
See All Featured
The Cult of Friendly URLs
andyhume
78
6.3k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
34
2.9k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
135
33k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.5k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.2k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
12k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.8k
Into the Great Unknown - MozCon
thekraken
38
1.7k
Automating Front-end Workflow
addyosmani
1370
200k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
13
800
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
Transcript
Extremely Defensive Coding
a!/samphippen
Who is having fun?
Who is here for their first time?
I want to start with a story
“When is it OK to override the methods on object?”
I umm’d and ahh’d for a bit
I gave a half explanation and then asked them if
they understood
I eventually came to an answer to do with consistency
Do it when it makes your object more consistent with
Ruby, not less
e.g. an == on a data object
What makes a gem good?
Internals?
Internals?
Interface?
Interface? ✅
More convenient than if I did it myself
And it stays convenient
And it can be used by everyone on a team
And it works with a wide range of Ruby codebases
RSpec
RSpec Definitely always convenient
RSpec Definitely always convenient
User story
As an RSpec user
When I stub an object
I want the original method to be on that object
after the example
So that my objects aren’t broken by my test suite
As an RSpec user
When I stub an object
I want the original method to be on that object
after the example
So that my objects aren’t broken by my test suite
How does that work?
allow(cat).to receive(:meow)
Takes the meow method off cat
Saves it
Executes test
Puts the method back on the original object
How do you save a method?
None
Method object
Put it somewhere else
Put it back at end of test
The end
The end
Defensive coding
RSpec::Support .method_handle_for
Simply invoking the method method is not good enough
Some scenes may have been altered/accelerated for your viewing pleasure
Let’s have some questions !/samphippen sam@funandplausible.com
Users Lie
def method ‘get’ end
Users can redefine anything at any time in Ruby
and that’s fine
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Instance method object Method without a target object
Comes from a class/module not an instance
Grab the Kernel implementation of #method
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Users can and will redefine core methods at any time
Instead we use Kernel’s implementation
Nobody screws with Kernel
Ruby interpreters lie
Some objects do not have Kernel in their inheritance chain
None
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Rebinding module methods
c
c
RSpec does not support Rubinius
None
We tried, we really really tried
So anyway, dealing with module methods
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Ruby interpreters behave differently.
Let’s have some questions !/samphippen sam@funandplausible.com
Sometimes users don’t lie
None
None
None
None
`method': undefined method `foo' for class `Foo' (NameError)
This is a catch 22
Solution: trust but verify
None
None
None
Let’s put it all together
None
Wrapping up
This is why I love RSpec
Please file bugs
Your gem should be defensive
Users lie Redefinitions come from anywhere, expect them
Ruby interpreters lie Your code will run on non-MRI, old
MRI, etc
Sometimes users don’t lie Users are weird, trust but verify
What makes a gem good?
Internals?
That explanation made no sense
Internals?
Interface?
allow(cat).to receive(:meow)
You get the complexity of RSpec working with any object
for free
You probably didn’t even know it was there until I
just told you
Interface? ✅
Gems
Gems provide strong abstraction boundaries
Done badly they cause an even more extreme mess
Done correctly they hide huge complexity behind well defined barriers
Defending against users helps your gem be convenient
Write defensively, and your users will never know what’s inside
the box
Remember the story?
This talk is born out of Ruby’s power
We need our code to defend today, against the mistakes
of our tomorrow
Let’s have some questions !/samphippen sam@funandplausible.com
Let’s have some questions !/samphippen sam@funandplausible.com
Minitest Mock is 169 lines of code
I just showed you more code than that
For a tiny feature that isn’t a complete mocking library
and that’s fine
Please check out https://browserpath.co
None
Let’s have some questions a!/samphippen sam@funandplausible.com