Wednesday, December 10, 2008

C# odditiy: Object initializer scope

I was reviewing some code today and ran across something that looked like this:
SomeProperty = SomeProperty

Odd, I thought that doesn't do anything, probably not what the writer intended. I sort of ignored it since I was doing some refactoring that removed that line anyway and went on. When I realized I didn't have any tests covering this bit of code, I saved my changes, reverted the unit, wrote a test and ran it, expecting a failure. Much to my surprise, it worked.

In context, the function looked sort of like this:
public class SomeClass
{
    public string SomeProperty { get; set; }

    public object Clone()
    {
        return new SomeClass { SomeProperty = SomeProperty };
    }
}

Looking at this, I expected both the SomeProperty properties to be in the scope of the object initializer and end up not doing anything, essentially assigning the property to itself. The test seemed to indicate otherwise. Thinking I had a problem with my test, I set some breakpoints and did some evaluation at run-time. I didn't see anything wrong with the tests and everything seemed to be working.

Still convinced something had to be wrong, I did some searching on the web trying to find somebody who talked about scoping rules in object initializers. Of course, I may not have hit on the correct search terms, but in any case I didn't find anything. So I wrote the following console application:
namespace TestObjectInitializerScopeConsole
{
    public class TestClass
    {
        public string TestText { get; set; }
    }

    class Program
    {
        public static string TestText { get; private set; }

        static void Main(string[] args)
        {
            TestText = "Some random text";
            Console.WriteLine("this.TestText = \"{0}\" (initially)", TestText);

            var test1 = new TestClass();
            Console.WriteLine("test1.TestText = \"{0}\" (without initializer)", test1.TestText);

            var test2 = new TestClass { TestText = TestText };
            Console.WriteLine("test2.TestText = \"{0}\" (with initializer)", test2.TestText);

            Console.WriteLine("Enter to finish...");
            Console.ReadLine();
        }
    }
}

According to this test, it seems to indicate the scope for items on the left hand of the assignment are the new object and those on the right hand are what you'd normally expect for the method. It seems pretty odd and anti-intuitive to have different scope like this.

Any comments? Am I missing something? Is this defined somewhere that I've missed? Does it seem weird to anyone else?

Friday, December 5, 2008

How to show WWSGD text in Blogger

I've been doing quite a bit of reading regarding the ins and outs of blogging, search engine optimization and building readership. In the course of this, I read 21 Ways to Make Your Blog or Website Sticky. In that article, Darren Rowse mentioned a WordPress plug-in by Richard Miller called What Would Seth Godin Do. Based on an observation by Seth Godin, this plug-in allows customized messages to viewers based on the number of times they visit your site.

Intrigued by this idea, I set off to find something similar for Blogger (a.k.a. Blogspot) based sites. After a lot of searching, I failed to find anything. I figured it couldn't be too hard; I'd just roll my own. It took a bit more work than I expected, but I finally came up with my own variation. There is no code shared at all with the WordPress plug-in; it's simply similar functionality inspired by Seth's observation and Richard's implementation. The following explains how to configure a Blogger site display different text based on a user's visit count.

First, go into the Layout tab for your site and then the Page Elements sub-tab. Click on Add a Gadget. Select the HTML/JavaScript option. In the Content section, place something like this:
<div id="NewVisitor" style="display: none;">Thanks for visiting! Use the RSS feed or e-mail subscription to keep up to date on what's happening on this site.</div>
<div id="ReturningVisitor" style="display: none;">Welcome back! We're glad you enjoy our writing. If you especially like a particular article, please consider casting a Digg vote. Thanks!</div>
I'm no copywriter and obviously you'll want different text, but the important thing is to have two div sections with IDs of NewVisitor and ReturningVisitor, and with a style attribute for both set to display: none;. When the page is loaded, one section or the other will be changed to visible based on the result of a cookie.

Except for the limitations of ID and style, the rest is normal HTML. You can put things that are common to both text sections outside the div sections. Inside the div sections, put things you want displayed for the context identified by the ID attribute.

Save the gadget. Since the text is inside a gadget, you can move it to where you want it to display.

