Friday, February 02, 2007

Session Timeouts - Web Apps' Unaddressed Weakness?

This bugs me: I restore an application window from my taskbar, enter a bunch of data, hit "commit" and get taken to the login screen. My data is lost. If I'm incredibly lucky (and think to do it) the app honours the back button and I can login, backup to the screen with the data still in it and recommit.

If you take the time, DHTML, Flash, Ajax, etc. can be used to significantly narrow the UX gap between smart client and Web apps, but what can you do about session timeouts?

BTW, I'm not a Web developer :-)

Tuesday, January 16, 2007

Truth

I've been hanging on to this in my inbox for ages so thought I'd put it here. If you love Jack Nicholson's performance in A Few Good Men, you'll like this!

 

Programmer: Jack Nicholson

Sales Team: Tom Cruise

 

Programmer: You want answers?

Sales Team: I think I'm entitled to them.

Programmer: You want answers?!

Sales Team: I want the truth!

Programmer: You can't HANDLE the truth!!

Son, we live in a world that has DATA, CODE AND CONCEPTS. And those ABSTRACT SOLUTIONS have to MAP TO THE REAL WORLD. Who's gonna DESIGN THEM?

You? You, MR. SALES TEAM? I have a greater responsibility than you can possibly fathom. You weep for FUNCTIONALITY and you curse the SPEED OF THE SYSTEM. You have that luxury. You have the luxury of not knowing what I know: that these SYSTEMS, while tragic, probably saved lives. And my existence, while grotesque and incomprehensible to you, saves lives...You don't want the truth. Because deep down, in places you don't talk about at parties, you want me on that DESIGN TEAM.

You need me on that DESIGN TEAM.

We use words like DESIGN, CODE, ANALYSIS...we use these words as the backbone to a life spent PROVIDING ANSWERS AND SOLUTIONS.

You use 'em as a punch line.

I have neither the time nor the inclination to explain my DESIGN to a man who rises and sleeps under the blanket of the very SOLUTION I provide, then questions the manner in which I provide it! I'd rather you just said thank you and went on your way. Otherwise, I suggest you pick up a CODING LANGUAGE and DESIGN a SYSTEM. Either way, I don't give a damn what you think you're entitled to!

Sales Team: Did you CUT THOSE EXTRA FEATURES?

Programmer: (quietly) I did the job you HIRED me to do.

Sales Team: Did you CUT THOSE EXTRA FEATURES?!!

Programmer: You're goddamn right I did!!

Thursday, January 11, 2007

Microsoft Vista and Office Launch Event

Managed to score a place at this event! If you did too, there's a geek dinner on the Friday night, organized by Zi Makki. Sign up here!

Friday, November 24, 2006

Forwarding IEnumerable(Of T)

Often we have a class that implements IEnumerable by returning the enumerator from an embedded list or array:

    1 

    2 Public Class Class1

    3     Implements IEnumerable

    4 

    5     Private Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator

    6         Return _items.GetEnumerator

    7     End Function

    8 

    9     Private _items() As Integer

   10 

   11 End Class

   12 

When I tried to do the same thing with a generic class, I had a problem:

    1 

    2 Public Class Class2(Of X As New)

    3     Implements IEnumerable(Of X)

    4 

    5     Private Function GetEnumerator() As IEnumerator(Of X) Implements IEnumerable(Of X).GetEnumerator

    6         Return DirectCast(_items.GetEnumerator, IEnumerator(Of X))  'Throws InvalidCastException

    7     End Function

    8 

    9     Private Function GetEnumerator1() As IEnumerator Implements IEnumerable.GetEnumerator

   10         Return _items.GetEnumerator

   11     End Function

   12 

   13     Private _items() As X

   14 

   15 End Class

   16 

Line 6 throws an exception with the message "Unable to cast object of type 'SZArrayEnumerator' to type 'System.Collections.Generic.IEnumerator`1[System.Int32]'."

