In many programming languages, it’s a popular conventionor even a language rulethat class names begin with a capital letter and class instances begin with a lowercase letter. For example, you might have a
Dog class and a particular instance of that class named
dog. In other words, you have a
dog is a
I just accepted that as the normal state of affairs, until I read my daughter her new book Just Dog.
Just Dog begins:
“Dog was a dog and that’s what everyone called him. Dog. Just Dog.”
Now wait a minute. The story doesn’t say
dog is a
Dog, it says Dog is a dog.
Come to think of it, I’m not a
mike, I’m a person named Mike.
So why do we use a naming convention in programming that is the exact opposite of how we name things in the real world?
And even more puzzling, why does it feel right?
Mike Sax wonders what’s the fuss about iterators. Aren’t they just a fancy use of function pointers? Indeed, Mike has hit the nail on the head. Consider the window iterator that’s been built into Windows since 1.0:
This function iterates through all of the top-level windows (children of the desktop window) and calls
lpEnumFunc for each one, passing it the
HWND of each window and the
lParam that you passed to
lParam is how you get to provide some state that the enumeration function can make use of. Suppose you wanted to write a function that counted the number of visible top-level windows. Your C code might look like this:
This works, but it is rather tedious. So Windows 2.0 added the
GetWindow function, which lets you simply ask for a window’s child or next sibling. That simplifies the overall structure of the code, especially if you use the
GetNextSibling macros defined in
That’s it, just one function, no callback function or struct definition needed. We don’t need the struct because the code inside the loop can directly reference the
nVisible variable defined in the function.
But the simplification came at a price: We had to write the loop ourselves, asking explicitly for the first child of the desktop window and then the next sibling of each child window.
Also, it doesn’t work.
What if another application creates or destroys a top-level window, or just changes a window’s Z-order, while you’re in the loop? You’ll either miss a window, count one twice, or crash with an invalid window handle.
To handle these cases, you need a bit more complexity. If you had a way to temporarily lock all window creation and destruction, you could quickly create a list of all the windows and then release the lock, then enumerate from that list, perhaps also doing a last-minute check when you enumerate each window to skip any that get destroyed during enumeration. Or, you might set a Windows hook to notify you of any windows created, destroyed, or moved in the Z-order, so you could deal with them appropriately.
Whatever you did, it would be enough code that you wouldn’t want to duplicate it each time you wanted to write a window loop. The
GetNextSibling style of loop doesn’t really facilitate that kind of code isolation. The
EnumWindows style enumerator completely separates the code that does the iterating (
EnumWindows itself) from the code that receives the iteration (your callback function). But, it makes it harder to share state between the callback function and the code that called
Both those language have enough extra syntactic cruft that when you look at a simple example using nested anonymous functions, it’s easy to be unimpressed. The payoff shows up in more complicated, real-life coding situations.
Code blocks in Ruby simplify this technique down to its essence, making it useful even for simple cases. Assuming a good Rubyesque Windows interface library, our function might be something like:
In this code, the
enumWindows function takes a code block argument and calls that code block for each window, passing it the window as an argument. Because the code block is nested inside the
countVisibleWindows function, it can access the
nVisible variable directly.
This solves both our problems: The logic for iterating through the windows is separated out into the
enumWindows function, and the callback function (code block) can access state variables cleanly and easily.
(In Ruby, a code block is a like a callback function, but it’s not quite a full-fledged function. A code block does not introduce a new scope for variablesit shares the scope of the enclosing function.)
Unfortunately, Ruby does not seem to have a Windows interface library that works like this. Ruby’s standard
Win32 module provides a general way to call Windows DLL functions, but it doesn’t have a clean implementation of
enumWindows that uses a code block.
However, MoonWolf has written a Ruby port of Perl’s Win32::GuiTest module that includes this kind of
enumWindows function. It’s implemented in two parts: a low level function written in C that enumerates
HWND values, and a higher level function written in Ruby that constructs Ruby
window objects and enumerates them. The
window object in
Win32::GuiTest is a fairly thin wrapper that encapsulates an
HWND and other window information.
enumWindows looks like this:
This code calls the low-level
_enumWindows function, which passes an
HWND to the code block enclosed in curly braces. This code block creates the
window object, appends to the
ret array, and also yields the window object to a code block that was provided by the caller of
If I were implementing this, I think I would change it a bit. Typically a function like this either yields results to a code block, or it returns a value, but not both. And I would change the confusingly named
createWindow function (which has no relation to the
CreateWindow function in Windows):
Either way, our
countVisibleWindows example ends up pretty much as I’d imagined:
enumWindows function that enumerates
HWND values is implemented in C. The initialization code to add the
enumWindows function is simply:
mGuiTest is a reference to the
guitest_enumWindows function is:
EnumWindowsProc callback is:
This shows how easy it is to extend Ruby with C code, adding functions that work just like ones written in Ruby.
So, how do all the calls and callbacks stack up when we run the
countVisibleWindows function? Something like this:
In everyday use, of course, you don’t worry about that whole call stack, just the part of it you’re working with.
I had to fix a bug recently where my shell extension was crashing another application when you used that app’s File Open dialog.
This application has a thumbnail view of the selected file in the File Open dialog, which they generate the same way as Windows Explorer: by loading a shell extension for the selected filetype and calling its
IExtractImage interface. It’s a fairly weird protocol: First they call your
IPersistFile::Load to give you the filename, then you give them back the same filename when they call
IExtractImage::GetLocation. Finally they call
IExtractImage::Extract and that’s when you generate the thumbnail.
But, after my
GetLocation method returned, the application silently exited. What could be wrong? My code worked fine in Explorer.
GetLocation is a typical function that takes a character string buffer and length along with some other parameters (omitted here):
I noticed that this other app was giving me an unusually large file pathname buffer, 520 characters or 1040 bytes to be exact. This number sounded strangely familiar (and not just because of this).
Then I realized what happened. I’ve never seen the source code for this app I was crashing, but I just know it looked like this:
cchMax argument to
GetLocation is a length in characters, but
sizeof gives you the size in bytes. And we’re talking
WCHAR here, so each character is two bytes.
MAX_PATH is 260, making
szPath 520 bytes long, the number that they passed into my code.
One way to fix the problem is:
That gives correct code, but I never like seeing
MAX_PATH repeated like this.
sizeof is in the right spirit, actually measuring the array length instead of repeating a constant, but it measures the wrong thing, bytes instead of characters (array elements).
I like to code this with the
elementsof macro, defined as:
Then you can just use
elementsof instead of
elementsof is handy anytime you need the length of a character string array or any array.
Of course, I didn’t have the luxury of fixing this code at its source (other than reporting the bug to the program’s authors). So I worked around it by checking for the bogus 520 character
cchMax and cutting it back to 260 (
Making a valiant attempt to post code with my comment system (Sorry, Mike! :-(), Mike Roome points out:
The ruby example isn
Matt Pietrek marvels at C# 2.0 iterators and dissects them right down to the CLR bytecode. I always learn something from Matt, and this whirlwind tour is no exception.
Matt says, “This was the beginning of my descent into the loopy world of C# 2.0 iterators. It took me awhile to wrap my head around them, and when I tried to explain them to other team members I got looks of total confusion.” I wonder if it would have been less confusing if Matt’s team had first been exposed to
yield iterators in a language that makes them easier to use.
After using Python and Ruby, the iterators in C# feel right at home to me. They work the same in all three languages, but in Ruby and Python there’s not as much other code to get in the way of understanding them.
Let’s combine all of Matt’s examples into one, and compare the code in each language. First, in C#:
When you run that, it should print:
Here’s how you would write the same code in Python:
And in Ruby, the code looks like this:
The one unfamiliar thing here may be the
|name| notation, which is how a code block such as the body of a loop receives its argument. And the
p statements are a kind of print statement.
This Ruby version is even more concise and equally readable once you’re comfortable with the
Either way, the Python and Ruby versions make it easier to see what the iterator function does and how
yield interacts with the rest of the code.
You may note that the Python and Ruby versions don’t create and instantiate a
SomeContainer class as the C# version does. That’s true, and it would make the code in those languages a bit longer (but still simpler than the C# code). But, if you don’t need to—and you especially don’t need to when you’re experimenting and trying to understand a radical new technique like
yield iterators—why bother?
Wow! This is nice work! I’ll live with it being written in PHP. ;-) It was easy to get running on my virtual Linux server, once I figured out how to add a MySQL user for WordPress. The default stylesheet stinks big-time, but the WordPress Wiki pointed me to the Style Competition, where I found the Rubric style was closest to my taste. I tweaked it a bit and here we are.