Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Coercion in Ruby
Grzegorz Witek
May 09, 2018
Technology
1
24
Coercion in Ruby
Grzegorz Witek
May 09, 2018
Tweet
Share
More Decks by Grzegorz Witek
See All by Grzegorz Witek
arnvald
0
31
arnvald
0
18
arnvald
0
21
arnvald
2
23
arnvald
0
240
arnvald
0
14
arnvald
0
12
arnvald
0
13
arnvald
0
71
Other Decks in Technology
See All in Technology
ykanazawa
0
340
ahana
0
360
ks91
PRO
0
300
chipstar_light
0
470
yuhta28
0
140
jaguar_imo
0
110
surumegohan
1
160
hanasuke
0
230
tutsunom
1
330
line_developers
PRO
1
490
charity
9
11k
soracom
0
820
Featured
See All Featured
smashingmag
232
18k
mthomps
38
2.3k
maggiecrowley
10
540
bermonpainter
343
26k
maltzj
502
36k
pauljervisheath
195
15k
jonyablonski
21
1.3k
productmarketing
6
770
matthewcrist
73
7.5k
jcasabona
8
590
bryan
99
11k
morganepeng
19
1.3k
Transcript
Coercion in Ruby Between the strong and weak typing
Grzegorz Witek
Strong vs. weak typing $> 3 + “a” Python: unsupported
operand type(s) for +: 'int' and 'str' Ruby: String can't be coerced into Fixnum Javascript: “3a”
Strong vs. weak typing $> 3 + “a” Python: unsupported
operand type(s) for +: 'int' and 'str' Ruby: String can't be coerced into Fixnum Javascript: “3a”
Coercion in Ruby class Money < Struct.new(:amount) def *(value) amount
* value end end
How do I Ruby? money = Money.new(3) money * 2
# => 6 2 * money # => ERROR U FAIL
Bad solution class Fixnum alias :old_multiply :* def *(val) if
defined?(Money) && val.is_a?(Money) return self * val.amount else old_multiply(val) end end end
Bad solution Pros: works Cons: it’s wrong on as many
levels as you can imagine
Good solution class Money < Struct.new(:amount) def *(value) amount
* value end def coerce(other) [self, other] end end
Good solution def coerce(other) [self, other] end
Good solution def coerce(other) [other, amount] end
How does it work? Short answer: when Ruby can’t handle
the param type, it calls arg.coerce(self) it gets 2 elements array, and calls array[0].method(array[1])
How does it work? Fixnum#*(Money) => omg, what to do?
How does it work? Fixnum#(Money)* => omg, what to do?
Money#coerce => [Money, Fixnum]
How does it work? Fixnum#*(Money) => omg, what to do?
Money#coerce => [Money, Fixnum] Money#*(Fixnum) => I know how to handle it!
Coercion in Ruby Thanks! Grzegorz Witek @arnvald