All atomic-powered posts from July 2010:



Sustainable Agile Training

For the last 10 years, Atomic Object has been a pioneer in agile software development. During this decade, we have produced hundreds of projects for over 100 satisfied clients. Why so satisfied you might ask? Aside from our freshly popped popcorn, it’s because we consistently deliver high quality software in a highly predictable timeframe.

These attributes have not gone unnoticed. We have become known for this strong process that really produces great work, and it has become commonplace for customers to request agile training for their own development teams. We’ve done this training in the following two ways:

1.) The Traditional Approach

The traditional approach is what most people think of when they hear the word training. In this approach we identify the aspect of “agile” that the customer would like to learn about (i.e. testing, velocity tracking, simple design, pair programming, etc) and then craft a course that meets the request. These courses are usually week-long engagements that include hands on exercises. We have recently conducted a similar training in Baltimore.

Although these types of engagements are beneficial for companies, here at Atomic, we feel that there is an even better way to create a long-term sustainable change within an organization. This leads us to the second, preferred approach.

2.) The Integrated Approach

Integrated training is when we join the client’s development team for an extended engagement. These types of engagements generally last at least 3 months, which allows team members to internalize the concept, become comfortable with it, and then really apply it to the fullest extent – all under the guidance of experienced agile developers – and in their own code base. This approach commonly happens with companies that are trying to create a small agile team within a larger waterfall-centric organization. The approach here is to work directly with the client’s development team, creating software towards their current internal goals. During this time we also integrate our various agile practices. The beauty of this approach is that a team doesn’t have to take time off from development for training; instead, the training happens naturally while software is actually being created.

The main challenge that most clients face when adopting agile practices is not their willingness or ability, but rather, their organization’s ability to deal with the change. Being on the ground floor of this change allows us to innovate and modify process outputs to fit into the unique structure of the organization. An example of an innovation would be a modified burndown chart that more closely matches what the marketing department requires, or a tool that automatically generates high-level system requirements based on test output for the compliance department. We have found that these are the types of custom tweaks that are needed for a small agile team to be successful long-term within a larger organization.

In summary, integrated training is the preferred choice because:
  1. The client team continues to get real work done while they learn to be agile.
  2. Atomic helps customize agile process outputs to match the client’s organizational needs.
  3. Management’s greater buy-in (longer engagement) signals their dedication to the training effort.
  4. Better chance for long-term agile sustainability.

A New AO Library

Atomic Object has always embraced the scholarly side of Computer Science. We encourage conference attendance and participation, writing for trade journals, and sharing technical expertise through our company blog. During the lunch hour, employees frequently give “brown bag” talks—presentations on a particular technology, problem, or methodology. When they’re not developing software at work, employees are expected to develop professionally, that is, to investigate new technologies and hone their skills. And before founding Atomic, our president, Carl Erickson, was a professor of Computer Science at GVSU, making it safe to say that AO’s had these scholastic sympathies from the very beginning.

Another symbol of our academic bent is our rather large library – yes, a physical library – of books, made available for use by Atomic employees. We have books on, to name a few, operating systems, system administration, visual design principles, agile methodologies, project management, and oh so many programming languages. In fact, our burgeoning library was outgrowing its space on our IKEA shelving, not designed to withstand the weight of such CS tomes as Knuth’s 3 volume set, The Art of Computer Programming. Also, the classification system was getting muddled, with newer books horizontally stacked atop older books being the only recognizable taxonomy.

And so we needed a new solution. Luckily for us, our Business Manager, Mary, has a background in commercial interior design and was able to use her skills in drafting to design an entire wall of built-in bookcases. With all the information radiators around the office, wall space has become an increasingly scarce commodity, so the final design left an opening for the whiteboard currently occupying the wall in addition to ample shelving. [Nerdy art history sidebar: The design references the facade of our building, symmetrical, with a large entablature supported by two engaged pilasters.] Our friend Ken Idema (of Ken Idema Builders) created the library shelves, continuing his habit of beautifying our space.

The lot of re-”cataloging” our books – unfortunately – fell on me. Lacking a technical background, you can imagine how mind-boggling it must have been to rely on reason alone to organize books on C, C++, C# and Objective-C. (Let alone Cocoon?)

With the help of a friend, the oversight of an intern, and a little sweat equity, we have made the library easier to navigate (usable) and gave it ample room for growth (scalable).

