Any object which has a
valueOf function available can play.
valueOf is simple: it should return a primitive representation of the object’s value.
valueOf method whenever an object is in a position it should be converted to a primitive - comparison operations or arithmetic where other primitives are concerned, or in inequalities between objects.
valueOf clearly affects the behaviour when explicitly comparing an object with a boolean - in contrast, it has no effect in implicit tests for truthiness. In
if statements, the
! unary operator, or anywhere else that implicitly converts to a boolean, objects are simply defined as true:
Having a numeric value for our objects keeps sorting much cleaner, as we can simply use subtraction - just like sorting numbers. This makes, for instance, code for a priority queue of nodes in a search algorithm clean and expressive.
From the way inequality operators work with two objects having
valueOf defined we’d assume that equality would be similar. Actually, objects are only equal under both the
=== operators when they are the same object. This leads to the following surprising code, where
e is neither less, or more, than
f, but isn’t equal to it.
Comparison with different types
Although we can control the value of our objects in comparison, we have no knowledge of the context: what we’re comparing the objects to. This means we can’t model comparisons with more than one type - unless you’re careful to return a value that is sensibly comparable to all the types you’d like to compare it with. This can lead to absurd comparisons:
In Ruby you can control exactly what happens on comparison via the
<=> method, which is passed the object to compare. This makes it easy to allow comparisons with some objects, but throw exceptions for invalid comparisons.
valueOf is ready to make your code better
Now you know what
valueOf can and cannot do, you’ve got a shiny new tool to make your code even more beautiful!