Coercion in Ruby

Coercion in Ruby

Afa6e65b91b46f3317c3d3e94e9255f2?s=128

Grzegorz Witek

May 09, 2018
Tweet

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