Through the process of moving and organizing the books, I became rather fond of these books so foreign to my own education – or were they? I couldn’t help but notice the prejudice for modern art cover designs among the books. They featured works by Pete Mondrain, Wassily Kandinsky, M.C. Escher, Georges Seurat (the connection of pointillism to pixels is a given), to name a few.

So please – admire with me the final product – an homage to order, learning, and to craftsmanship (of all kinds).


Atomic Object's Library

Atomic Object Typography Book

Simplicity is Not the Answer

Don Norman writes about why Simplicity Is Not the Answer

If my cellphone only had one button it certainly would be simple, but, umm, all I could do would be to turn it on or off: I wouldn’t be able to make a phone call. Is the piano too complex because it has 88 keys and three pedals? Should we simplify it? Surely no piece of music uses all of those keys. The cry for simplicity misses the point.

Converting to UTF-16 and UCS-2 with Iconv

Recently the SME Toolkit, a project sponsored by the International Finance Corporation (a member of the World Bank Group), was attempting to send international SMS messages. This gave everyone on the team a good lesson in character encodings. We had previously utilized UTF-16 to send our SMS messages to the telephone company which we were partnering with for international messages. However, when we tried to send our SMS messages to a telco in Sri Lanka, they requested that we use a predecessor to UTF-16 known as UCS-2.

Since we knew UTF-16 and UCS-2 were very similar, we didn't anticipate any problems. (The major differences between UTF-16 and UCS-2 occur for characters which we were not concerned about). We dutifully converted our messages to UCS-2, and sent them off -- only to find that no one in Sri Lanka could read them. They showed up as gibberish on our testers phones, or were not even accepted by the telco's SMS gateway -- being rejected as malformed. What had happened? UTF-16 and UCS-2 are supposed to be similar, right? Well, they are similar. Unfortunately, character encodings are widely misunderstood, and implementations differ widely. A particular program may handle even similar encodings in very different fashions.

After discovering we were sending nonsense messages, we decided to examine the logs. To our surprise, we discovered that not only was the telco receiving messages from us without a byte order mark (BOM), they were receiving our messages as if they were little endian -- with the least significant byte first! This was a major surprise to us as we had anticipated that our messages would be sent just like UTF-16: with a BOM so that the actual byte order was not an issue.

It turns out that there is a snag with the Unix Iconv library (libiconv) on certain systems depending on the system's endianness. We converted our messages in Ruby using the Iconv library which utilizes the local system's library. It seems that Iconv silently omits the BOM when converting messages to UCS-2, but does include the BOM when converting messages to UTF-16. This is surprising (and somewhat concerning), as the UCS-2 encoding is byte order sensitive, just like UTF-16. In addition, the default byte order is supposed to be big endian. Unfortunately, we couldn't find a good explanation for this behavior, so we simply adapted.

We recognized the problem when doing a trial a conversion with the Iconv library in IRB from UTF-8 to UCS-2:

  • On a local system:
    irb(main):001:0> Iconv.conv("UCS-2","UTF-8","a")
    => "\000a"

  • On our production server:
    irb(main):001:0> Iconv.conv("UCS-2","UTF-8","a")
    => "a\000"

For comparison, the Iconv library in IRB does include the BOM when converting from UTF-8 to UTF-16:

  • On a local system:
    irb(main):002:0> Iconv.conv("UTF-16","UTF-8","a")
    => "\376\377\000a"

  • On our production server:
    irb(main):002:0> Iconv.conv("UTF-16","UTF-8","a")
    => "\377\376a\000"

While this type of behavior in Iconv may be intended, it certainly is confusing and unhelpful since it isn't documented. I could find no information regarding intended behavior of Iconv other than the odd forum post which referred to UCS-2 conversion in Iconv being "broken." The UCS-2 standard allows a BOM, but it can be omitted. This wouldn't be such a problem if Iconv always converted into the same variant of UCS-2 rather than switching between big endian and little endian depending on the current architecture.

Somewhat cryptically, Ruby outputs the contents of a byte as the ASCII equivalent, or the octal value if that will not be visible. So, in our case, the character "a" gets displayed as "\000a" on one machine, and "a\000" on the other machine. This is endianness in action. One machine is clearly putting the most significant byte first, the other the least significant byte first. This is a problem since the UCS-2 standard specifies that in the absence of a BOM, the bytes should be interpreted as big endian.

Instead of receiving the character "a" (Unicode: 0x00 0x61), the telco would have received the character "愀" (Unicode: 0x61 0x00) -- a Han ideograph. No wonder the Sri Lankan phones couldn't display it!

