I have been working for the past few years doing ASP.NET development with C# as the language of choice. While I do plenty of C# programming, I also write a lot of HTML and JavaScript. C# is a strongly typed language while JavaScript is not. C# is compiled while JavaScript is interpreted.
Over the years I have been careful to keep these things in mind as I program because subtle programming errors that are usually prevented because a language is strongly typed or because the compiler caught me being stupid can cause nightmares and wreak havoc in those languages that are not.
A good example of this is when assignment was used where equality was desired.
In C# we have a compiler that will slap us on the hands for this:
public static void Main(){
int i = 10;
int b = 20;
if(a = b) //compiler warning
{
//assignment always happens
}
else
{
//dead code
}
}
But, in JavaScript we don't have a compiler to nag at us for this:function Main(){
var i = 10;
var b = 20;
if(a = b) //no compiler so, no warning
{
//assignment always happens
}
else
{
//dead code
}
};Well, recently I was bit by just this very type of issue with a twist. I had some code that was using an integer flag to represent the valid values of an instance variable (see Flag Word). In my JavaScript code I had de-serialized a value from the server that was supposed to represent the style of an HTML element. The possible values were:
- Bold
- Underline
- Italic
function ApplyStyles() {
var deserializedValue = 7;
var styleMask = {
Bold: 1,
Underline: 2,
Italic: 4
}
if (deserializedValue & styleMask.Underline == styleMask.Underline) {
//execute because 7 & 2 == 2 should evaluate to true
}
}
But, the if block never got executed. Why not? I set a break point because I figured the values that were being returned from the server were not what I was expecting. What I found was exactly what I expected. The values in the watch window looked like the comment in the above code.So, I called a co-worker over. He looked at the watch window and scratched his head. After a bit of poking around in the debugger he asked me to evaluate both sides of the bit-wise and operator (&). the left side was 7 and the right side was True. Doh! we added an extra set of parentheses and it worked.
function ApplyStyles() {
var deserializedValue = 7;
var styleMask = {
Bold: 1,
Underline: 2,
Italic: 4
}
if ((deserializedValue & styleMask.Underline) == styleMask.Underline) {
//extra parentheses (7 & 2) == 2 NOW its true
}
}
Why, what happened? "I do this all the time in my C# and don't need the parentheses... why do I need them here." I ranted. So to prove it to myself, off I went and looked at my C# code. OMG there they were, an extra set of parentheses . Why!!! Whats up with that?We need to go back to our intro Computer Science classes and remember operator precedence (see Order of operations - Programming languages). The bit-wise AND and bit-wise OR operators are of lower operator precedence than equality. What the hell, I thought they were evaluated before equality, somewhere around the bit-wise shift operators.
Well here is where working in a strongly typed language and relying on the debugger has made me lazy and forgetful. In C# the compiler nags when you attempt to do this. You will get a compiler warning.
Operator '&' cannot be applied to operands of type 'int' and 'bool'It all makes perfect sense, I have conditioned myself when doing this type of operation. I have conditioned myself poorly. I have waited until the compiler identified my bad code and then I would go back and correct it instead of writing better code to being with.
Shame on me!
No comments:
Post a Comment