Next, select the code below and copy it to the clipboard. Then go to the Edit HTML section of your blog configuration and scroll down through the template code until you find the line that says <body>. Just above this line, there will be one that says </head>; paste the copied code just above the </head> line.

<!-- Start of script for "WWSGD" div manipulation -->
<script type='text/javascript'>
function getCookie(c_name)
{
  if (document.cookie.length > 0)
  {
    c_start=document.cookie.indexOf(c_name + "=");
    if (c_start != -1)
    {
      c_start=c_start + c_name.length+1;
      c_end=document.cookie.indexOf(";",c_start);
      if (c_end==-1) c_end=document.cookie.length;
      return unescape(document.cookie.substring(c_start,c_end));
    }
  }
  return "";
}

function setCookie(c_name,value,expiredays)
{
  var exdate=new Date();
  exdate.setDate(exdate.getDate()+expiredays);
  document.cookie=c_name+ "=" +escape(value)+
      ((expiredays==null)
        ? ""
        : "; expires="+exdate.toGMTString()+
      "; path=/");
}

function checkCookie()
{
  wwsgd_count=getCookie('wwsgd_count');
  if (wwsgd_count == null || wwsgd_count == "")
  {
    wwsgd_count = 0;
  }
  else
  {
    wwsgd_count = parseInt(wwsgd_count);
  }
  setCookie('wwsgd_count',wwsgd_count+1,365);
  visibleTag = 'ReturningVisitor';
  <!-- This will show the "new visitor" text three times.
      Change 3 to the desired value. -->
  if (wwsgd_count &lt; 3)
  {
    visibleTag = 'NewVisitor';
  }
  divToSee = document.getElementById(visibleTag);
  if (divToSee != null)
  {
    divToSee.style.display = "block";
  }
}
</script>
<!-- End of script for "WWSGD" div manipulation -->

(For those with sharp eyes, JavaScript's less than operator is encoded above. This is by intent. It needs to be encoded in the Blogger template when it is saved. It gets converted to a real less than sign and used properly when it is sent to the client's browswer.)

Finally, on the <body> line, before the closing ">", add onLoad='checkCookie()'. When done, this line will look like:
<body onLoad='checkCookie()'>

When these three things are finished, the site should show the items inside the NewVisitor div section the first three times it is visited. After that, the items inside the ReturningVisitor should be displayed. If you want a different count for the first message, change the numeral 3 in the script (indicated by a comment) to the desired number. If cookies aren't enabled, then nothing will be displayed.

Leave a comment if you have any thoughts or find this useful. Thanks!

Resources

Thanks to the following for information found useful in the development of this tool:

Monday, November 24, 2008

Microsoft's OfficeUI Ribbon: Application template

I've been working with the recently released Ribbon control from Microsoft's Office UI group. There are several cookie-cutter setup steps to get an application ribbon aware. In order to facilitate setting up a new application, I made a Visual Studio 2008 template that creates a blank application containing a ribbon bar with some empty controls.

Here is the template file. Copy this zip file to My Documents\Visual Studio 2008\Templates\ProjectTemplates\Visual C#. When Visual Studio is started, the New project dialog displayed when File | New | Project... will have a new Ribbon Application option under My Templates. Select this to create a skeleton ribbon application.

When the application is created, an error will be displayed indicating the ribbon control library cannot be found. This is because this library needs to be acquired directly from Microsoft. To get it you need to go to the OfficeUI web site. (Here are the how-to-get instructions.)

Once the library is downloaded and installed on your computer, go to the new ribbon application's References, remove RibbonControlsLibrary and then add it in again, pointing to the location on your computer.

The skeleton application contains a Close option on the application menu to stop the application. There is a single tab with a single group containing a single button. Finally, there is a single button on the quick access toolbar. These all can be used as templates to easily add more.

More information on creating Visual Studio templates can be found on the MSDN site. (Thanks to paranoid ferret for the pointers on to how to create templates.)

Friday, November 14, 2008

How much of the implementation can be hidden by interfaces?

Short answer: All of it.