Discussion with the telco in Sri Lanka revealed what we had come to suspect: they wanted the UCS-2 messages to be big endian. I suppose it would have been helpful if they would have specified this in the first place, but they might have (rightfully) expected that we would use the default -- big endian.

In order to force our server to use big endian, we specified it explicitly when doing our conversions with Iconv:

  • On our production server:
    irb(main):0003:0> Iconv.conv("UCS-2BE","UTF-8","a")
    => "\000a"

This effectively solved our problem. No longer did we have to worry about whether our machine was representing characters differently than the telco's machines -- we specified exactly which encoding and byte order to use. Sadly, documentation of character encoding issues like this is very sparse and we had to do much research and testing ourselves before coming to this conclusion.

Further reading:

Polyglot Persistence and Rails 3

Developers at Atomic really value using the right tool for the job. That’s why we occasionally get together outside of work to learn and teach new technologies. Keeping up with the latest tools and approaches is easiest with a group of friends and a couple of beers, so last month we organized an after-work exploration of some non-relational databases. The experience got us thinking about persistence in the new world of NoSQL and Rails 3.

ORM agnosticism has recently become a core principle of Rails. An ORM is a mapping between objects and relations, but in Rails 3 this can mean more than just alternative syntax for the same relational operations. Now your models can be persisted in an entirely different data storage paradigm, or a combination of new and old. That means more flexibility to think about your application outside of tables and columns, without sacrificing the familiarity and convention of Rails.

As with any newcomer to your application stack, you’ll need time to get familiar with performance and operational characteristics of a NoSQL database, so don’t put all your persistence eggs in the same basket. Our own approach to integrating these new tools is to take baby steps: apply them where their novel features can shine instead of completely throwing out the standard approach. Use MongoDB for the part of your app that needs a more flexible schema, and keep using Postgres for payment processing, where its transactions and durability keep it in the game.

This integrated approach to using multiple data stores is often called “polyglot persistence”. It’s more than just a transitional step towards replacing your database. It means letting you always use the right tool for the job and not falling into a monocultural mindset. The salient conclusion of our recent foray was that each database makes its own tradeoffs. Web apps wear MongoDB well, but it’s not best for critical transactions involving multiple records. Neo4j doesn’t pretend to be a whole-app data store, but might be the best way to query your huge social network. Redis is extremely flexible but it may take more work to solve your common problems: it’s more of a general-purpose toolkit than an out-of-box solution. SQL databases are still useful and mature tools for many problems, especially where transactions are necessary.

The new directions in Rails 3 aren’t just about letting you replace ActiveRecord. They entirely decouple the ORM from the core framework, so you can pick the right tools and have them all coexist in harmony. But to fully realize the dream, the greater Rails’ gem ecosystem needs to shift a bit. On a recent project combining Rails 3, ActiveRecord, and Mongoid, we’ve noticed a few common problems.

The first is gems too targeted toward ActiveRecord. Mongoid is extremely similar to Rails’ default ORM, but some gems focus so much on providing magic that they lack the configurability necessary to adapt to new storage paradigms. Too much magic without configurability can lead to too strong a tie to ActiveRecord. Rails 3 offers the convenience of convention without sacrificing the flexibility of configuration, which is a good model to follow.

Another problem we’ve seen is gems that try to accommodate multiple ORMs, but assume only one will be present. This is an acknowledged limitation of Database Cleaner, which would otherwise make fixture cleanup in a multiple database scenario easy and straightforward.

Once we got through these issues, working in a our polyglot rails application has been a fantastic experience. MongoDB has already paid off by allowing us to embed one document inside another for a surprisingly elegant solution to a modeling problem. At the same time using ActiveRecord for user accounts has let us continue using Clearance for breezy authentication and reserved the option for transactional payment processing.

This is really exciting.

How to Talk About User Experience With Clients

The language that we as UX practitioners use to talk to each other isn’t always useful to our customers. Author David Sherwin suggests having a cheat sheet for talking to clients about the business value of UX and shares his own cheatsheet as a guide.

Can You Say That in English? Explaining UX Research to Clients

As much as I’d like to tell my clients to go read The Elements of User Experience and call me back when they’re done, that won’t cut it in a professional services environment. The whole team needs a common language and a philosophy that’s easy to grok.
I created a cheat sheet to help you pitch UX research using plain, client-friendly language that focuses on the business value of each exercise.

Programming for Wikipedia

As one of the top ten sites on the Internet, Wikipedia is well known both for being the largest encyclopedia in the world and for having a highly unconventional editorial process. What far fewer people know about is the community of editors that has built up around the project.

