For example (and there are code smells in this, but it gets the idea across):
if account = Account.create(params[:account])
...
else
complainAbout account.errors
end
Truthiness should not be reserved for whether an object exists, it could also be used for whether it is valid, complete, or anything else.My particular example might not be a great one, but I think framework and library developers ought to be able to work a consistent use for truthiness and falseness into their creations, e.g. a true object has been saved, a true object is valid, a true object is complete, a true object represents the current state of the world instead of the past or future or a wrong state, and so forth.
If you care enough about the state of what's being returned then it would be trivial to test if the returned object was of the class you were expecting (Account) and if not handle what it did return (some error indication) as appropriate.
Alternately, why not just switch to a functional language where, it seems, ambiguity and other related problems rarely make it past the bouncer at the front door.
At a deep level, I wonder if my issue is with if stamens and boolean operators being magic outside of the object system. Smalltalk gets this right. Scheme gets this right. if "if" is defined in the standard library rather than being magic syntactic construct, we can write our own control primitives:
provided account = Account.create(params[:account])
...
end
:-)There are practical reasons that we're not all coding in IO. Allowing for the redefinition of control primitives is a slippery slope. In short order, we may have apps that read well to us but aren't clear to others.
That said, I'm all for experimentation and would love to see this idea tried.
I know the reasoning (it's much faster to do math on object IDs than it is to call a method), but there are workarounds for this (e.g. only allowing frozen objects to be boolean-false, and having the object's truth-ness/false-ness represented by the return value of its #false? method at the time of freezing—thus allowing the interpreter to locate it in a semantically-meaningful part of object-ID space that can later be masked for in a TEST instruction.)