Consider this example:
unit uSomeManager;
interface
type
    ISomeManager = interface
    ...
    end;
function SomeManager: ISomeManager;
implementation
type
    TSomeManager = class(TInterfacedObject, ISomeManager)
    ...
    end;
var
    gSomeManager: ISomeManager;
function SomeManager: ISomeManager;
begin
    if not Assigned(gSomeManager) then
       gSomeManager := TSomeManager.Create;
    result := gSomeManager;
end;
Notice what is in the interface part of the unit. There are two things: the interface that is being defined and a global function which returns something implementing that interface. There is no class information  whatsoever. The entire implementation of this interface, including the class declaration, is in the implementation section of the unit. This prohibits others from using this class in any other way. They can't extend it, override it or instantiate another copy of it. If they want a different implementation of this interface, they have to completely re-implement it.

Whether or not this is a Good Thing is another discussion, but it does make it very clear to the user that it is intended to only have one instance of this. I find it works well for places where you might want to use a singleton, without the low-level messiness normally associated with them in Delphi.

Thursday, November 6, 2008

Splash screens are evil! 8 ways to improve them.

Ok, perhaps evil is too strong a word, but ideally splash screens should not be needed. They represent a failure on the part of the development team to make an application that can load fast enough that the user isn't left wondering what happened when they double click its icon. The best case is to make the program load fast enough that it's not needed. As a developer, I realize minimizing application start-up time can be a really hard problem, possibly hard enough that it's not worth the resources to invest in this area of optimization.

Faced with this reality, here are some guidelines, splash screen etiquette if you will, to make it less obnoxious. These are things I've come up with as a user of many different software packages over the years within the context of having done a fair bit of reading in the area of user interaction and experience. I find it interesting that after a bit of searching on the topic, both on the web and in some dead-tree resources, I have found many people talking about splash screens' visual design but no one describing their functionality.

1. Not centered: that's where I'm working!

I typically have a minimum of three applications open. Quite frequently I have two or three times that number. When I start an application, the odds are I have something else I'm working on, and want to continue working on, while the new application is starting. The center of the screen is where my focus is normally going to be for those other applications. Therefore, the center of the screen is the worst place the splash screen can go. It's going to be right in the way of my doing anything else.

2. Not modal: I'm trying to do something else.

The splash screen should should not be system modal. I am working on something else while the new application tries to get going. There is no reason to think the splash screen is more important than what I'm working on. The splash screen should not ever cover up my current work.

3. Not focused: I'm not typing to you.

The starting application should not grab focus unless no other application has it. If another application has focus, it should maintain it. If I'm typing, I'm not typing into the not yet started application, I'm typing to the existing application. (Microsoft Office Outlook team, do you hear me?!?)

4. Not too big: you're not that important.

All the splash screen needs to do is tell me it's working. To do this it just needs a small, unobtrusive animation. I'm willing to give splash screens 5% of my screen. If it can't let me know it's there in a 300 x 300 pixel box, the designers need to rethink what they're trying to do. Ideally, I should be able to size it to the dimensions I want, including minimized.

5. Not fixed: I want that space.

Even when it's not centered, I should still be able to move it where I want it so it's out of the way. No matter where the designers set it by default, there is always going to be the case where, for someone, that location is in the way. Make the silly thing movable, like any other window on my system.

6. Not default: remember what I've told you.

After I've told you where and how big, remember it! Next time I start the application, odds are my system is going to be about the same configuration. I've gone through the hassle of moving it and sizing it; I shouldn't have to do it again tomorrow.

7. Not a non-task: be on the task bar.