While occasional, often anonymous contributions comprise the majority of article content on Wikipedia, tens of thousands of regular editors — the core community — deal with such internal tasks as article cleanup, coordinating efforts, fixing bad edits, and managing the site. I have edited Wikipedia since 2006 (though with varying degrees of activity), and it is quite an interesting and useful experience. Wikipedia’s organizational structure is extremely decentralized out of necessity, but there are numerous procedures governed mostly by convention. There is no central authority; the Wikimedia Foundation, while officially controlling the project, rarely goes beyond facilitating volunteer editors’ work.

I mostly chose to involve myself with cleaning up existing articles, monitoring new edits, and writing editing tools. Wikipedia allows users to add scripts written in JavaScript to their account in a manner similar to Greasemonkey. There are a number of these scripts, ranging widely in purpose: modifying the interface, automating common tasks, and giving easy access to technical information are some of the most common uses.

When I first started editing, I had little knowledge of programming. Some of my first experience with programming came as a result of installing a Wikipedia script that gives information about an article’s quality while viewing the article. (This isn’t as fancy as it sounds; Wikipedia has a process for assessing articles, e.g. as “B-class,” “C-class,” etc., and most articles have this information readily available but not very visible.) It was quite useful, but it had bugs, and the script’s original editor had stopped working on it. Since all user contributions to Wikipedia can be freely modified, I copied the script and tried to fix the problems with it, learning JavaScript in the process.

The script was quite basic and only used by a few people when I started working on it. Over time, I ended up rewriting most of it and adding features, mostly for my own use, but every now and then at another editor’s request. It’s now a pretty useful tool, providing a summary of an article’s passage through various editorial processes, as well as the ratings given to it by groups of editors dealing with specific topics; it’s gained more users, too, though there isn’t an easy way to tell how many.

To most people, Wikipedia is simply a useful resource, but to those who spend some time contributing to it, Wikipedia is a place to both find information and improve your own knowledge and skills by working on it.

Grand Rapids Agile UX Retreat

Atomic Object hosted a second Agile UX Retreat in Grand Rapids, Michigan over the weekend of July 10-11, 2010. The first retreat was hosted earlier this year by Cooper in San Francisco. The group was initially brought together by Anders Ramsay and Lane Halley to focus on creating a new blend of user experience (UX) practices and agile software development practices.

I’ll happily admit to having more than one “pinch me” moments over the weekend as I looked around the room at the thought leaders represented in the participants who’d come to Grand Rapids from all across the country. [Side note: in our experience with bringing software professionals from major metropolises to Grand Rapids, the near universal response is compliments and utter surprise on how much GR has going on and how attractive a city it is. If GR was a company, it would desperately need a marketing strategy.] I haven’t had my brain stretched this much for some time. On the other hand, I don’t know what else I should have expected considering the talent and personalities in the room, the fact that we represented distinct disciplines each with its own history, terminology, and perspective, and the incredibly ambitious nature of the work we’re doing. Potentially so ambitious, in fact, that the idea that what we were really discussing was a post-industrial approach to collaborative, interdisciplinary, creative team work was given serious debate.

The group of twenty participants included developers, designers, testers, researchers, company owners, consultants, and employees. Approximately half of us had participated in the first retreat, and half of us were new to the group. I felt we had a great balance between new and old, and a useful diversity of experience and opinion. The spirit of mutual respect and collaboration was both remarkable and productive. The group self-organized, with a few people naturally and effectively facilitating as necessary. The Factory in downtown Grand Rapids provided a great physical space for our work.

The majority of our time (at least if you don’t count dining and drinking at San Chez Bistro on Saturday night) was spent on two initiatives. The first was to craft a statement of values. The second was to organize and summarize a list of brainstormed problems we’ve all experienced. We concluded the retreat with a plan for continuing the work we started, and a strong desire to meet again soon and push this important effort forward.

AUX Retreat Grand Rapids

Presenter First in GTK and C

Recently Mike Karlesky and I spent a week in the Baltimore area leading up a workshop-style training course. The intent of the workshop was to demonstrate Agile techniques applied in the embedded domain.

As part of the workshop, I created a small GTK application to demonstrate Presenter First and Model-View-Presenter. (Although a GUI application may not seem particularly embedded, the principle is the same: the view walls off some untestable library; the presenter and model allow us to test around it.) GTK turned out to be a good choice, since the events flying out of its widgets were much like the asynchronous events that come out of other windowing toolkits or hardware devices.

