Update: The conclusions below are wrong, empty() is the best solution to the particular problem, read the follow up post for more information.
As of late I am getting sick of some best practices I have taught myself. Never using the @-error suppressing operator quickly moving to the top of the list.
Before you start crying out loud (I know you will), let me say this: I do not mean to encourage anybody to use the @-operator. Applying the practice herein introduced may result in permanent damage to your coding habits and could serve as a gateway behavior to writing shitty code.
Ok, you have been warned, lets move on. Today I found myself writing the following line of code:
if (isset($step['options']['merge']) &&
$step['options']['merge']) {
// do stuff
}
I was basically checking for a sub-key of an element to be true(ish). However, I knew this sub-key may not be included in the array under some circumstances, so a direct check for it could result in a PHP warning.
You can probably feel the pain of conflict here. On one side I want to write very short and expressive code. On the other side I am also trying to follow the so called "best practices". It is impossible.
Of course there is always the option to normalize the array before doing the check:
$step['options'] =
array('merge' =>
false) +
$step['options'];
if ($step['options']['merge']) {
// do stuff
}
This however still adds a basically useless line of code. Plus normalizing a multi-dimensional array like this requires a more sophisticated merging algorithm than PHP provides you with (CakePHP's Set::merge() function provides good multi-dimensional array merging, but that would be throwing even more code and CPU cycles at the problem).
So today I have, for probably first time in years, I wrote the following line of code:
if (@$step['options']['merge']) {
// do stuff
}
It still causes me mild pain to look at. I hope for that to go away soon. But I no longer have the strength to close my eyes to the very true lesson to be learned here: Using the @-operator like this solves more problems for me than it creates.
This may not be true for you. Using the @-operator is 4x slower than solution #1 and 1.3x slower than #2. If you run a loop with 100000 records, this is 150ms wasted (on my laptop, your mileage may vary). However, my scenario is more like running into this 5-10 times for any given request. So we are talking about 0.0015ms here.
It is not like I don't care about my CPU-cycle footprint. The opposite is true. By sparing myself the pain of typing up and maintaing more verbose-than-necessary code I can save millions of CPU cycles elsewhere! I can go and optimize stuff that actually needs to be optimized.
How will you choose?
-- Felix Geisendörfer aka the_undefined
PS: In case you wonder, @-suppressed errors do not show up in any error logs. So no problems with that.
