Hello, Apple? It’s 1999 calling. Can we interest you in a feature set?

Cut and paste.

MMS.

Search.

Everything old is new again.

Cut and paste, MMS highlight iPhone 3.0 improvements | Software | iPhone Central | Macworld.

(And yes, I own an iPhone and love it. These three features match the top three complaints I’ve had with it, so I’m very pleased. It’s just a little funny that these features are being added in version 3 instead of version 1, but sales figures don’t lie.)

Published in: on March 19, 2009 at 3:23 pm Leave a Comment

SMTP over SSL with Rails 2.2.2

I spent several hours yesterday trying to get Rails 2.2.2 to send SMTP mail through our secure Zimbra server. I’m still fairly new to Rails, but I couldn’t for the life of me figure out how to get ActionMailer to do it. The support may exist in Net::Mail, but I’m still a rails n00b and wasn’t very interested in writing my own mail code from scratch; I’m too spoiled by having ActionThis and ActionThat do all the work for me (not to mention the fact that I have (billable) customer work waiting for me.

Yet my mad google skillz paid off in the end, when I found Douglas F. Shearer’s dead-simple and invaluable solution:

Douglas F Shearer :: Weblog :: GMail SMTP with Ruby on Rails and ActionMailer .

Hats off to Douglas. Also to whomever coined the term “monkeypatching”, which I first became familiar with yesterday, during my trek through the wilderness.

Published in: on March 18, 2009 at 10:16 am Leave a Comment

Box, VBox, HBox

Yeah, they’re legacy when Gumbo comes out, but I’ve still been meaning to write this down because I find it interesting, and more interesting that not a lot of Flex developers I’ve talked to about it are aware of it.

So VBox and HBox are, unsurprisingly, subclasses of Box. However, they are probably the thinnest subclasses I’ve personally looked at in the SDK. The only thing that they add is the following line.

VBox.as:
mx_internal::layoutObject.direction = BoxDirection.VERTICAL;

HBox.as:
mx_internal::layoutObject.direction = BoxDirection.HORIZONTAL

Well, actually they each do one other thing–they prevent you from changing the direction, by including the following code:


override public function set direction(value:String):void
{
}

This is, presumably, to keep you from hurting yourself by turning your HBox into a VBox. I’m not sure why didn’t just make the setter final in the superclass, but hey, I just use the things, I don’t make ‘em.

Anyway, this simple application shows a behavior that, while mostly useless, is still cool and unappreciated:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">

  <mx:Script>
    <![CDATA[
      import mx.containers.BoxDirection;
      private function flip() : void {
        if (box.direction == BoxDirection.HORIZONTAL) {
          box.direction = BoxDirection.VERTICAL;
        } else {
          box.direction = BoxDirection.HORIZONTAL;
        }
      }
    ]]>
  </mx:Script>

  <mx:Box id="box" horizontalCenter="0" verticalCenter="0" horizontalAlign="center" verticalAlign="middle">
    <mx:Box width="50" height="50" backgroundColor="0xFF0000"/>
    <mx:Box width="50" height="50" backgroundColor="0x00FF00"/>
    <mx:Box width="50" height="50" backgroundColor="0x0000FF"/>
    <mx:Button label="Flip It" click="flip()"/>
  </mx:Box>

</mx:Application>

(Sorry if that’s cut off a little; I haven’t yet installed WordPress on my own site so I can’t get a decent code formatter plugin.)

I would love to know why they made a whole class (BoxDirection) for two constants that, as far as I can tell, are only ever used by Box and its subclasses. There’s a bit of back-and-forth in the SDK on this; I notice it a lot with events, where some Event classes (like FlexEvent) define their own constants, while others (like CollectionEvent) utilize a separate class (CollectionEventKind, in this case).

Perhaps it will all make sense in Gumbo.

Published in: on March 6, 2009 at 12:00 pm Leave a Comment

Theory vs. Experimentation

I love debuggers. I really do. I’ll spend three hours wiring up a a new debugger/IDE configuration to get five minutes’ use out of it. But anything becomes a crutch if you lean on it all the time. (Plus your armpit gets all funky.)

I’ve just been working through a very odd bug in a Flex application we at roundpeg are  building for one of our customers. We have a DataGrid with a list of people–shocking, I know–and one of the testers noticed that after he clicked on a person who shared the same last name as another person in the list, he was not able to select the second co-surnamed person. He would click, but nothing would happen. And it only seemed to happen with entries in the list who shared this field in common.

So, off I go into the debugger. I’ll save you the details because they’re tedious and boring, as the whole experience was, but suffice it to say that four hours later, at line 8,351 of mx.controls.listClasses.ListBase.as, I decided that the approach I was taking was suboptimal.

So I stopped debugging. And I started to comment out code. I commented out a bunch of code in the code-behind class for my list, and what do you know, the problem went away. I started uncommenting line-by-line, and, voila, found a single line in that class that was the jumping off point for the problem. Now of course I wasn’t done there–that single line invoked a controller method that had a cascade of effects, and I was soon commenting out message dispatches, narrowing them down to the one that, again, eliminated the problem (along with other important functionality) when it was commented out. Then it was on to searching for and commenting out methods that were receiving the error-inducing message (one of the drawbacks of an event-driven system, that searching is). And finally I found the line in our code that was causing the problem: We were setting the selectedItem property of the list at the same time it was being set by the DataGrid’s own click handler.

It wasn’t necessary for us to do this–I can’t imagine a case where it would be, since the selected item already was the object in question, but it certainly shouldn’t have caused this bizarre behavior. It wasn’t for nothing that the code existed; it was there to cause the list to select an item newly added by another interface, but happened to reuse a message that was also emitted when a new item in the list was selected.

My best guess (and at 4 AM with the problem fixed I wasn’t interested in exploring it any more) is that somehow the object comparison was getting muddled. It’s a lousy guess, since object equivalence should be a matter of comparing the UIDs of two references, and the “U” in UID is for Unique.

To make a long story… well, not any longer, the title references a common tension in the scientific community between theorists and experimenters. It isn’t always present, and from my position as an avid follower but non-practitioner of physics I’m not aware of it becoming anything like, say Cowboys versus Redskins, or UI engineers versus server-side engineers. But the tension exists, and for good reason–both approaches are essential, but they’re different, and at different points in time, under varying circumstances, one or the other will be adding more value to solving the problem at hand.

In my case, I began with the theory. “I’m going to do this the right way,” I thought. “I’m going to use the debugger and really follow what’s going on, until I understand the whole process and can pinpoint exactly where the failure occurs.” That is a perfectly reasonable, very-often-correct approach. And if my goal was to understand the problem, that would be the right approach. But it wasn’t, not really. My goal was to fix the problem. Of course I needed to understand it enough–enough to have a general idea of the processes at work, and enough to have narrowed down the list of culprits from the entire universe (or at least the body of source code from Flash Player down to the hardware).

But as the hours wore on and yesterday turned in to tomorrow, I just needed to fix the damn thing. And that’s where experimentation took over.

A theory predicts what is. An experiment proves what isn’t. Per Holmes:

When you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.

Sometimes you just need to put down the book, pick up the magnifying glass, and start eliminating the suspects..

Published in: on March 5, 2009 at 10:23 pm Leave a Comment

The Eightfold Way of Meeting Visual Requirements

Everything shall have:

  1. The right font
  2. The right assets
  3. The right color
  4. The right alpha
  5. The right size
  6. The right width
  7. The right height
  8. The right position
Published in: on August 24, 2008 at 11:04 pm Leave a Comment

Oh, Ted

FTMFW!

Really, who hasn’t had days like this? But poor Ted must be feeling sore in parts of his body he never realized would be affected by his professional life.

Published in: on December 22, 2007 at 6:30 pm Leave a Comment

lolboat

brij.gif

Published in: on at 5:50 pm Leave a Comment

Or, Cool, Fast, Cheap

Continuing a theme–just so long as “cool” comes in addition to, rather than instead of, “good”.

Cooler, Faster, Cheaper: Researchers Advance Process To Manufacture Silicon Chips

Published in: on December 3, 2007 at 3:59 pm Leave a Comment

Good, Cheap, Fast Works Too

It’s unsurprising, but the principle is universally true.

good-cheap-fast3.jpg

Via Oomsa, one of my favorite new ways to waste time.

Published in: on December 2, 2007 at 9:43 pm Leave a Comment

Software vs. Whiteboard

Whiteboard wins.

The manual whiteboard allows flexibility in tracking patients,” Bisantz said. “For example, maybe the first time the provider sees a patient, she initials the name on the whiteboard, then the next time she circles the initials, then when the patient is discharged, she might put an “x” in the circle, signals that are a means of communicating with her colleagues in the ER.

“With a computerized system, providers have to find an available computer terminal and log-in,” she said, noting: “The providers can’t just walk up to the whiteboard and make a notation.”

In some cases, providers noted that computer systems hid some of the information; if only three comments could be viewed per screen, they had to click to get to another screen, requiring them to search for information that might demand immediate attention.

The study also found that there were fewer visual cues with the computational system. Some providers noted that they used to be able to get a sense of the status of the emergency department just by walking through the room and visually checking the manual whiteboard.

Often in this business we set out to replace tools and process that we consider outmoded, ineffective, inefficient and error-prone. Certainly those adjectives apply to the whiteboard. What we often–far too often–fail to examine is the way in which those tools are used, and this article (and presumably the underlying study, which doesn’t appear to be publically available) illustrates a perfect case study of what can go wrong when that happens.

I’ve experienced a similar phenomenon when writing software for the mortgage industry. As anyone who’s ever purchased a home is aware, this industry has historically been dominated by mountains of paperwork; what’s true for the consumer is also true for the provider. Replacing at least some of this paper tracking with electronic systems seems like a natural business opportunity, and indeed doing so is a laudable goal and has been done successfully in many cases. However, a simple, undocumented, informal process can turn out to be both extremely important to the user and very difficult to replicate.

In this particular case, the process involved the order of files in a mortgage processor’s inbox. It turns out that many processors prioritize work simply by moving files to the front of the stack. You won’t find that written down anywhere, and you won’t discover it unless you physically go to the workspace and spend time unobtrusively observing your user’s current behavior. But replace those files with a software application that doesn not allow the processor to move a file to the front of the stack, and you’ve created a situation much like replacing the whiteboard: Your users, frustrated, either find extra-systemic workarounds or simply reduce their productivity.

Also, you might not ever know this is happening. Very often in enterprise software, end users are so far removed from project owners that they don’t feel able or welcome to provide negative feedback as they adopt the new system. I’ve experienced this again and again: You can spend months working with your customer’s management implementing, testing and deploying the shiny new enterprise app; then you get a couple of people who actually use the software on the phone or in a closed room, and they unleash a wave of very accurate criticism that’s completely new to you.

All of this points to usability testing, of course, but usability testing is only going to tell you, at best, whether what you’ve already designed, prototyped or built is working for your users. This really comes down to a fundamental difficulty in the early product marketing stages of product development. You must remember that nobody knows a job better than the person doing it, and to design successful enterprise software, you (and your customers) have to be willing to find out, up front, just what that job really is.

Published in: on November 27, 2007 at 10:32 am Leave a Comment