And here it is: the aptly named PF Calculator. Guess what? It’s a calculator. The calculator’s functionality is quite limited, in that it can only divide integers, but it still demonstrates Presenter First concepts quite well:
  • The ApplicationPresenter responds to events from the ApplicationModel and ApplicationView.
  • The ApplicationView fires events roughly corresponding to events coming from GTK widgets. Along the way, it does some translation to only relay the relevant information and remove traces of GTK in the event.
  • The ApplicationModel is used to compute the “business logic” (haha, I love that term, especially when applied in such a silly context). The Model delegates to the NumberValidator to get some help when needed.
  • And last (but not least), all of the above code was written Presenter First.

Everything is implemented in C. Here are a few notes about the implementation:
  • In a language with automatic object construction, I’d have the Presenters wire up their events in their constructor methods. Since that strategy isn’t available here, I’ve instead implemented a Presenters_RegisterForEvents function. The purpose of the function is to rip through all of the Presenters and tell them to RegisterEvents. It would be trivial to have the build system automatically generate this file in a project with many Presenters.
  • I only support one subscriptor to any single event. This is because I didn’t feel like implementing a bounded array or linked list to hold the function pointers. I did see something about a GSList data structure available in the GLib documentation, but I never got around to trying it out.
  • I call the gtk_init function in main before firing up the application. I’m not wild about this GTK-specific knowledge leaking outside of the view, but for this very simple example, it was the cleanest way to handle this detail. In a real project I’d strive to keep GTK specifics confined to views.
I depend on a number of libraries and tools to get them job done. More notes:
  • I’m using the Ceedling build and test harness developed by Mike Karlesky, Greg Williams, and Mark VanderVoord. Ceedling gives me easy access to unit testing via Unity, C mock generation via CMock, and C exceptions via CException. Ceedling also weaves everything together to create the executables.
    • Ceedling hasn’t had a 1.0 release yet, but the code available from the Sourceforge project is quite functional.
  • I used this project as an excuse to monkey around with the PCRE library. I didn’t use it extensively, but it was enough to get a taste. It turns out PCRE is tasty.
  • I also recently heard about bstring and tried it out. Again, I didn’t use it for much, but enough such that I’m sold on it.
Warning: I haven’t tried to build this code on anything other than my personal Linux system, so I can’t say how portable it is. Here are some details about my system:
  • The Linux distribution is Ubuntu 10.04.
  • The GTK development files have been installed via the libgtk2.0-dev package.
  • The PCRE development files have been installed via the libpcre3-dev package.
  • bstring is bundled with the project.
  • The build system relies on Ruby and Rake. The build system uses pkg-config commands to gather the build flags for PCRE and GTK. Hopefully this means it will be easier to build the project on an arbitrary system.

To build and run the application, type rake. To run all the tests, type rake test:all. To test an individual module, like ApplicationModel, type rake test:ApplicationModel.c.

Big thanks to Mike Karlesky for assisting with Ceedling, CMock, and Unity. Also thanks to Greg Williams and Mark VanderVoord for helping develop this great software.

Resources:

Edit July 13, 2010: The article was initially published without the Ubuntu package names filled in. This has been corrected.

Consolidate Multiple FileSystemWatcher Events

The .NET framework provides a FileSystemWatcher class that can be used to monitor the file system for changes. My requirements were to monitor a directory for new files or changes to existing files. When a change occurs, the application needs to read the file and immediately perform some operation based on the contents of the file.

While doing some manual testing of my initial implementation it was very obvious that the FileSystemWatcher was firing multiple events whenever I made a change to a file or copied a file into the directory being monitored. I came across the following in the MSDN documentation’s Troubleshooting FileSystemWatcher Components

Multiple Created Events Generated for a Single Action

You may notice in certain situations that a single creation event generates multiple Created events that are handled by your component. For example, if you use a FileSystemWatcher component to monitor the creation of new files in a directory, and then test it by using Notepad to create a file, you may see two Created events generated even though only a single file was created. This is because Notepad performs multiple file system actions during the writing process. Notepad writes to the disk in batches that create the content of the file and then the file attributes. Other applications may perform in the same manner. Because FileSystemWatcher monitors the operating system activities, all events that these applications fire will be picked up.

Note: Notepad may also cause other interesting event generations. For example, if you use the ChangeEventFilter to specify that you want to watch only for attribute changes, and then you write to a file in the directory you are watching using Notepad, you will raise an event. This is because Notepad updates the Archived attribute for the file during this operation.

