Tuesday, April 29, 2008

Programming Books Usually Suck

Jeff Atwood over at Coding Horror is always going on about how programmers don't read programming books because most of them suck, and I agree with that.  I personally have only read about three really good ones.

In Jeff's post, he mentioned (as an example of poor writing) a book called Perl for Dummies. I followed through to the linked review, and it was great. So I wanted to point out a few of the best (of the worst) examples, as I think programmers who are writing should take notice of these kinds of things.

When there are simple and difficult explanations, you can usually count on Hoffman to find the difficult explanation, and then to tell you how difficult is. For example: (page 93)

int can be a bit tricky because it rounds down for positive numbers and rounds up for negative numbers.

He's right; that is tricky. Wait, which was does it round again? Up, down, positive, negative, I can't remember. But if he had said

int is very simple: It throws away the fractional part of a number, leaving the integer part.

then it is a lot easier and you understand the name so that next week you might remember what it does.  Another example of this: In the ill-advised explanation of xor, he says

The operator returns true if the two things have different truth values but returns false if they have the same truth value. (See table 8-2.)

Here's the simple version:

$soup xor $salad is true if either $soup or $salad is true, but not both.

Then you dispense with the table.

Part of the reason Robert and I do Develocity is because we are always finding terrible sample code out in the wilds of the Internet, and it's teaching programmers the wrong ways to do things. It's scary to think people are filling books with the same sort of nonsense.

I'm not a programming expert, and I make my share of mistakes too, but before I post sample code that other people are going to look at and possibly use, I will go through it a few times, seeing if it can be made simpler and easier to understand.

Most examples have too much noise.  A "Hello, World" example should do nothing but print "Hello, World" to the screen. Don't add any for loops or random number generators to it.

Sunday, April 13, 2008

Learn and Practice LINQ With LINQPad

LINQPad is a free tool that lets you query your databases using LINQ syntax in an IDE similar to a poor man's SQL Management Studio. It comes packed with 200+ examples.

image

You can also use it as a code snippet compiler, but I think Snippet Compiler is better suited for that, as LINQPad doesn't have Intellisense at the moment.

http://www.linqpad.net/

Friday, April 11, 2008

Development-Related Uses For Screencasts

I’ve started using a program called Jing recently. It can record a video of what's currently on your screen.

Possible uses:

  1. Show managers or project sponsors the current state of your in-progress application without giving them access to the version on your machine (that you might accidentally break since you're still working on it).
  2. When a new feature is created, developers could create a video that shows the QA team what the new feature is supposed to do.
  3. When the new feature doesn't work, the QA team can show the developers the steps necessary to reproduce the problem. (Most of the time, a simple text description isn't enough.)
  4. I have a friend who wants to show his users in Asia how to use certain features of his application.
  5. I have another friend who wants to record the repetitive (yet somewhat complicated) tasks he’s currently doing, so he can show someone else how to do those tasks.
  6. Project sponsors could keep customers (internal and external) abreast of new changes to an application via a blog and show off those changes with an embedded screencast.

If you want to get really fancy, you could even create tutorial videos like the kind you see on www.asp.net, but I think a program like Camtasia Studio would probably be better suited to that, as Jing has a 5 minute limit on any videos created, and there is no way to edit the videos it creates.

Also, because I don't want to divulge any company secrets, I'm not sharing my videos to Screencast.com, Jing's default video destination. I set it up to save a file on my hard drive, so that I can attach it to an email or TFS work item.

Jing is free and extremely easy to use.

http://www.jingproject.com/

How To: Hide a Button When Clicked on an ASP.NET Page Containing Validation Controls

Suppose you have a form with some ASP.NET validation controls on it, and you want to prevent users from clicking the form's submit button more than once.

image

It might sound easy at first. Just add some javascript to the asp:Button's OnClientClick to hide the button and show your custom message:

<script language="javascript" type="text/javascript">
function DisableButton(button)
{
button.style.display
= 'none';
document.getElementById(
'loading').style.display = 'inline';
}
</script>
<asp:Button ID="LoginButton" runat="server" Text="Login" OnClientClick="DisableButton(this)" />
<span id="loading" style="display: none;">Logging in...</span>