The splash screen should cause a button to appear on the task bar; preferably the same button that will be used by the main form when it finally appears. This way, one of the sizes I can give it (see #4 above) is minimized. This allows me to know the application is starting without it having to take any of my precious screen space.

8. Not needed: delay initialization.

Finally, the ideal is to not need a splash screen at all. Consider making the main form visible immediately with things disabled. As modules are loaded and initialized, then build the form and enable the various areas for the user.

Friday, October 31, 2008

PDC2008.Last;

I reported on the first half of PDC2008 the other day. Today I reflect on the last half of the conference.

Wednesday's keynote reviewed work being done by Microsoft Research, a division that's involved in pure research. They're an impressive group. Started in 1991, they have grown to over 850 PhD researchers in six locations around the world. Each summer they have 1000 graduate student interns working on projects. 25% of Computer Science PhD graduates in the United States have worked for Microsoft Research by the time they finish their degree. 15% of the division's budget is granted to universities. 30% of papers read at peer-reviewed conferences are submitted by Microsoft Research fellows.

One of the most interesting items they presented was a highly modified surface device. (A surface device is a multi-touch sensitive table top display.) This particular device was configured such that if you put another semi-opaque surface over it, something like a piece of tissue paper or frosted plastic, then a different image would be seen on the secondary screen. An example was a picture of an animal on the primary display. Hold a piece of paper over it and text about the animal was seen. Pretty cool stuff!

Another really cool piece of software technology presented in one of the sessions on Wednesday was the Concurrency Analysis Platform, or CAP for short. This is a low-level library used during the testing cycle that inserts itself between the application and the operating environment and replaces the thread scheduler. There are implementations for both Win32 and managed code. This provides a means for testing tools be built that explicitly control the scheduler. Think about this for a second. The scheduler is no longer non-deterministically interrupting your code, but rather can be controlled in a deterministic manner. Very, very cool.

CHESS is an automated tool built on this framework that analyzes a project and finds the points where schedule interleaving may make a difference. Without this analysis, it would have to run each thread with each line interrupted by the scheduler. This problem's scale is nnk where n is the number of threads and k is the number of lines. With the double exponent, relatively small numbers cause this to explode to more permutations than there are estimated atoms in the universe. By analyzing the code, the problem space can be reduced to (n2*k)c*nn where c is a small number, like 2 or 3, and n and k are as defined previously. This becomes a much more tractable problem space.

Within this reduced space, the tool runs the code with each permutation of schedule interleaving to detect assertions, dead-locks, live-locks and data race conditions. When a failure is found, the problematic interleaving can be captured to directly, consistently reproduce the problem. Over my career, this could have saved me literally weeks of debugging time. During the session, they presented a couple real life case studies where this tool was used to find and fix very obscure, rare threading bugs in non-trivial code bases. They have also used it on several projects to find and fix bugs that have not yet been experienced. Obviously, using a tool like this throughout the development cycle has the potential to significantly increase the reliability of threaded applications.

Thursday marked the end of PDC2008. We had the same number of break-out sessions but ended early since there was no keynote speaker and only a short break for lunch. As I attended the sessions, it seemed like they had saved some of the best material for last.

First up are two new things coming out the research arm: CodeContracts and Pex. These two independent but complementary technologies are designed to improve code quality.

Inspired by Bertrand Meyer's Design by Contract work and rooted in the earlier Microsoft Research project Spec#, CodeContract is a .NET library to enforce method and class contracts. Calls to the CodeContract class are put at the beginning of methods to indicate requirements (pre-conditions) and expectations (post-conditions). As far as the build process is concerned, these become part of the method signature, so warnings and errors are emitted during build for cases where static analysis can detect calling code that violates the contract. Further, parts of classes can be marked as invariant, allowing the same checks on derived classes without re-declaring the constraints. Lastly, these same conditions can be placed on interfaces. This allows the checks to automatically be applied to all implementing classes without the class having to explicitly declare them.

Pex is a static code analyzer which works without CodeContracts but will use the additional information contained in them if they exist. It provides additional information about the warnings emitted by the CodeContract as well as the facility to automatically generate test cases based on method signatures and branches within the code that it has analyzed. Basically, it maximizes code coverage in the target class while minimizing the number of test cases needed for that coverage.

The last session I attended was a well presented introduction to the newish language F#. It is a functional language[1] in the same way C++ is object oriented. The purpose of C++ is to write object oriented code while not excluding procedural code. Similarly, F#'s purpose is to write functional code while not excluding an object oriented paradigm. F# has been around for a couple years as a research language and has matured to the point where it's going to become a fully supported language in the near future.

The presenter started with a common, simple math problem and implemented it in F# using a typical procedural approach. It was basically line for line how it'd be written in C# with F# syntax. He then rewrote it in a slightly more mathematical way and then again using a fully functional approach.

Following this he presented a more realistic problem of downloading a CSV file from Yahoo's financial web site, slicing the data apart, running it through a function and emitting some results. He leveraged existing classes of the .NET framework for the data gathering and used a bit of F# code to do the data manipulation and glue things together. The first implementation had a single thread of execution. He finished with a highly impressive finale: with very minor changes to about three lines of code, he transformed this into a multi-threaded app that gave the same results in significantly less time.

All in all, this was a great conference with a lot of really interesting information. Videos of the sessions are available at microsoftpdc.com/.

1. One of the major tenets of functional languages is side-effect free methods. This eliminates many dependencies on order of execution, in turn making threading a much easier problem.

Wednesday, October 29, 2008

PDC2008.Length mod 4 = 2

I'm now at the half way point of my first Microsoft conference. I've attended many conferences in the past, but this is my first sponsored by the Redmond giant. For a Monday morning start, I flew into LA Sunday afternoon on a CRJ-700. I must say it was the quietest plane I've ever flown on. Sunday evening I had a delightful dinner with some family who live in the area.

Overall, the conference itself has been very good. Good presenters. Great information. Super food. The purpose of this conference is for Microsoft to cast their vision of the computing future. It is mostly about new technology that has not been released yet. This spans the gamut from next versions of current products to things in research to directions they think the industry is headed.

In Monday's keynote they talked about a new product called Windows Azure that they are positioning to be the OS for the web. It's made up of a number of coordinating services such as .Net Services, SQL Services and Live Services that they host in their data centers. The idea is they take care of the infrastructure and you use it to put your applications in. It reminds me of Amazon's offering on a larger, more ambitious scale. As they talked about it, I kept having two thoughts: really cool technology! And, how do they pay for it? I thought they were going to finish without answering the question. But at the very end, they finally claimed they haven't worked out all the details, but it'll probably be a subscription service based on traffic and needed reliability.

In Tuesday's keynote, Windows 7 was presented. It's the next version of the desktop client to replace Vista in 18 or so months. Each attendee was given a hard drive, as well as a CD, with the install for Windows 7 and a host of other software to support it. I tried installing it on a virtual machine from the CD but got errors about a file not being found. It installed flawlessly, and much faster, from the HD. So far I haven't had a chance to use it other than playing around with a few settings, but as a pre-beta release, it seems pretty mature. Someone claimed everyone at Microsoft is using it for their day to day work.

So far there have only been two down sides to the conference: the bumper music has been awful; it makes me want to do violence to some sound equipment. And secondly, the special event last night was at Universal Studios. I was there once before and sort of ambivalent about going, but the food was free and I figured I'd check out the changes they've made in the last 20 years. It was terrible. None of the rides held any interest to me whatsoever and the lines were long enough I didn't feel like wasting any of my life on them. The worse part though was they were prepared for Halloween. This meant they had people in costume that would try to scare people, get in their face and generally be highly annoying. In addition, smoke machines limited visibility to 4 feet in places and the music (using the term loosly) was loud enough I couldn't hear the people taking my order for food. Needless to say, I didn't spend more time there than needed to get dinner and leave. They did a great job at changing my ambivalence about going to outright refusal for future visits.

Wednesday, August 20, 2008

Never write software that fails silently!!

One of the tenets of software development is to fail early. The earlier something fails the less costly it is since you don't have as much invested as if it failed later. Visual Studio needs to learn this lesson.

I just spent the better part of an hour trying to figure out why a DeploymentItem attribute on a test didn't work. I had created some new files for the test, added them to the project and created an attribute that should have copied them over. The test didn't fail in the expected manner, because the code hadn't been updated to handle multiple files, but rather because there were no files at all. Setting a break point indicated that in fact the files were not being copied even though the were right there in the project.

After much frustration, I found through cygwin's grep the missing element: the files themselves needed to have their Copy to Output Directory property changed from Never to Every time. Why couldn't anything in the five steps leading up to the test execution have told me there might be a problem?

(And why did Explorer's Search fail to find the files that grep did?!?)

Monday, July 21, 2008

Adventures in firmware development: You learn something new everyday

Ethernet and TCP/IP, the core technologies for the internet, have been around long enough that typically you plug things in and they "just work." So I have been pretty puzzled the last couple weeks trying to figure out why this little Ethernet development kit I'm working with had a 30 second delay on initial start up. Internally, I could see the controller thought everything was up and running, it just didn't see any packets even though the link and data lights would light up.

I contacted technical support for the board and they couldn't reproduce the problem. Hmm. I hate those kinds of issues. After a number of messages back and forth, we found that I was going through the corporate router and they used direct connections to their test PCs. I changed my configuration to talk directly to my PC and the problem went away. Well, this was a step in the right direction.

So, the next step was to talk to our network admin to see if he had any ideas. He immediately remembered a configuration parameter called PortFast on our switches that by default was disabled.

PortFast is an option on Cisco switches to turn STP, short for Spanning Tree Protocol, on and off. I'd never heard of it before but this is what I learned: when you have multiple switches, routers and hubs on a network, it is possible to create a physical loop. Without STP, a physical loop can cause each router to forward packets to the other, ad infinitum, flooding a network with an increasing number of identical packets leading to a non-responsive network. It's basically a DOS attack on yourself. STP is something implemented by switches to detect physical loops so they can filter problematic packets, eliminating the cascades that can take down a network.

STP has five steps it goes through, two of which take approximately 15 seconds each. This is where my delay came from. When you have something plugged into a switch that you know cannot create a physical loop, you can enable PortFast. This bypasses these two steps, changing the start up time from around 30 seconds to almost instant.

The network admin hasn't had a chance to change this setting, but in a number of tests, I'm almost certain this is the problem I was having. I can reliably set things up to keep the router from knowing the board has reset. When I do this, it restarts in a few seconds; the expected behavior. In the end, the problem had nothing to do with the new board and everything to do with the existing router. It happens all the time with my PC too, it's just that the computer takes long enough to boot that the network has finished its protocol negotiation by the time the computer is ready to go.

For more detailed information:

Friday, July 18, 2008

Adventures in firmware development: New task, new tools

Idaho Technology, the company I work for, is experimenting with the idea of using ethernet for communicating with future instruments. Since our hardware engineers have zero experience with networking, and I have some from the PC side, I've recently been tasked with helping them out. I must say, it's been a delightful change of pace from the Windows desktop app development I've been doing of late.

Last time I worked on firmware was 20 years ago. Way back then, to change the the code on the device, I had to use a command line C compiler to generate .hex files on a PC. Then I used an EPROM burner to put it on a memory chip, physically take the memory out of the burner and put it in the device and finally turn it on. Debugging was a matter of examining the source code (and sometimes the generated assembly code) to figure out why it didn't work as expected. Changes to the code involved taking the memory out of the device, erasing the memory using UV light for 30 minutes (I think that's how long it took) and doing the whole, compile/burn cycle over again. The insides of the chip were completely opaque; there was no way to examine what was going on inside the device.

Now, the tools are so much cooler. I have a ethernet development system with an 8051-based micro-controller and programmer sitting on my desk. The programmer is plugged into the PC through a USB port on one side and to the 8051 controller through a ribbon connector on the other. There's an IDE I can use to program, compile and download the new firmware to the chip through. No power cycles on the device, no memory chips to erase and program. And the really, really cool thing: I can set breakpoints, evaluate registers and step through the firmware all from my PC. It's not much different than writing software for the PC itself.

Yeah, I know, these tools have been around for awhile. It's just this is the first time I've had a chance to play with them. Pretty fun stuff.

Tuesday, April 1, 2008

Welcome to the new home of Skylark Software

We're in the process of changing our servers. The old articles will be posted here as I have time to move them over and I have plans, time permitting, for new articles.