Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Coercion in Ruby

Coercion in Ruby

Afa6e65b91b46f3317c3d3e94e9255f2?s=128

Grzegorz Witek

May 09, 2018
Tweet

More Decks by Grzegorz Witek

Other Decks in Technology

Transcript

  1. Coercion in Ruby Between the strong and weak typing

  2. Grzegorz Witek

  3. 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”
  4. 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”
  5. Coercion in Ruby class Money < Struct.new(:amount) def *(value)
 amount

    * value
 end end
  6. How do I Ruby? money = Money.new(3) money * 2

    # => 6 2 * money # => ERROR U FAIL
  7. 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
  8. Bad solution Pros: works Cons: it’s wrong on as many

    levels as you can imagine

  9. Good solution class Money < Struct.new(:amount)
 
 def *(value)
 amount

    * value
 end def coerce(other) 
 [self, other]
 end end
  10. Good solution def coerce(other) 
 [self, other]
 end

  11. Good solution def coerce(other) 
 [other, amount]
 end

  12. 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])
  13. How does it work? Fixnum#*(Money) => omg, what to do?

  14. How does it work? Fixnum#(Money)* => omg, what to do?

    Money#coerce => [Money, Fixnum]
  15. How does it work? Fixnum#*(Money) => omg, what to do?

    Money#coerce => [Money, Fixnum] Money#*(Fixnum) => I know how to handle it!
  16. Coercion in Ruby Thanks! Grzegorz Witek
 @arnvald