intridea/hashie — pull request #200 by maxlinc (2014-08-08 04:37:49+00:00)
Title: Improved coercion: primitives and error handling

This includes #199 (coerce only when necessary) but also fixes #161 (Boolean coercion?)

Actually, it adds:
- Integer coercion (via to_i)
- Float coercion (via to_f)
- String coercion (via to_s)
- Symbol coercion (via to_sym)
- Boolean type-checking, using the pseudo-type `:boolean`
- Better coercion error messages

Boolean type checking is done via:
```ruby
coerce_key :foo, :boolean
```

This will check that foo is a boolean. It would be possible to coerce foo to a boolean, but there isn't a standard convention so we'd need to make a choice. For example, integers can be converted to a boolean as:
- non-zero is true, 0 is false (`!i.zero?`)
- positive is true, otherwise false (`i > 0`)
- any value is true, nil is false (`!!i`)

This PR also adds better error messages for when coercion fails. It will indicate if a type is not coercible:
```ruby
subject.coerce_key :foo, TrueClass
instance[:foo] = true
#=> TypeError: Cannot coerce property :foo from TrueClass to TrueClass: TrueClass is not a coercable type
```

Or if a type is coercable under some circumstances, but not from that specific value:
```ruby
subject.coerce_value Fixnum, Symbol
instance[:foo] = 1
#=> TypeError: Cannot coerce property :hi from Fixnum to Symbol: undefined method `to_sym' for 1:Fixnum
```