The answer is simple, but had me scratching my head for a while:

    6 Return DirectCast(_items, IEnumerable(Of X)).GetEnumerator

Wednesday, November 08, 2006

Numbers Divisible by their Reverse

Here is my solution Jon Galloway's puzzle (my guess was "tens of numbers"):

    1 Module Module1

    2 

    3     Sub Main()

    4 

    5         Dim testValue As Integer = 21

    6         Const maxTestValue As Integer = 1000000

    7         Dim count As Integer = 0

    8 

    9         Do

   10 

   11             If testValue Mod 10 <> 0 Then

   12                 Dim testString As String = testValue.ToString

   13                 Dim reverseString As String = Reverse(testString)

   14                 If reverseString < testString Then

   15                     Dim reverseValue As Integer = CInt(reverseString)

   16                     If testValue Mod reverseValue = 0 Then

   17                         Console.WriteLine(String.Format("{0} / {1} = {2}", testValue, reverseValue, testValue / reverseValue))

   18                         count += 1

   19                     End If

   20                 End If

   21             End If

   22 

   23             testValue += 1

   24 

   25         Loop Until testValue > maxTestValue

   26 

   27         Console.WriteLine(String.Format("{0} numbers <= {1} are non-trivially divisible by their reverse.", count, maxTestValue))

   28         Console.ReadLine()

   29 

   30     End Sub

   31 

   32     Private Function Reverse(ByVal value As String) As String

   33         Dim chars() As Char = value.ToCharArray

   34         Array.Reverse(chars)

   35         Return New String(chars)

   36     End Function

   37 

   38 End Module

The .NET limitation is that the String class has no Reverse method!

This gives the following rather interesting result:

It is easily seen that (only) numbers of the format "879*12" and "989*01" (using regex * = 0-or-more occurrences) are solutions to this problem.

I have found a rather elegant proof of this but unfortunately it is too large to fit in the margin ;-)

I wonder how this generalizes for bases other than 10.

Update 9/11/06:

Jon's solution post shows I should have taken the sequence a bit further before jumping to conclusions:

The pattern now looks like: (879*12)+ or (989*01)+

Reminds me of this old puzzle:

If you have n points on the circumference of a circle, and join them all together with straight lines, how many regions are outlined? (More than two lines may not cross at the same point.)

1 point => 1 region
2 points => 2 regions
3 points => 4 regions
4 points => 8 regions

n points => 2^(n-1) regions, right?

Tuesday, October 31, 2006

You're Shadowing My Stupidity Overload

When I wrote my Overloads vs Shadows post, I was obviously still in the grips of my confusion. One of those times when you think you're being clever, but in fact you're not quite clever enough.

Having looked into what the compiler does (and admittedly not much more at the spec), and calmed down a bit, I offer this attempt at clarification.

  • Within the same "declaration context" (Class, Interface or Module), you can use the same name more than once, as long as at most one of the uses is a typey thing (class, enum, event/delegate), and all the others (which are methods or properties) have different signatures. No keywords are necessary nor can they influence the compiler's behaviour.
  • When considering inherited members with the same name as your own members:
    • If you're overriding a method/property, that's fine. We all know what that's about.
    • Otherwise, by default, the member in your class Shadows all inherited members of the same name. None of the inherited members are accessible except by casting your object reference to the base type.
    • However, if you add the Overloads keyword to the member in your derived class, the member only makes inaccessible any base members that have the same signature.

So the confusion stems (for me at least) from being brought up to believe that Overloads means "there are other methods/properties in this class with the same name". Curse you, section 4.1.1!

I promise never to use Overloads this way again.

Catch When What?

Joe Duffy's excellent blog has just taught me something (in guideline 16 of this article) that I didn't know about structured exception handling in VB.NET, and which is not explained in the language spec (see 10.10.1).

