Salman Samson Rogers
Salman Samson Rogers

Reputation: 33

Providing an implicit conversion of nil in Ruby?

Operations involving the plus operator (e.g. string concatenation or arithmetic) would be so much more convenient if Ruby knew that:

'a' + nil 
# => 'a'

and

nil + 'a' 
# => 'a'

These statements are unambiguous, but they return errors:

TypeError: no implicit conversion of nil into String

and

NoMethodError: undefined method '+' for nil:NilClass

When programming to process databases, e.g. parsing XML and JSON from human-input data, one encounters empty fields all the time, frequently resulting in variables set to nil.

Specific Example

Using the JSON gem,

json('firstname')

will return nil if firstname is not defined. Then wishing to process the result as a string, I'd normally have to write some logic to handle the case that it is nil rather than an empty string. To do this for many fields in a database is very tedious. It would be very convenient if I could handle these by implicitly converting nil to a string.

What is the Ruby way to solve this problem?

Upvotes: 0

Views: 1232

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369458

nil does define explicit conversions to String, Integer, Float, Array, Hash, Rational and Complex, so you could just do

'a' + nil.to_s
nil.to_s + 'a'

1 + nil.to_i
nil.to_i + 1

1.0 + nil.to_f
nil.to_f + 1.0

[] + nil.to_a
nil.to_a + []

{}.merge(nil.to_h)
nil.to_h.merge({})

Rational(1) + nil.to_r
nil.to_r + Rational(1)

Complex(1, 1) + nil.to_c
nil.to_c + Complex(1, 1)

It does not define implicit conversions, because getting a nil where you didn't expect it is usually either a bug or bad design. (And if you do expect it, then you can test for it or explicitly convert it.)

You could, of course, add the necessary operators (+, …), implicit conversions (to_str, to_int, to_float, to_ary, to_hash, …) and numeric coercions (coerce) to NilClass, but I would consider that a mistake. The implicit conversions are meant to implement an IS-A relationship but saying that "nil IS-A String" is just wrong.

Upvotes: 1

phoet
phoet

Reputation: 18835

thats why you should use string-interpolation.

nil.to_s == ''

val = nil

"a#{val}" == 'a'

Upvotes: 2

Related Questions