I've seen ternary operators satanized as being just very obfuscated ifs for lazy programers who don't want to take the time to make their code maintainable. And they can be, of course.
But I've taken a liking to them. They provide one of the most succinct and clear ways to construct a value from a list of conditions. And, what are Best Practices for if not to be able to read the code as fast and as transparently as possible?
The general way in which I like to format them is this:
var resultValue :Whatever = conditionA ? valueForA
: conditionB ? valueForB
: conditionC ? valueForC
: defaultValue
;
This can be read almost straight in English---Does this happen to be true? then the value is this. If not, does this? then the value is so. If this other? This. None of the above? then set it to the default value--- You get your conditions in one column associated with the results in the next column. And the compiler makes sure that you set a default value at the end.
I got this neat idea from the amazing Perl Best Practices by Damien Conway (I have to admit that I'm kind of a Perl guy trapped in the body of an Actionscript programmer.)
Here's a Flex example from an actual project. Here we determine the state of a component based on a couple of heterogeneous data sources that are mapped to the string names of the defined states.
<mx:currentState>
{
_deviceData.state != DeviceState.CONNECTED ? DISCONNECTED
: _guiData.state == GUIState.CATEGORIES ? CATALOG_VIEW
: _guiData.state == GUIState.DEVICE_DETAIL ? DEVICE_VIEW
: CONNECTED
}
</mx:currentState>
It might be a bit scarier looking than the previous abstract example, but it can be read just as easily: the current state of this commenent is: if the device is not connected, DISCONNECTED, if the gui state is set to categories, then CATALOG_VIEW, if the gui state is set to device detail, then set to DEVICE_VIEW, for every other case, go to the CONNECTED component state.
In this example, this single construct is bound to from the currentState property of the component. This provides a simple way to keep the currentState in sync with those two data sources.