Except if you do that, and you're using ASP.NET validation controls on the page, your user could end up in a situation like this:

image

Now your user is stuck because the Login button is gone!

So, this is how to get around that:

<script language="javascript" type="text/javascript">
function DisableButton(button)
{
Page_ClientValidate();
if (Page_IsValid)
{
button.style.display
= 'none';
document.getElementById(
'loading').style.display = 'inline';
}
}
</script>

In the script above, you'll notice I'm using a Page_ClientValidate() method and a Page_IsValid boolean variable. Those are exposed as part of ASP.NET's Client-Side Validation API.

What's happening:

  1. Page_ClientValidate() forces the validation to happen immediately.
  2. If the validation tests pass (Page_IsValid), hide the button, show the message, and submit the page.
    image
  3. If the validation tests fail, ASP.NET will handle showing the validation errors for you, and the page will not be submitted.
    image

For more information on ASP.NET Validation, see this article on MSDN:
http://msdn2.microsoft.com/en-us/library/aa479045.aspx

Friday, April 4, 2008

Enhancing C#'s switch statement with a fluent API

A colleague pointed me to this article today.  It shows a very clever set of utility classes that can dramatically improve the usefulness of the "switch..case" concept.  Since the C# language can't be extended, it is implemented as a fluent API that tries to mimic the built-in switch statement.

The most interesting use to me is the generics-based double dispatch using delegates that enables a sort of visitor pattern:

void Do(Control c) 
{
new Switch(c)
.Case<Label>(l =>
{
// ...
})
.Case<Button>(b =>
{
// ...
})
.Default(cc =>
{
// ...
});
}



An interesting oddity of the implementation is that the various Case() overloads are implemented as Extension methods on the Switch types. That is the only thing I don't like in the linked article. It exploits a "feature" of Extension methods that sorta allows you to call methods on null references. The case "statements" (method calls) are short-circuited by returning null and additional calls to Case() check for the null "this" pointer (the fake "this" which is the first parameter to extension methods) and exits quickly. To me, this seems like abuse of extension methods since the same thing can easily be accomplished with a traditional class.



Here is a modified version of the Switch<T> class implemented as a simple class without the extension methods:




public class Switch<T>
{
public T Object { get; private set; }
private bool hasBroken = false;

public Switch(T obj)
{
this.Object = obj;
}

public Switch<T> Case(T other, Action<T> action)
{
return this.Case(other, action, SwitchBehavior.Break);
}

public Switch<T> Case(T other, Action<T> action, SwitchBehavior behavior)
{
return this.Case(x => object.Equals(x, other), action, behavior);
}

public Switch<T> Case(Func<T, bool> condition, Action<T> action)
{
return this.Case(condition, action, SwitchBehavior.Break);
}

public Switch<T> Case(Func<T, bool> condition, Action<T> action, SwitchBehavior behavior)
{
if (!this.hasBroken && condition(this.Object))
{
action(this.Object);
if (behavior == SwitchBehavior.Break)
this.hasBroken = true;
}

return this;
}

public void Default(Action<T> action)
{
this.Case(t => true, action, SwitchBehavior.Break);
}
}

public enum SwitchBehavior { FallThrough, Break }



A functional C# (type)switch - B# .NET Blog

Javascript: More than meets the eye...

I recently ran across a presentation on InfoQ by Glenn Vanderburg called "The Power of Javascript" that was recorded at JAOO.

Summary
Glenn Vanderburg makes the case for Javascript, a language long overlooked. This presentation from JAOO 2007 shows how its OOP model and other language features make it a very powerful tool and how to use these features to get the most out of the language.

The presentation describes how Javascript got its name - starting out as LiveScript developed by Netscape and later rebranded as Javascript to exploit the popularity of the new kid on the block - Java, developed by Sun. He explains why it is commonly considered to be a "toy language" and why it isn't.

A while ago I posted the first in a series of articles about javascript. Since then I've been somewhat stingy in releasing the other proposed articles.  I'll try to get back into the swing of things promptly.