What do you think this code should do?

    1 

    2 Module Module1

    3 

    4     Private _value As Integer

    5 

    6     Sub Main()

    7         _value = 42

    8         Try

    9             Trouble()

   10         Catch ex As Exception When _value = 7

   11             MsgBox("Oh, that's all right then.")

   12         Catch ex As Exception

   13             MsgBox("The non-7 value is: " & _value.ToString)

   14         End Try

   15     End Sub

   16 

   17     Sub Trouble()

   18         Try

   19             Throw New Exception

   20         Finally

   21             _value = 7

   22         End Try

   23     End Sub

   24 

   25 End Module

   26 

It prints "The non-7 value is: 7" of course.

Without a great deal of research (i.e. none) it seems the two passes mentioned by Joe are:

  1. find the target of the exception (i.e. the closest matching catch block on the stack);
  2. transfer control to that catch block via each finally block between it and the throw point.

Therefore no finally-block code will have executed when the When clause is executed, so invariants could still be broken.

No big deal (since exception filters should be kept simple), but worth knowing.

Tuesday, October 24, 2006

Overloads Overloads

Finally got around to digging into something that's been bugging me since February, re the warning message that can be issued by VB.NET in VS2005: "Inappropriate use of 'Overloads' keyword in a module".

As related in that post, the Microsoft explanation (from the lovely Amanda Silver) is: "the Overloads keyword only makes a difference to the semantics of the application when the method is overloaded across an inheritance chain". But we all know that an overload is when two methods (properties etc.) share the same name but have different signatures, right? It even says so in the VB language spec (section 4.1.1): "The only way to declare identically named entities of the same kind in a declaration space is through overloading."

Ah, but that's the concept called overloading, which is obviously different from the overloading keyword. A few pages further on in the spec (section 4.3.3), all is made clear: "Shadowing by name is specified using the Shadows keyword. ... Shadowing by name and signature is specified using the Overloads keyword.". I.e. "overloads" is actually overloaded in Visual Basic! And those C# snobs call us stupid ;-)

Joking aside, the point is that Overloads and Shadows are telling the compiler about the relationship between a name in the current class and the same name in base classes, not about the relationship between same-named members within one class. They are saying "this member is not related to members of the same name that I happen to inherit; specifically, it does not override any of them". So actually, these keywords are only necessary when the base member is overridable (i.e. virtual).

As mentioned, the difference between the two keywords is that Overloads prevents overriding of a specific signature while Shadows prevents overriding of anything with the same name; the following code is illegal:

    1 

    2 Public Class Class1

    3 

    4     Public Overridable Sub F(ByVal x As Integer)

    5     End Sub

    6 

    7     Public Overridable Sub F(ByVal s As String)

    8     End Sub

    9 

   10 End Class

   11 

   12 Public Class Class2

   13     Inherits Class1

   14 

   15     Public Shadows Sub F(ByVal y As Integer)

   16     End Sub

   17 

   18     Public Overrides Sub F(ByVal s As String)

   19         MyBase.F(s)

   20     End Sub

   21 

   22 End Class

   23 

It generates the error "sub 'F' cannot be declared 'Overrides' because it does not override a sub in a base class." on line 18. Replace Shadows with Overloads on line 15 and it works just fine.

Here's the equivalent in C#, which only has a single keyword for this duty, i.e. new:

    1 

    2 public class Class1

    3 {

    4     public virtual void F(int x) { }

    5     public virtual void F(string s) { }

    6 }

    7 

    8 public class Class2 : Class1

    9 {

   10     public new void F(int y) { }

   11     public override void F(string s) { }

   12 }

   13 

This compiles fine, leading us to deduce that new is equivalent to Overloads. However in the book on which I cut my .NET teeth (Table 7-4), Jeffrey Richter cites Shadows as the VB equivalent of new.

Hmm, I wonder... Did Overloads start off meaning "I meant to give these methods the same name" but morph into its current meaning when Microsoft realized Shadows was a bit too blunt-edged?


Update 31/10/2006

I was obviously still confused when I wrote the above post, so I've attempted to straighten it out here.