I did some searching and was surprised that .NET did not provide any kind of wrapper around the FileSystemWatcher to make it a bit more user friendly. I ended up writing my own wrapper that would monitor a directory and only throw one event when a new file was created, or an existing file was changed.

In order to consolidate the multiple FileSystemWatcher events down to a single event, I save the timestamp when each event is received, and I check back every so often (using a Timer) to find paths that have not caused additional events in a while. When one of these paths is ready, a single Changed event is fired. An additional benefit of this technique is that the event from the FileSystemWatcher is handled very quickly, which could help prevent its internal buffer from filling up.

Here is the code for a DirectoryMonitor class that consolidates multiple Win32 events into a single Change event for each change:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;

namespace FileSystem
{
  public delegate void FileSystemEvent(String path);

  public interface IDirectoryMonitor
  {
    event FileSystemEvent Change;
    void Start();
  }

  public class DirectoryMonitor : IDirectoryMonitor
  {
    private readonly FileSystemWatcher m_fileSystemWatcher = 
      new FileSystemWatcher();
    private readonly Dictionary<string, DateTime> m_pendingEvents = 
      new Dictionary<string, DateTime>();
    private readonly Timer m_timer;
    private bool m_timerStarted = false;

    public DirectoryMonitor(string dirPath)
    {
      m_fileSystemWatcher.Path = dirPath;
      m_fileSystemWatcher.IncludeSubdirectories = false;
      m_fileSystemWatcher.Created += new FileSystemEventHandler(OnChange);
      m_fileSystemWatcher.Changed += new FileSystemEventHandler(OnChange);

      m_timer = new Timer(OnTimeout, null, Timeout.Infinite, Timeout.Infinite);
    }

    public event FileSystemEvent Change;

    public void Start()
    {
      m_fileSystemWatcher.EnableRaisingEvents = true;
    }

    private void OnChange(object sender, FileSystemEventArgs e)
    {
      // Don't want other threads messing with the pending events right now
      lock (m_pendingEvents)
      {
        // Save a timestamp for the most recent event for this path
        m_pendingEvents[e.FullPath] = DateTime.Now;

        // Start a timer if not already started
        if (!m_timerStarted)
        {
          m_timer.Change(100, 100);
          m_timerStarted = true;
        }   
      }
    }

    private void OnTimeout(object state)
    {
      List<string> paths;

      // Don't want other threads messing with the pending events right now
      lock (m_pendingEvents)
      {
        // Get a list of all paths that should have events thrown
        paths = FindReadyPaths(m_pendingEvents);

        // Remove paths that are going to be used now
        paths.ForEach(delegate(string path)
          {
            m_pendingEvents.Remove(path);
          });

        // Stop the timer if there are no more events pending
        if (m_pendingEvents.Count == 0)
        {
          m_timer.Change(Timeout.Infinite, Timeout.Infinite);
          m_timerStarted = false;
        }
      }

      // Fire an event for each path that has changed
      paths.ForEach(delegate(string path)
        {
          FireEvent(path);
        });
    }

    private List<string> FindReadyPaths(Dictionary<string, DateTime> events)
    {
      List<string> results = new List<string>();
      DateTime now = DateTime.Now;

      foreach (KeyValuePair<string, DateTime> entry in events)
      {
        // If the path has not received a new event in the last 75ms
        // an event for the path should be fired
        double diff = now.Subtract(entry.Value).TotalMilliseconds;
        if (diff >= 75)
        {
          results.Add(entry.Key);
        }
      }

      return results;
    }

    private void FireEvent(string path)
    {
      FileSystemEvent evt = Change;
      if (evt != null)
      {
        evt(path);
      }
    }
  }
}
Filed in: Technologies, Tips

Catching exceptions via NSInvocation and NSProxy is no longer possible in Objective C

This issue has already been raised in several places, but in the hopes of adding some more visibility to the issue I figured it would not hurt to post it here. Under the iOS 3.2 and iOS 4 simulator platforms it is no longer possible to catch exceptions via NSInvocation and Apple’s object proxy mechanism (NSProxy). Specifically, it makes it almost impossible to use OCHamcrest and OCMock as they both rely heavily on dynamic invocation and proxy objects.

The issue has already been raised here:

I created a sandbox project in an attempt to diagnose the various scenarios in which exception handling did not work. Until Apple releases a fix for the bug it is going to take some creative work-arounds in order to “move on” from the issue.

Read the rest of this entry