Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
extremely defensive coding - rubyconf edition
Search
Penelope Phippen
November 16, 2015
Technology
310
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
extremely defensive coding - rubyconf edition
Penelope Phippen
November 16, 2015
Transcript
136 slides
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
[email protected]
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
[email protected]
Let’s have some questions !/samphippen
[email protected]
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
[email protected]
Let’s have some questions !/samphippen
[email protected]
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
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
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
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Let’s have some questions !/samphippen
[email protected]
Ruby interpreters behave differently.
Let’s have some questions !/samphippen
[email protected]
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
[email protected]
Let’s have some questions !/samphippen
[email protected]
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
[email protected]
More Decks by Penelope Phippen
See All by Penelope Phippen
Introducing Rubyfmt
penelope_zone
0
640
How RSpec Works
penelope_zone
0
6.9k
Quick and easy browser testing using RSpec and Rails 5.1
penelope_zone
1
130
Teaching RSpec to play nice with Rails
penelope_zone
2
190
Little machines that eat strings
penelope_zone
1
150
What is processor (brighton ruby edition)
penelope_zone
0
160
What is processor?
penelope_zone
1
400
Agile, etc.
penelope_zone
2
270
Extremely Defensive Coding
penelope_zone
0
150
Other Decks in Technology
See All in Technology
DevOps Agentにあらゆるセキュリティインシデントのトリアージを任せた件
jirtosterone
1
140
「AIチャットからもできないの?」と言われたら ~業務アプリをMCP対応するときの認証・認可の勘所
oidfj
0
330
思考過程から秘密が漏れる:Amazon Bedrock上のKimi K3を5つの方法で攻めたら、25回中22回漏洩した話
yama3133
1
160
AWS基盤改善を支える 私たちの理念と行動指針
kentosuzuki
0
220
マネージャーをエスパーにしない マネジメントされる側から始める、働きやすい現場づくり
comi190327
0
400
AWS Quick 入門 | 目指せ Quick マスター 01
inariku
PRO
2
340
BALLAS Technology Deck
ballas_inc
0
620
並列度を下げたら速くなった — go build の重複コンパイルを実測で見る
tomoaki25
2
1.2k
これからのデータエンジニアの役割について考える / Rethinking the Role of Data Engineers in the AI Era
okiyuki99
0
490
小さなエージェントから始めてみよう!実践コンテキストエンジニアリング
iwamot
PRO
0
120
田んぼから始まる挑戦 〜新米農家の1年目〜
miu_crescent
PRO
0
360
うちなーぐちが認識できるなら、秋田弁もいけるはず!? Amazon Transcribe方言チューニング検証
ryouto715
1
180
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
33
5.7k
Odyssey Design
rkendrick25
PRO
3
940
Technical Leadership for Architectural Decision Making
baasie
4
640
A better future with KSS
kneath
240
18k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
350
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
350
Digital Projects Gone Horribly Wrong (And the UX Pros Who Still Save the Day) - Dean Schuster
uxyall
2
3.9k
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
850
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
660
Designing for humans not robots
tammielis
254
26k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Six Lessons from altMBA
skipperchong
29
4.6k