<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Nuthole</title>
 <link href="http://localhost:4000/atom.xml" rel="self"/>
 <link href="http://localhost:4000/"/>
 <updated>2023-01-04T11:59:13+01:00</updated>
 <id>http://localhost:4000</id>
 <author>
   <name></name>
   <email></email>
 </author>

 
 <entry>
   <title>Five leadership lessons I learned from dancing</title>
   <link href="http://localhost:4000/blog/2018/06/26/five-leadership-lessons-i-learned-from-dancing/"/>
   <updated>2018-06-26T12:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2018/06/26/five-leadership-lessons-i-learned-from-dancing</id>
   <content type="html">&lt;p&gt;Throughout my adult life, and even sometimes when I was a teenager, people have told me that I have leadership qualities, or that they’ve noticed people looking to me for direction. For a long time, I never really paid much attention to this idea. Now and then, someone would ask me  to help lead their club or organization, because they looked at me and saw what they thought was a leader.&lt;!--more--&gt; But most of the time, I sort of floundered in these positions. I simply didn’t know how to lead an organization or its people, and I’d quickly lose interest. And my work as a software developer, often hunched over a computer keyboard solving problems by myself for hours on end, never really made me feel like much of a leader. To me, it seemed that a leader was supposed to have an agenda they’re trying to realize, and some sort of ability to convince people to jump into action to work on that agenda. This doesn’t sound anything like me! I’m just trying to do my job, right? Do I have an agenda? Can I somehow make people just do things for me?&lt;/p&gt;

&lt;p&gt;As my career has advanced, I’ve reached a point where there is sometimes an expectation and/or a specific request for me to step up and lead a team of developers in some way. I’ve gingerly stepped into this sort of role a few times, but haven’t always known how to proceed. Am I supposed to be a manager? Should I get an MBA? For me personally, I don’t really think so, but I think that’s OK, because I’ve started finding a path forward from an unexpected area: &lt;strong&gt;dance&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A few months ago, I started attending a Lindy Hop course. Lindy Hop is a form of swing dance that has plenty of variation and movement, and (for more advanced dancers) lots of speed and acrobatics. This is my first time trying to learn how to dance at all, so for me, everything is new. I was aware from the start that in most forms of partner dance, one person (typically a man) is supposed to “lead,” and the other (typically a woman) is supposed to “follow.” I had no idea what those words meant in practice, however. Looking at a couple doing Lindy Hop, I just saw two people moving in unison, with no obvious communication between the two of them. Who’s the follower and who’s the lead? How is the lead telling the follower what to do?&lt;/p&gt;

&lt;div style=&quot;width:100%;height:0;padding-bottom:56%;position:relative;&quot;&gt;&lt;iframe src=&quot;https://giphy.com/embed/w5fkGvP9pgRB6&quot; width=&quot;100%&quot; height=&quot;100%&quot; style=&quot;position:absolute&quot; frameborder=&quot;0&quot; class=&quot;giphy-embed&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;&lt;font size=&quot;-1em&quot;&gt;[via &lt;a href=&quot;https://giphy.com/gifs/chicago-w5fkGvP9pgRB6&quot;&gt;GIPHY&lt;/a&gt;. &lt;b&gt;This is not a depiction of the author&lt;/b&gt;.]&lt;/font&gt;&lt;/p&gt;

&lt;p&gt;For as long as I’ve observed (but not practiced) partner dance, this has been a mystery to me. Even knowing that the man is typically the lead, I couldn’t see what the man was actually &lt;em&gt;doing&lt;/em&gt; to lead his partner. In fact, if you disregard the conventions of gender, clothing, and who’s spending more of their time spinning around, it’s really hard for an outsider to see who’s the lead and who’s the follower. For the dancers, however, it’s as plain as day. Once I began to understand how leading and following works in Lindy Hop, it wasn’t long before I started thinking about how these concepts might relate to the concept of leadership in other areas, such as work, politics, sports, or even just a group of friends out for a night on the town.&lt;/p&gt;

&lt;p&gt;Here are five key elements I’ve identified for successfully dancing with a partner, and some ideas about how they relate to leadership in work, and in other aspects of life.&lt;/p&gt;

&lt;h2 id=&quot;1-get-a-feel-for-each-other&quot;&gt;1. Get a feel for each other&lt;/h2&gt;

&lt;p&gt;A lead and a follower negotiate the basics of their dance wordlessly, and in just a few seconds. When dancing with a new partner, we start off in a predetermined position. Her right hand is in my left hand, my right arm is reaching around her back or waist, and her left arm is resting on my right upper arm, with her hand on my shoulder. In Lindy Hop, this is called “closed position.” We bounce lightly with the music for a few beats, and together we establish a certain amount of tension between our bodies, through our arms. Neither of us are stiff, and neither of us are flopping around like fish, we’re going for the “just right” amount of tension. We maintain a comfortable hold on each other, with a small distance between us. Imagine you’ve just hugged an old friend, and have then leaned back a little to look them in the eyes and say, “Good to see you, old friend,” but you still have your arms part-way around each other; it’s something like that. There’s no tight squeezing going on, but you’re not quite letting go, either.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;To successfully lead people, it’s important to establish rapport. Especially in work situations, it’s often the case that people will simply be assigned to follow someone, regardless of whether they feel any natural affinity with that person. If you’re assigned to lead a group of people, it’s important to try to get close to them at a human level, in a friendly, relaxed way. Don’t just barge in and start bossing people around; Instead, meet people on their own terms, sit down to talk with them, try to get a feel for who they are.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;2-get-on-the-floor-together&quot;&gt;2. Get on the floor together&lt;/h2&gt;

&lt;p&gt;With the basic position established, we can start moving to the beat. The basic idea of dancing in closed position is that the two of us follow one of just a few predefined sequences of steps, grouped into pairs of steps and faster triplets of steps. I’m not going to try to describe it here, but will just say that the basic combinations are pretty standardized in this type of dance, and every newcomer learns some of them in the first hour of dancing. After some practice, these basic eight-count patterns become second nature.&lt;/p&gt;

&lt;p&gt;As my partner and I are doing these steps together, just staying in closed position, I can begin to move us around the floor. I can make us turn together, I can make us move forward (which is backward from my partner’s point of view) or backward (forward from my partner’s point of view), etc. To do this, all I do is move my body in the direction I want to move. Specifically, I use my legs to move my torso where I want us to go, and try to keep my arms in the same position and tension (relative to my body) that they already were. If my partner is maintaining the same position and tension in her arms as well, then the movement of my torso will travel directly to her torso, through our arms. All she has to do is let her legs follow her torso, while lifting and setting down her feet in the standard patterns, and she’ll go wherever I go. If it feels like I’m using any force to push or pull my partner around, then something is wrong. Either I’m not being clear enough in my movements, or my partner isn’t paying attention, or isn’t letting her torso just follow mine. If everything is working, this should feel so effortless and obvious that you can easily have a conversation while dancing around in closed position. The whole thing seems like magic at first, and it takes some practice to get it right, but once you experience it, it suddenly makes sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Few work activities match the physical closeness of dancing, but in many work situations, followers benefit from having a leader who is actually doing some of the work with them, and a leader benefits from being “on the floor” with their followers, working alongside them at least some of the time. The best leaders have enough understanding of their followers’ tasks to help them do their best work, and this understanding often comes, in part, from doing some of the work themselves.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;3-be-receptive-to-input-from-followers&quot;&gt;3. Be receptive to input from followers&lt;/h2&gt;

&lt;p&gt;The first few times I went to a Lindy Hop drop-in trial course, there were a couple of older ladies in attendance who were new to Lindy Hop, but had clearly done other types of partner dance for years. As we learned the basic steps, I discovered that each time I danced with one of these ladies, they followed my movements with what seemed to be effortless, automatic smoothness. It seemed like I could move however I wanted, and they’d just float along, their feet bouncing along underneath them. I was dancing for the first time in my life, and I felt like a king! One of the amazing things about this kind of dance is the way that with a minimal physical connection and some simple movement patterns agreed upon in advance, we can interact in new ways, and enjoy the physicality of bouncing to the beat of the music in a way that you really can’t do on your own. These ladies were so good at following, that without even saying a word, they were able to teach me important lessons about how to lead.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In any leadership context, it’s crucial that the leader pays attention to what their followers are doing and saying. It may be tempting, as a leader, to think that you’re in charge and should be able to call the shots, but a smart leader knows the value of relying on their smart followers to help see the right way to take each step.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;4-clear-a-path-for-your-followers&quot;&gt;4. Clear a path for your followers&lt;/h2&gt;

&lt;p&gt;From what I’ve described so far, it may seem like there’s an unfair imbalance here, like one of us is just telling the other where to go all the time. Shouldn’t we at least take turns? If we were only dancing in closed position, that might make sense. But at least in Lindy Hop’s case, a lot of what’s going on happens in a different configuration called “open position”, and in the transitioning between closed and open positions. In open position, the lead and the follower move apart from each other, and are often doing pretty different things. The follower is often doing more turns and spins, and the lead is usually just a little more “static” than follower. This changes the equation pretty substantially. The follower is being “told what to do,” but the follower gets something out of this. In partner dance, a lead and a follower are exchanging services.&lt;/p&gt;

&lt;p&gt;As a lead, I’m responsible for choosing what we are going to do from one moment to the next. This includes which direction we’re moving, whether we’re initiating a sequence that’s going to send us apart into open position or pull us together into closed position, whether my partner is going to do a turn or a spin, etc. I need to be on the lookout for obstacles, and make sure that my partner doesn’t crash into them. On a busy dance floor, there are other dancers, walls, and maybe other kinds of trouble to look out for. My partner is likely to be doing turns a lot more frequently than I am, so I need to keep an eye on our surroundings. If I’m not paying attention to the direction I’m sending my partner, I may send her on a collision course with another dancer, or worse, into a wall! If I send my partner out on a free spin, I’ve got to make sure that I have a hand in place to stop her spin at just the right time and bring us back together.&lt;/p&gt;

&lt;p&gt;I’m taking care of the overall structure and direction of our movement, so my partner is free to focus on the details of her part of the dance. She doesn’t have to worry about whether she’s going to crash into someone. She’s free to focus on her footwork, on when she wants to swivel her feet, throw in some kicks, etc. Even though she’s frequently doing these things while turning or spinning, I’m making sure she’s got nothing to worry about.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;In a corporate context, a leader often has a broader perspective than their followers do, because they may be aware of externalities before their followers are. A careful leader uses this knowledge to make sure that they can create a clear, safe path for their followers to move along, giving them the freedom to work to the best of their abilities within the given path.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;5-when-all-else-fails-just-keep-going&quot;&gt;5. When all else fails, just keep going&lt;/h2&gt;

&lt;p&gt;Sometimes while dancing, my partner and I will fall out of step. Maybe the music is a little too quiet and we lose the beat, or one of us gets distracted and loses count of their steps. Or, most likely, I’m not giving clear directions, and so my partner and I end up with a different idea of what the next movement is. It only takes a split-second for this to happen, and in my experience, this happens a &lt;em&gt;lot&lt;/em&gt;. It happens every time I’m dancing, for sure, maybe a couple of dozen times in an hour! The best remedy for this that I know is to simply reconnect with my partner and keep going! I look her in the eyes and take her by the hand, we both laugh a little, and then we start bouncing until the next down-beat, when it feels right to start moving again. By not making a big deal out of small mishaps, we’re able to just pick up where we left off and get back to having a good time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Flexible leaders understand that unexpected things happen all the time. They don’t make a big fuss about problems that that can be easily corrected, and they have enough insight to understand that they, themselves, may be the origin of many problems! They help their followers adapt to the new situation and get right back to work.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h1 id=&quot;the-take-away&quot;&gt;The take-away&lt;/h1&gt;

&lt;p&gt;In business, as in dance, leadership isn’t about being a boss, or ordering people around. It’s about doing specific things &lt;em&gt;together&lt;/em&gt; with the people you’re leading, so that everyone can move forward. A leader provides structure and a path, making some decisions on behalf of (and hopefully to the benefit of) their followers, freeing them to do their part of the work with as few obstacles as possible. This lets a group of people accomplish much more than they ever could individually.&lt;/p&gt;

&lt;p&gt;To summarize, here are five leadership skills that I’ve learned from dancing:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Establish rapport&lt;/strong&gt; with everyone who’s following you.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Work together with your followers&lt;/strong&gt;, so you understand what they’re going through and what they need.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pay attention to your followers&lt;/strong&gt;. Their words and actions will teach you about what you’re doing well, and what needs improvement.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Give your followers a clear, safe path&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;When things go wrong&lt;/strong&gt; (and they will, often), don’t get caught up in negativity or blaming. Just get your bearings and &lt;strong&gt;keep going&lt;/strong&gt;!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I don’t pretend that mine is a complete or perfect analysis, and I’m surely not the only person who’s thought of this, but I’ve never seen this connection mentioned before. Now that I’ve started to think this way, it’s really changed how I look at situations where I’m placed in a leadership role. Hopefully these insights will be helpful to others as well!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Trumped</title>
   <link href="http://localhost:4000/blog/2017/01/23/trumped/"/>
   <updated>2017-01-23T02:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2017/01/23/trumped</id>
   <content type="html">&lt;p&gt;It happened. As I sadly &lt;a href=&quot;http://nuthole.com/blog/2016/02/26/the-president/&quot;&gt;predicted&lt;/a&gt; last Feburary, Donald Trump won
the Republican primaries, went on to win the general election, and is now the
President. I didn’t watch the inauguration, but have seen highlights or maybe lowlights during the weekend. The day after the inauguration, there were wonderful, peaceful protests in cities around the world, and I applaud and appreciate these, but also doubt whether they’ll have any real effect.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The Swedish language has a remarkably appropriate word to describe my feeling these days: &lt;em&gt;trumpen&lt;/em&gt;. It means glum or bitter. Not necessarily defeated in the way that “trumped” means, but just… down. That’s basically where I’m at. We now have a President who is a clownish cartoon protagonist, someone whose worldview is so small, simplistic, and fearful that it boggles the mind. If you had told me 30, 20, 10, or even 5 years ago that this would be our President, I would have laughed at the idea. I feel like I’m trapped in an absurdist nightmare, or a Twilight Zone episode that won’t seem to end.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Escape</title>
   <link href="http://localhost:4000/blog/2016/11/17/escape/"/>
   <updated>2016-11-17T00:20:00+01:00</updated>
   <id>http://localhost:4000/blog/2016/11/17/escape</id>
   <content type="html">&lt;p&gt;Anyone paying attention to Apple this fall has surely noticed the new MacBook
Pro models where the upper row of function keys is replaced by the new Touch
Bar. Along with the disappearing function keys, the escape key also goes away.
&lt;!--more--&gt;
In many apps, the escape key will still exist as a virtual key on the Touch
Bar, but for many people (vim users, heavy terminal users in general), this
feels pretty weak. For much of the technology that springs from unixy origins,
the escape key is pretty important, and having the physical key replaced with
the butt end of a touch pad just seems wrong.&lt;/p&gt;

&lt;p&gt;But I’m here to tell you that there is a solution that can give you an actual
escape key, in nearly the position you expect to have it. It’s called the
International English  keyboard. If you make sure to order your new MacBook Pro
with the International English keyboard option, you will get an extra key which
will make all the difference.&lt;/p&gt;

&lt;p&gt;The International English keyboard is very similar to the standard US keyboard,
but actually adds one extra key, next to the left shift key. The back-tick key,
which is to the left of the 1 key, moves down bewteen left-shift and Z, and the
key to the left of 1 features a couple of incredibly useless symbols that no
one wants. You might be saying to yourself, “Useless, really?” To remove any
doubts about the uselessness of this key, just see for yourself:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://assets.nuthole.com/useless_key.png&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Come on, man. I could live to be a thousand and never find a use for either of
those. This topic may require further research and complaining, but let’s not
go down that rabbit-hole today. I’ll stop at saying that I have named this key
&lt;strong&gt;Captain Useless&lt;/strong&gt;. Now, let’s see what we can do about it.  The following
image shows the US keyboard above, and the International English keyboard
below, and shows how a few keys are moved and where Captain Useless (outlined
in red) is added:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://assets.nuthole.com/mac-keyboards.png&quot;&gt;
&lt;img src=&quot;http://assets.nuthole.com/mac-keyboards-small.png&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You’ll notice that Captain Useless on the International English keyboard,
positioned where back-tick used to be, is located &lt;em&gt;just below&lt;/em&gt; the escape key.
If you’re like me, you might even occasionally hit that key when you mean to
hit escape. So how about just changing that into an escape key? The best way I
know to do this is with a Mac app called &lt;a href=&quot;http://scripts.sil.org/ukelele&quot;&gt;Ukekele&lt;/a&gt;, which lets you
create your own keyboard mappings. It’s a little technical, and takes a couple
minutes to figure it out, so I’ve saved you some trouble and created a modified
mapping called &lt;a href=&quot;http://assets.nuthole.com/SweetEscape.bundle.zip&quot;&gt;Sweet Escape&lt;/a&gt;. This takes the form of an input
bundle called &lt;em&gt;SweetEscape&lt;/em&gt;, which contains a U.S. layout named &lt;em&gt;U.S. Sweet
Escape&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;If you don’t want to mess around with Ukelele, you can just download the
&lt;a href=&quot;http://assets.nuthole.com/SweetEscape.bundle.zip&quot;&gt;SweetEscape bundle&lt;/a&gt;, unzip it, put it in your &lt;strong&gt;/Library/Keyboard
Layouts/&lt;/strong&gt; folder. If that seems like too much work, you can instead download
Sweet Escape &lt;a href=&quot;http://assets.nuthole.com/SweetEscape.dmg&quot;&gt;as a dmg file&lt;/a&gt;, which will open to reveal the
keyboard input bundle and a link to the relevant folder. Just drag it over.  In
either case, you should then use &lt;em&gt;System Preferences&lt;/em&gt; (under &lt;em&gt;Keyboard&lt;/em&gt;, go to
the &lt;em&gt;Input Sources&lt;/em&gt; tab) to enable the new layout.&lt;/p&gt;

&lt;p&gt;I don’t even have a new MacBook
Pro with the Touch Bar yet, but I’m already using this layout on my previous
MacBook Pro (which has an international keyboard) so that I can give some
purpose to that useless key. Bye-bye, Captain Useless.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Jack Shirt</title>
   <link href="http://localhost:4000/blog/2016/05/03/jack-shirt/"/>
   <updated>2016-05-03T00:20:00+02:00</updated>
   <id>http://localhost:4000/blog/2016/05/03/jack-shirt</id>
   <content type="html">&lt;p&gt;In an unexpected turn at this point in my life, I have become a fashion
blogger.
&lt;!--more--&gt;
That’s right. I started a tumblr called &lt;a href=&quot;http://jackshirt.tumblr.com&quot;&gt;Jack Shirt&lt;/a&gt; and
have been showing and describing the shirts I’m wearing each weekday. Two weeks
solid so far!&lt;/p&gt;

&lt;p&gt;It’s early days still, but I’m sure that at some point this will end up with
corporate shirt sponsorships and possibly some sort of bribery scandal. &lt;a href=&quot;http://jackshirt.tumblr.com&quot;&gt;Check
it out&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://jackshirt.tumblr.com&quot;&gt;
&lt;img src=&quot;http://assets.nuthole.com/jackshirt.jpg&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The President</title>
   <link href="http://localhost:4000/blog/2016/02/26/the-president/"/>
   <updated>2016-02-26T00:20:00+01:00</updated>
   <id>http://localhost:4000/blog/2016/02/26/the-president</id>
   <content type="html">&lt;p&gt;He started off as an outsider, came into the race unexpectedly, and seemed to
mock the very institution whose presidency he was running for.  From the
outset, he painted all of his opponents as cronies, and himself as someone who
would bring some plain-talking common sense into the presidential race, and
hopefully to the presidency itself.&lt;/p&gt;

&lt;p&gt;I’m not talking about Donald Trump.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;1988&quot;&gt;1988&lt;/h2&gt;

&lt;p&gt;The candidacy I’m talking about is from way back in 1988. And it wasn’t the U.S
presidency at stake, but the student council presidency of the public high
school I attended in Austin, Minnesota. I had never participated in student
government, and was basically the kind of nerdy outsider (not widely hated, but
definitely not in with the in crowd either) who would never typically try to
win a popularity contest.&lt;/p&gt;

&lt;p&gt;But that spring, I heard that several popular kids were all going to run for
student council president. I figured that maybe I could attract the votes of
the other outsiders, and that the popular candidates running at the same time
would unwittingly complete the “divide” part to allow me to “conquer.” Plus, I
had just recently started playing in bands, had developed a taste for standing
on stage in front of a crowd, and figured it would be fun to stand up in front
of the entire student body and say some things. So I signed up.&lt;/p&gt;

&lt;h2 id=&quot;speechifying&quot;&gt;Speechifying&lt;/h2&gt;

&lt;p&gt;The exact words I spoke at the podium, in front of hundreds of kids, are lost
to history (I had written out a complete speech, but that piece of paper is
long gone). My best recollection is that, in brief, I said something like this:&lt;/p&gt;

&lt;blockquote&gt;
We all know that this is a popularity contest. I'm not the most popular
candidate up here today, and I'm not an athlete, so I really don't expect to
win. So by all means, do what you normally do on election day, and just vote
for whichever one of these guys you imagine you'd want to have as a friend.
&lt;/blockquote&gt;

&lt;p&gt;The crowd erupted in cheers. Much to my surprise, I realized that I &lt;em&gt;had&lt;/em&gt; them.
I had apparently hit a nerve. The election was a few days later, and I won.&lt;/p&gt;

&lt;p&gt;I hadn’t made any campaign promises. I hadn’t proposed any real solutions to
any real problems. Hell, I didn’t even &lt;em&gt;talk&lt;/em&gt; about any real problems. The only
“problem” I mentioned at all was that the election process was geared towards
letting popular kids win for no good reason (which is a problem, but a small
one). All I had done was appeal to people’s sense that things weren’t fair.
That the deck was stacked agains them, and that an elite were taking advantage
of everyone else.&lt;/p&gt;

&lt;p&gt;In short, it was pure populism. And as I watch the unexpected rise of Donald
Trump in the Republican primaries, and see the other Republican presidential
candidates fight each other for scraps while Trump’s juggernaut of a political
machine sucks more and more voters into the fold, I can’t help but be
terrified. I’ve seen this scenario play out, from the inside, and I’m afraid
that Trump is doing all the “right” things to win. At least when I won my
presidency, I wasn’t a vile, power-mad, tasteless, misogynist, racist monster.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>What rough beast slouches towards Inbox Zero</title>
   <link href="http://localhost:4000/blog/2015/12/22/what-rough-beast-slouches-towards-inbox-zero/"/>
   <updated>2015-12-22T00:20:00+01:00</updated>
   <id>http://localhost:4000/blog/2015/12/22/what-rough-beast-slouches-towards-inbox-zero</id>
   <content type="html">&lt;p&gt;I’ve had what you might call an email problem. Before &lt;em&gt;Getting Things Done&lt;/em&gt; was
published, and long before Merlin Mann started talking about &lt;em&gt;Inbox Zero&lt;/em&gt;, I
was already in a deep, dark pit of email messages, both read and unread (and
plenty that were actually read but were &lt;em&gt;marked&lt;/em&gt; as unread). I’m going to tell
you how I got there, and how and why I got out of it.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h2 id=&quot;habits-and-residue&quot;&gt;Habits and residue&lt;/h2&gt;

&lt;p&gt;I’ve been using internet-based email since about 1990. At a time when most
people still hadn’t even heard of the internet, I had subscriptions to a
variety of mailing lists covering all kinds of subjects, on and off, over long
ranges of time. Even though most of these were public mailing lists, those
lists weren’t well-indexed by Google or anyone else during much of the 90s, so
I ended up keeping them. And that habit stuck. When I first got access to gmail
a decade ago, I quickly realized that it gave me some great tools to
automatically label and filter mailing list content, so I moved all my
subscriptions there, and in fact used my gmail account almost exclusively for
mailing list content for many years.&lt;/p&gt;

&lt;p&gt;Some of these mailing lists, especially those covering Apple tech, were really
high-traffic lists, and over time, I found myself lacking the time to read them
all, and I ended up with a lot of unread messages festering in categorized
folders in gmail. Over time, it also seemed that some of the lists’ headers
changed just enough to no longer be picked up by the gmail filters I had set
up, so they ended up languishing in the inbox itself. I became accustomed to
the fact that my gmail inbox had this ludicrous, growing number attached to it,
and maybe that desensitized me for what was to come later: Life kicked me
around a bit.&lt;/p&gt;

&lt;h2 id=&quot;kicking-around&quot;&gt;Kicking around&lt;/h2&gt;

&lt;p&gt;I’m not going to go into detail of how life kicked me around. It was mostly
family issues, including a death and some other changes, the kind of things
that happen to everyone now and then during their lives. I found it basically
impossible to keep up with the flow of email. I had already gotten used to just
leaving most email messages in my main account’s Inbox at all times, and relied
on searching/filtering to find things. That’s pretty much the same as just
hitting “archive” on everything, except it’s still in the Inbox. When life
started kicking me around, I began not only leaving things in the inbox. I also
left them unread or, if they seemed important, I might read them and then
&lt;em&gt;mark&lt;/em&gt; them as unread, to leave little reminders for myself that I hadn’t yet
answered them.&lt;/p&gt;

&lt;p&gt;That alone might have been OK, but I was so bogged down that I wasn’t even
deleting pure spam and garbage, so it was also just lying there, unread, with
the emails that I had some intention of handling properly, some day. In short,
this was a big, unmanageable mess.&lt;/p&gt;

&lt;h2 id=&quot;the-dream-of-zero&quot;&gt;The dream of zero&lt;/h2&gt;

&lt;p&gt;Sometime during all this, maybe about five years ago, I began to hear about
things like Inbox Zero, but it seemed like an impossible dream. By that time I
surely had tens of thousands of unread messages spread across various accounts,
and taming that hoard seemed both impossible and not very useful. What sort of
gain would I get that would actually be worth the time it would take me to sort
it out?&lt;/p&gt;

&lt;p&gt;So time went on, and my unread counts grew. From time to time, a friend or
co-worker would notice the ridiculous badge number on my email program, be
surprised, and ask me about it. Eventually I developed a standard excuse: “You
don’t tick a check-box for every ad you seen in every newspaper you read, do
you? So why should I spend time dealing with every piece of spam or
uninteresting offer that hits my inbox?” Snarky, right? I felt so clever with
this excuse.&lt;/p&gt;

&lt;h2 id=&quot;an-epiphany&quot;&gt;An epiphany&lt;/h2&gt;

&lt;p&gt;A couple of weeks ago, I was pairing with a colleague visiting from another
office, who noticed my inbox badge, and said “Oh my god, it’s true!” I looked
up and saw the number, similar to the growing number that I saw several times a
day, and that I had become so desensitized to. If memory serves, it was roughly
143,000. Yes, that’s &lt;em&gt;one hundred forty-three thousand&lt;/em&gt; unread messages. And
the thing that got to me was that the “oh my god, it’s true” implied that the
number was so large, and was so far outside the norm, that &lt;em&gt;people were talking
about it&lt;/em&gt;. And not just any people, but my colleagues at thoughtbot, who I
consider to be the smartest, finest people I have ever worked with. At that
moment, I realized that I had to make a change.&lt;/p&gt;

&lt;h2 id=&quot;the-main-culprits&quot;&gt;The main culprits&lt;/h2&gt;

&lt;p&gt;I started thinking about this, and a few days later started looking through my
email to look for patterns. I first turned to my gmail account, which contained
all that mailing list content. That account alone had over 100,000 unreads, and
the vast majority were from mailing lists. Many from lists that I had stopped
subscribing to long ago. Those were the easiest to deal with, by using the
gmail web interface to find the list content, mark all the messages as read,
and archive them all away. My gmail account has always been remarkably free
from spam, so doing that left me with a (very large) handful of individual
emails marked as unread. I dealt with some of the newest ones right away, but
most of these were old enough that I conculded that if I hadn’t answered them
by now, I didn’t need to work about them any more. I selected them all, marked
them as read, and archived them. Gmail: sorted!&lt;/p&gt;

&lt;p&gt;More problematic were my other main email accounts, one on iCloud and one on a
personal domain. Each of these had gathered copious amounts of spam over the
years, so the unread messages they contained were a frothy mix of spam and
actual emails from friends and associates that I had marked as unread (or had
actually never read) with the intention of getting to them later. As with
gmail, I reasoned that old, unanswered emails could be safely filed away, but I
didn’t want to actually file away the spam as well, so a new approach was
needed.&lt;/p&gt;

&lt;h2 id=&quot;the-devil-in-the-details&quot;&gt;The devil in the details&lt;/h2&gt;

&lt;p&gt;I decided to use the Smart Mailbox feature in Mac OS X to help me out. I made a
smart mailbox to show me just the unread messages from one of these accounts,
then sorted the message list by sender. A huge number of the emails I wanted to
get rid of were recurring emails coming from a variety of sources, and having
them sorted by sender let me find huge chunks of these, select thema, and
delete them. I started with the A’s and worked my way down, deleting garbage
all the way. By the time I reached the Z’s, all I had left were emails from
actual humans. I marked them all as read and archived them away. Finally I went
back to the inbox (which still contained many thousands of &lt;em&gt;read&lt;/em&gt; messages) and
archived those away as well. Then I did the same for my other main non-gmail
account.&lt;/p&gt;

&lt;p&gt;Plowing through those thousands of messages did take time, but not as much as I
feared. I finished off the last of those inboxes, starting from about 7000
unreads, in about an hour just today. Altogether this project hasn’t taken
more than four or five hours, spread across a few evenings.&lt;/p&gt;

&lt;h2 id=&quot;the-promised-land&quot;&gt;The promised land&lt;/h2&gt;

&lt;p&gt;So now, suddenly, I find myself at inbox zero, and I think I’m here to stay.
I’m surprised, myself, at how good it feels to &lt;em&gt;not&lt;/em&gt; see those big numbers
looming over my head. I’m no longer using “unread” as a flag to tell me that I
need to do something, someday, about this message. Now, the unread state simple
means that I haven’t read it, and the continued presence of a message in an
inbox itself means that there is some unfinished business. The inbox becomes a
sort of dynamic to-do list. It’s great.&lt;/p&gt;

&lt;p&gt;And that’s the end of my tale. You probably don’t have such an extreme amount
of unread email as I did, but hopefully this will serve as a lesson. I honestly
never thought I would be at inbox zero, and yet there I am. Dreams really can
come true, I’m living proof, yada yada. Now go forth and purge.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>White Space</title>
   <link href="http://localhost:4000/blog/2015/11/25/white-space/"/>
   <updated>2015-11-25T08:15:00+01:00</updated>
   <id>http://localhost:4000/blog/2015/11/25/white-space</id>
   <content type="html">&lt;p&gt;Anyone who knew me as a teenager or young adult is likely to remember that
music was a big part of my life back then. I was constantly joining or forming
bands, writing songs, and playing in front of people as often as I could manage
to find gigs.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;This was never something that I did with any idea of earning
anything. The only times I can remember getting paid at all were two occasions
where one of my bands played a show at the &lt;a href=&quot;http://first-avenue.com/venue/entry&quot;&gt;7th Street Entry&lt;/a&gt;
in Minneapolis. Each time, the band received a whopping $20, which probably
didn’t even cover the cost of gas to the gig and back from Austin, MN. My
friends and I did this sort of thing simply because we loved it and had a good
time doing it. Performing on stage really is its own reward, especially if you
have the good fortune of finding an audience who likes what you’re doing.&lt;/p&gt;

&lt;p&gt;For a variety of reasons, beyond the scope of this post, in my mid-20s all of
that ground to a halt. I wasn’t playing in any bands, wasn’t writing songs,
seldom even pulled out a guitar to play on. This went on so long that
eventually I realized I couldn’t any longer describe myself as a guitarist
without wincing internally. I had become a guy who &lt;em&gt;used to play&lt;/em&gt; guitar, and
the realization of that was profound and painful.&lt;/p&gt;

&lt;p&gt;Gradually things have turned around though. Years ago I created my own
hypothetical band, &lt;a href=&quot;http://bandofnone.com&quot;&gt;Band of None&lt;/a&gt;, with some friends, and while
the creative output is really mine alone, and we don’t really do anything as a
band, the germ of an idea was sowed. Later I spent a few years playing first
guitar and then drums in a local punk band with some other middle-aged dudes,
which was fun but fizzled out. This summer/fall, I had a crazy creative burst
and quickly wrote at least a half-dozen songs, most of which I’m pretty happy
with, and some of which can be heard as rough works-in-progress on
&lt;a href=&quot;http://soundcloud.com/jack-nutting&quot;&gt;SoundCloud&lt;/a&gt;. And for the first time, in a long time, I’ve had
occasion to sing and play (on ukulele) songs for a crowd of 1000 software
developers at the &lt;a href=&quot;http://oredev.org&quot;&gt;Øredev&lt;/a&gt; conference. Each time, I’ve written a parody
of a popular song, come up with a uke/guitar-friendly arrangement, and
performed it with the help of &lt;a href=&quot;https://lostechies.com/jimmybogard/&quot;&gt;Jimmy Bogard&lt;/a&gt; and &lt;a href=&quot;http://codeofrob.com/blog.html&quot;&gt;Rob Ashton&lt;/a&gt;, and
it’s all been a lot of fun. Here’s the latest, recorded live at Øredev in
November 2015, for your amusement:&lt;/p&gt;

&lt;iframe src=&quot;https://player.vimeo.com/video/146391965&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot; mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;p&gt;&lt;a href=&quot;https://vimeo.com/146391965&quot;&gt;The better parts&lt;/a&gt; from &lt;a href=&quot;https://vimeo.com/user4280938&quot;&gt;&amp;Oslash;redev Conference&lt;/a&gt; on &lt;a href=&quot;https://vimeo.com&quot;&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The song is called “White Space”, and it’s a parody of Taylor Swift’s “Blank
Space.” It’s sung from the perspective of a jaded developer encouraging a new
programmer to come join the company he works for, offering to take that
programmer under his wing, only to later throw the noob under the bus. Let it be
known that this is a work of fiction!&lt;/p&gt;

&lt;p&gt;Doing this has been a huge amount of fun, and has seriously got me wanting to
do more of this. There’s something really fun about the constraint of writing
lyrics to fit within the confines of an existing song structure, and the
constraint of on playing with a somewhat limited instrument such as the
ukulele, that really just gets me going. And frankly, I love hamming it up on
stage in front of a thousand people.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Sligulous Prondle-Garg</title>
   <link href="http://localhost:4000/blog/2014/09/04/the-sligulous-prondle-garg/"/>
   <updated>2014-09-04T00:08:00+02:00</updated>
   <id>http://localhost:4000/blog/2014/09/04/the-sligulous-prondle-garg</id>
   <content type="html">&lt;p&gt;My first attempt at Vogon Poetry, inspired by a joke I made on the thoughtbot chat today.
&lt;!--more--&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;h2 id=&quot;the-sligulous-prondle-garg&quot;&gt;The Sligulous Prondle-Garg&lt;/h2&gt;
  &lt;p&gt;Like franticores on Gibulax we sloked our nurmy gelbs,&lt;br /&gt;
While o’er the crutted blige a foetid krax our booge did fell.&lt;br /&gt;
To see that crenulacious crange&lt;br /&gt;
I would conflay numolic spange!&lt;/p&gt;

  &lt;p&gt;And though flatsolicorpulatic flugs engaled the flelf,&lt;br /&gt;
Our liprosatchic gormistles withheld their grury krell.&lt;br /&gt;
A grox upon that strandulay&lt;br /&gt;
Would slaguform my grontifay.&lt;/p&gt;

  &lt;p&gt;And yet the snorgy wanges have reglored.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Apologies to Douglas Adams and, well, everyone.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>iOS Text Kit Basics</title>
   <link href="http://localhost:4000/blog/2014/07/03/ios-text-kit-basics.html/"/>
   <updated>2014-07-03T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2014/07/03/ios-text-kit-basics.html</id>
   <content type="html">&lt;p&gt;&lt;em&gt;(reposted from &lt;a href=&quot;http://robots.thoughtbot.com/ios-text-kit-basics&quot;&gt;Giant Robots Smashing Into Other Giant Robots&lt;/a&gt;, where it originally appeared May 30, 2014)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the iOS 7 SDK, Apple gave developers programmatic access to &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html&quot;&gt;Text
Kit&lt;/a&gt;, an advanced text layout system that lets you easily display and
edit rich text in your applications. Although these capabilities are new to iOS,
they’ve existed in other contexts (OS X since its first release, and OpenStep
before that) for nearly two decades, in what’s called the &lt;a href=&quot;https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Introduction/Introduction.html&quot;&gt;Cocoa text system&lt;/a&gt;. In fact, if you’ve used OS X at all, there
is a near 100% chance that you’ve run apps built with the Cocoa text system.
&lt;!--more--&gt;
However, for iOS developers, who often are not steeped in the details of OS X
development, the details of using the supplied text layout system are new, and
may seem mysterious at first. I intend to help you understand the basics of how
this works, and see how you can add rich text features to your own apps.&lt;/p&gt;

&lt;h2 id=&quot;the-simplest-thing&quot;&gt;The simplest thing&lt;/h2&gt;

&lt;p&gt;Let’s start off by making the simplest possible app that shows off some of what
Text Kit can do. In Xcode, create a new project using the &lt;em&gt;Single View
Application&lt;/em&gt; template, and name it &lt;em&gt;Simple Text View&lt;/em&gt;. Select &lt;em&gt;Main.storyboard&lt;/em&gt;,
use the &lt;em&gt;Object Library&lt;/em&gt; to find a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt; object, and drag it out to fill
the view of the available view controller; you’ll see blue guidelines appear and
the whole thing snap into place when it’s properly centered. Then use the
&lt;em&gt;Attributes Inspector&lt;/em&gt; to change the text view’s &lt;em&gt;Text&lt;/em&gt; attribute from &lt;em&gt;Plain&lt;/em&gt;
to &lt;em&gt;Attributed&lt;/em&gt;. What this does is tell the text view to allow rich text by
using an &lt;em&gt;attributed string&lt;/em&gt;. An attributed string, which is represented in iOS
by the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSAttributedString&lt;/code&gt; class, is simply a string that has some attached
metadata describing its attributes. This metadata may contain any number of
ranges of characters, each with its own set of attributes. For example, you
could specify that starting at the fifth character, the next six characters are
bold, and that starting at the tenth character, the next five characters are
italicized; In that case, the tenth character would be both bold and italicized.
In effect,&lt;/p&gt;

&lt;p&gt;0123&lt;strong&gt;45678&lt;/strong&gt;&lt;strong&gt;&lt;em&gt;9&lt;/em&gt;&lt;/strong&gt;&lt;em&gt;ABCD&lt;/em&gt;EF&lt;/p&gt;

&lt;p&gt;However, plenty of rich text content is created not by programmatically
specifying ranges and attributes, but  by users working in an editor that lets
them create rich text. That’s a use case that is fully supported by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt;
starting in iOS 7.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://assets.nuthole.com/ios-core-text/xcode-uitextview.png&quot; alt=&quot;UITextView in Interface Builder&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To prove this, use the Attributes Inspector to modify parts
of the “Lorem ipsum” text that the view contains by default. Use the controls in
the inspector to change some fonts, adjust paragraph alignment, set foreground
and backgroud colors, whatever you want. When you hit cmd-R to run the app in
the iOS Simulator or on a device, you’ll see that all the formatting changes you
made show up on the device. You can tap to edit the text at any point, and the
formatting that applies where the cursor is will carry on to new characters you
type, just as you’d expect from any word processor application.&lt;/p&gt;

&lt;h2 id=&quot;the-innards&quot;&gt;The innards&lt;/h2&gt;

&lt;p&gt;So far, so good. Even better, it turns out that a few other popular UIKit
classes, namely &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UILabel&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextField&lt;/code&gt;, also allow the use of attributed
strings in iOS 7. This means that if you just want to display some rich text in
a single rectangular box, you’re all set. Just put a properly configured UILabel
where you want to show your rich text, and you’re done! This simple task was
remarkably hard to accomplish before iOS 7, so right there we’ve made a huge
leap.&lt;/p&gt;

&lt;p&gt;But, what if you want to do more? There are certain kinds of layout tricks that
none of the UIKit classes can do on their own, out of the box. For example, if
you want to make text flow around a graphic, or make a single string fill up one
rectangle before spilling into another (as in the case of multiple columns),
you’ll have to do more. Fortunately, the innards of Text Kit, which are used by
UITextView and the rest, are at your disposal in the form of the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextStorage&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSLayoutManager&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextContainer&lt;/code&gt; classes. Let’s talk
about these one by one:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextStorage&lt;/code&gt; is actually a subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSMutableAttributedString&lt;/code&gt;, which
itself is a subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSAttributedString&lt;/code&gt;. It adds some functionality that
is useful for dealing with a user editing text, and nothing more.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextContainer&lt;/code&gt; is an abstract description of a two-dimensional box that
text could be rendered into. Basically, this class is little more than a
glorified size. It contains a few parameters for describing how text should
behave when rendered within a box of its size, and that’s about it.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSLayoutManager&lt;/code&gt; is the real brains of the operation. It knows how to take an
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextStorage&lt;/code&gt; instance, and layout all the characters it contains into the
virtual boxes described by one or more &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextContainers&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A class like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt; uses these components to do all its text layout. In
fact, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt; has three properties called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textStorage&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textContainer&lt;/code&gt;,
and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutManager&lt;/code&gt; for just this purpose. When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt; wants to draw its
content, it tells its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutManager&lt;/code&gt; to figure out which glyphs (the graphical
representations of the characters it contains) from its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textStorage&lt;/code&gt; can fit
within its &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textContainer&lt;/code&gt;, then it tells the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutManager&lt;/code&gt; to actually draw
those glyphs at a point inside the text view’s frame. So you see that the design
of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt; itself is inherently limited to a single rectangle. In order to
get a feel for how these innards work, I’ll now show you a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIView&lt;/code&gt; subclass
that will display rich text in multiple columns, a trick that &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt;
really can’t pull off in its current form.&lt;/p&gt;

&lt;h2 id=&quot;create-tbtmulticolumntextview&quot;&gt;Create TBTMultiColumnTextView&lt;/h2&gt;

&lt;p&gt;In your open Xcode project, create a new subclass of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIView&lt;/code&gt; called
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TBTMultiColumnView&lt;/code&gt;. Like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt;, this class will have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;textStorage&lt;/code&gt; and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutManager&lt;/code&gt; properties. Unlike &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt;, it will keep track of multiple
independent text containers and multiple origins for drawing rectangles. The
first thing you should do is create a class extension at the top of the file,
containing the following properties:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;@interface TBTMultiColumnTextView ()

@property (copy, nonatomic) NSTextStorage *textStorage;
@property (strong, nonatomic) NSArray *textOrigins;
@property (strong, nonatomic) NSLayoutManager *layoutManager;

@end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Besides the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextStorage&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSLayoutManager&lt;/code&gt; instances, we’re also going to
maintain an array of origins, each corresponding to an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextContainer&lt;/code&gt;. We
don’t have to hang onto the text containers themselves, because the layout
manager keeps its own list, which we can access.&lt;/p&gt;

&lt;p&gt;Now, let’s get started with the methods for this class. First, override
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;viewDidLoad&lt;/code&gt; as shown here:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (void)awakeFromNib {
    [super awakeFromNib];
    self.layoutManager = [[NSLayoutManager alloc] init];
    
    NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@&quot;constitution&quot;
                                             withExtension:@&quot;rtf&quot;];
    self.textStorage = [[NSTextStorage alloc] initWithFileURL:fileURL
                                                      options:
                        @{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType}
                                           documentAttributes:nil
                                                        error:nil];
    [self createColumns];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This method is pretty straightforward. It starts off by creating a layout
manager, which we’ll use every time we need to draw this object’s content. Then
we read the contents of an RTF file, which we’ve included in our project, into
an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextStorage&lt;/code&gt; instance. Our project contains an RTF file that contains the
U.S. constitution, but you can use any RTF document you have at hand. Since this
object will need to be redrawn any time the text storage changes, we implement
the setter, like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (void)setTextStorage:(NSTextStorage *)textStorage {
    _textStorage = [[NSTextStorage alloc] initWithAttributedString:textStorage];
    [self.textStorage addLayoutManager:self.layoutManager];
    [self setNeedsDisplay];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that we have a special way of making a new copy of the object that’s passed
in. As it turns out, just sending &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copy&lt;/code&gt; to an instance of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSTextStorage&lt;/code&gt;
actually returns an instance of an immutable parent class (just like you’d
expect with, say, an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSMutableString&lt;/code&gt;). That’s why we take the step of
explicitly creating a new instance based on the received parameter.&lt;/p&gt;

&lt;p&gt;At the end of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;awakeFromNib&lt;/code&gt;, we called the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;createColumns&lt;/code&gt; method, which is
where most of this class’s work really happens. It looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (void)createColumns {
    // Remove any existing text containers, since we will recreate them.
    for (NSUInteger i = [self.layoutManager.textContainers count]; i &amp;gt; 0;) {
        [self.layoutManager removeTextContainerAtIndex:--i];
    }
    
    // Capture some frequently-used geometry values in local variables.
    CGRect bounds = self.bounds;
    CGFloat x = bounds.origin.x;
    CGFloat y = bounds.origin.y;
    
    // These are effectively constants. If you want to make this class more
    // extensible, turning these into public properties would be a nice start!
    NSUInteger columnCount = 2;
    CGFloat interColumnMargin = 10;
    
    // Calculate sizes for building a series of text containers.
    CGFloat totalMargin = interColumnMargin * (columnCount - 1);
    CGFloat columnWidth = (bounds.size.width - totalMargin) / columnCount;
    CGSize columnSize = CGSizeMake(columnWidth, bounds.size.height);
    
    NSMutableArray *containers = [NSMutableArray arrayWithCapacity:columnCount];
    NSMutableArray *origins = [NSMutableArray arrayWithCapacity:columnCount];
    
    for (NSUInteger i = 0; i &amp;lt; columnCount; i++) {
        // Create a new container of the appropriate size, and add it to our array.
        NSTextContainer *container = [[NSTextContainer alloc] initWithSize:columnSize];
        [containers addObject:container];
        
        // Create a new origin point for the container we just added.
        NSValue *originValue = [NSValue valueWithCGPoint:CGPointMake(x, y)];
        [origins addObject:originValue];
        
        [self.layoutManager addTextContainer:container];
        x += columnWidth + interColumnMargin;
    }
    self.textOrigins = origins;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This method is honestly a little longer than we’d like, but for this example it
does the job. This method may need to be called multiple times, whenever the
view’s coordinates are adjusted (such as when the device rotates), so we need to
make sure it can run multiple times without ending up in a weird state. So, it
starts off by removing any old text containers that may be attached to the
layout manager. It does this because the whole point of this method is to create
a fresh set of text containers, and having old ones lying around will only give
us grief. This method then calculates appropriate text container sizes depending
on the view’s size and some hard-coded values for the number of columns and the
amount of margin that should appear between columns. Finally it creates and
configures a number of containers and and equal number of points (wrapped in
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSValue&lt;/code&gt; objects).&lt;/p&gt;

&lt;p&gt;Next we’re going to make use of all those containers and points we just created.
The drawRect: method tells the layout manager to finally draw its content into
each text container. It looks like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (void)drawRect:(CGRect)rect {
    for (NSUInteger i = 0; i &amp;lt; [self.layoutManager.textContainers count]; i++) {
        NSTextContainer *container = self.layoutManager.textContainers[i];
        CGPoint origin = [self.textOrigins[i] CGPointValue];
        
        NSRange glyphRange = [self.layoutManager glyphRangeForTextContainer:container];
        
        [self.layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:origin];
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;All we do here is loop over all available text containers and origin points,
each time asking the layout manager which glyphs it can fit into the container,
then telling the layout manager to draw those glyphs at the origin point.&lt;/p&gt;

&lt;p&gt;That’s just about all we need. In order to make things work after device
rotation, however, we need to do one more thing. By overriding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;layoutSubviews&lt;/code&gt;,
which is called when the view rotates, we can make sure that the columns are
regenerated for the new size:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-objective-c&quot;&gt;- (void)layoutSubviews {
    [super layoutSubviews];
    [self createColumns];
    [self setNeedsDisplay];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That’s all we need to make this class draw rich text in two columns, and
automatically adjust for changes in view geometry. To see this in action, go
back to the storyboad and follow these steps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Remove the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UITextView&lt;/code&gt; you added at the start.&lt;/li&gt;
  &lt;li&gt;Find a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UIView&lt;/code&gt; in the object library, drag it into the view and make it fill
the view completely.&lt;/li&gt;
  &lt;li&gt;Use the &lt;em&gt;Identity Inspector&lt;/em&gt; to change this object’s class to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TBDMultiColumnView&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;To make sure the view’s geometry changes along with its superview (e.g. when
the device rotates), add constraints from the view to its superview for top,
bottom, leading, and trailing space. This is most easily accomplished by
clicking the &lt;em&gt;Pin&lt;/em&gt; button at the bottom of Interface Builder’s editing area, and
selecting each of the four red, dashed-line symbols surrounding the little
square (which represents the selected view). That sounds complicated, but once
you see it, you’ll get it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once you’ve taken those final steps, you can build and run in the simulator or
on a device, and see your multicolumn display in all its glory!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://assets.nuthole.com/ios-core-text/simulator-multi-column-text-view.png&quot; alt=&quot;Multi Column Text View running on iOS
Simulator&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;closing-remarks&quot;&gt;Closing remarks&lt;/h2&gt;

&lt;p&gt;This class demonstrates a technique for creating a view that lets rich text flow
across multiple columns in just a few lines of code. But we’re really just
scratching the surface here. Besides flowing across multiple rectangles, Text
Kit will let you do plenty of other things, including drawing text inside the
path of an arbitrary shape, making text flow around other paths, and more. You
can learn more about thse techniques by looking at Apple’s &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/CustomTextProcessing/CustomTextProcessing.html&quot;&gt;iOS Text Kit
Overview&lt;/a&gt;, as well as their Mac documentation for the &lt;a href=&quot;https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/Introduction/Introduction.html&quot;&gt;Cocoa text
system&lt;/a&gt;, which is where much of Text Kit’s
functionality originated.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>iOS Code Review: Loose Guidelines</title>
   <link href="http://localhost:4000/blog/2014/07/03/ios-code-review-guidlines/"/>
   <updated>2014-07-03T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2014/07/03/ios-code-review-guidlines</id>
   <content type="html">&lt;p&gt;&lt;em&gt;(reposted from &lt;a href=&quot;http://robots.thoughtbot.com/ios-code-review-guidlines&quot;&gt;Giant Robots Smashing Into Other Giant Robots&lt;/a&gt;, where it originally appeared February 19, 2014)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From time to time I’ve been asked to do an independent code review, to determine the overall health of a client’s code base. Unlike a code walkthrough, where someone familiar with the code shows the main components, this is a code review where an outside expert examines the project, takes copious amounts of notes, and reports back either in written form or in a meeting with the team, depending on what the client wants. 
&lt;!--more--&gt;
This is separate from doing testing or any other sort of QA on the applications themselves. The idea is that you might have an application that works great and passes all kinds of acceptance tests, but is built in a such a way that future maintenance and enhancements will be difficult and/or costly. If we can identify problem areas in an application’s source code, we can help set things on a better course. The sooner we can discover potential problems, the better. The experiences and guidelines described here are centered around iOS programming practices, but many of them apply to other sorts of projects as well.&lt;/p&gt;

&lt;p&gt;The last time I did this, the client’s budget was limited, so there wasn’t time to do in-depth examination of every source code file in each of the client’s application. I had a lot of territory to cover, and not a whole lot of time. So, I decided to do it in two phases: First, I took an initial look at each project to establish a quick (if superficial) opinion of each project’s health. After that, I dove deeper into each project, paying extra attention given to the projects that set off the most warning flags during the initial phase. This procedure worked pretty well, since I was able to report back with an approximate health level for each application, plus a lot of specifics for those that seemed to be in worse shape than the others.&lt;/p&gt;

&lt;p&gt;The set of guidelines I’m outlining here are the kind of thing that anyone can do on their own codebase as well. If you don’t understand what some of these points are all about, or why they’re worth thinking about when it comes to your own apps, this could be a good time to improve your own skills a bit by thinking about some of these topics and looking for relevant discussion and debate (for example, on the internet).&lt;/p&gt;

&lt;h2 id=&quot;phase-one-a-quick-look&quot;&gt;Phase One: A Quick Look&lt;/h2&gt;

&lt;p&gt;To get a feel for the overall health of each app, do the following things:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Make sure all external resources required by the project (3rd-party code, etc) are fully contained within the app, or referenced through submodules, or (best of all) included via &lt;a href=&quot;http://cocoapods.org/&quot;&gt;CocoaPods&lt;/a&gt;. If they’re not managed in some way (e.g. CocoaPods) see if there is any documentation describing how to obtain and update these resources.&lt;/li&gt;
  &lt;li&gt;Open the project in Xcode and build it. Make sure the project builds cleanly (with no warnings, and hopefully errors).&lt;/li&gt;
  &lt;li&gt;Perform a &lt;a href=&quot;https://developer.apple.com/library/ios/recipes/xcode_help-source_editor/Analyze/Analyze.html&quot;&gt;static analysis&lt;/a&gt; in Xcode to see if any other problems show up.&lt;/li&gt;
  &lt;li&gt;Run &lt;a href=&quot;http://oclint.org/&quot;&gt;oclint&lt;/a&gt; and see if this uncovers any other problems that Xcode’s static analysis didn’t reveal.&lt;/li&gt;
  &lt;li&gt;Examine the project structure. Do the various source code files seem to be placed in a reasonable hierarchy? The larger the project is, the more important it becomes to impose some kind of structure, in order to help outsiders find their way around.&lt;/li&gt;
  &lt;li&gt;Does the app have unit tests or integration tests? If so, run them and make sure they complete without any failures. Bonus points if tools are in use for measuring test coverage.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Doing all that should take several minutes for each app, regardless of the app’s size, unless you encounter major problems somewhere along the line. Finding things that are not to your liking on one or two of those points doesn’t necessarily mean that you’ve got a huge problem on your hands, but by considering your findings here you can start to get a sense of any project’s overall “smell”.&lt;/p&gt;

&lt;h2 id=&quot;phase-two-diving-deep&quot;&gt;Phase Two: Diving Deep&lt;/h2&gt;

&lt;p&gt;After that, do a closer examination of each app, starting with the ones that set off the most warning flags in your head during the initial examination. You should look at every source code file (if you have the time to do so), reading through the code with all of these things in mind. You’ll probably want to take notes as you go along, when you find things that need improving.&lt;/p&gt;

&lt;h3 id=&quot;objective-c&quot;&gt;Objective-C&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Are the latest Objective-C features from the past few years being used? This includes implicit accessor and instance variable synthesis, new syntactic shortcuts for creation of &lt;code&gt;NSNumber&lt;/code&gt;/&lt;code&gt;NSArray&lt;/code&gt;/&lt;code&gt;NSDictionary&lt;/code&gt;, new syntax for array and dictionary indexing, etc.&lt;/li&gt;
  &lt;li&gt;Are instance variables and properties used in a consistent way? Does the code use accessors where appropriate, keeping direct instance variable access limited to init and dealloc methods?&lt;/li&gt;
  &lt;li&gt;Are properties declared with the correct storage semantics? (e.g. copy instead of strong for value types)&lt;/li&gt;
  &lt;li&gt;Are good names used for classes, methods, and variables?&lt;/li&gt;
  &lt;li&gt;Are there any classes that seem overly long? Maybe some functionality should be split into separate classes.&lt;/li&gt;
  &lt;li&gt;Within each class, are there many methods that seem too long, or are things split up nicely? Objective-C code is, by necessity, longer than the corresponding code would be in a language like Ruby, but generally shorter is better. Anything longer than ten or fifteen lines might be worth refactoring, and anything longer than 30 or 40 lines is almost definitely in need of refactoring.&lt;/li&gt;
  &lt;li&gt;Is the app compiled with &lt;a href=&quot;https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/MemoryMgmt.html&quot;&gt;ARC, MRR&lt;/a&gt;, or a mix? If not all ARC, why not?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cocoa&quot;&gt;Cocoa&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Does the app make good use of common Cocoa patterns, such as &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/general/conceptual/devpedia-cocoacore/MVC.html&quot;&gt;MVC&lt;/a&gt;, &lt;a href=&quot;https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSNotificationCenter_Class/Reference/Reference.html&quot;&gt;notifications&lt;/a&gt;, &lt;a href=&quot;https://developer.apple.com/library/mac/documentation/cocoa/conceptual/KeyValueObserving/KeyValueObserving.html&quot;&gt;KVO&lt;/a&gt;, lazy-loading, etc? Are there any efforts underway to adopt patterns that aren’t backed by Apple, but are gaining steam in the iOS world, such as &lt;a href=&quot;https://github.com/ReactiveCocoa/ReactiveCocoa&quot;&gt;Reactive Cocoa&lt;/a&gt; and &lt;a href=&quot;http://www.teehanlax.com/blog/model-view-viewmodel-for-ios/&quot;&gt;MVVM&lt;/a&gt;?&lt;/li&gt;
  &lt;li&gt;Are there view-controllers that are overloaded with too much responsibility?&lt;/li&gt;
  &lt;li&gt;If discrete sections of the app need to communicate with each other, how do they do so? There are multiple ways of accomplishing this (KVO, notifications, a big pile of global variables, etc), each with their own pros and cons.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;model-layer&quot;&gt;Model Layer&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;If the app is using Core Data, does the data model seem sufficiently normalized and sensible? Is the Core Data stack set up for the possibility of doing some work on a background thread? See &lt;a href=&quot;https://twitter.com/theocalmes&quot;&gt;Theo&lt;/a&gt;’s &lt;a href=&quot;http://robots.thoughtbot.com/core-data&quot;&gt;guide to core data concurrency&lt;/a&gt; for more on this.&lt;/li&gt;
  &lt;li&gt;If not using Core Data, does the app store data using some other techniques, and if so, does it seem reasonable?&lt;/li&gt;
  &lt;li&gt;At the other end of the spectrum, does the app skip model classes to a large extent, and just deal with things as dictionaries?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;gui&quot;&gt;GUI&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Is the GUI created primarily using xibs, storyboards, or code?&lt;/li&gt;
  &lt;li&gt;Is GUI layout done with constraints, the old springs’n’struts, or hard-coded frame layout?&lt;/li&gt;
  &lt;li&gt;Does the running app have a reasonable look and feel?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;network-layer&quot;&gt;Network Layer&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Is all networking done using asynchronous techniques, allowing the app to remain responsive?&lt;/li&gt;
  &lt;li&gt;If a 3rd-party network framework is being used, is it a modern, supported framework, or something that’s become a dead end?&lt;/li&gt;
  &lt;li&gt;If no 3rd-party network framework is in use, are Apple’s underlying classes being used in a good way? (There are plenty of ways to get this wrong).&lt;/li&gt;
  &lt;li&gt;Does the app function in a fluid manner, without undesireable timeouts or obvious network lags affecting the user?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;other&quot;&gt;Other&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;Is the app localized for multiple languages? If so, is this done using standard iOS localisation techniques?&lt;/li&gt;
  &lt;li&gt;If there are tricky/difficult things happening in the code, are these documented?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a pretty hefty set of things to consider. Depending on the code base, you won’t necessarily be able to find a clear yes/no answer for all of these questions, and for certain types of apps, some of these points will be meaningless. Note that I’m not saying exactly what I think are the “right” answers for all of the questions listed here, although I certainly have my share of strong opinions about most of these (but those are topics for other blog posts). Even if you wouldn’t agree with my answers, these are probably all points that are worth thinking about and discussing with co-workers and other collaborators to figure out just what seems right for &lt;em&gt;your&lt;/em&gt; projects.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Another Workshop</title>
   <link href="http://localhost:4000/blog/2013/08/28/another-workshop/"/>
   <updated>2013-08-28T09:46:00+02:00</updated>
   <id>http://localhost:4000/blog/2013/08/28/another-workshop</id>
   <content type="html">&lt;p&gt;The time has come to once again for the Beginning iOS Development Workshop. This time it’s actually in central Stockholm instead of out in Norrtälje, so those of you who don’t want to ride that bus are in luck!&lt;/p&gt;

&lt;p&gt;It takes place September 18-20. Details are &lt;a href=&quot;http://learncocoa.org/beginning_ios_development_workshop.html&quot;&gt;here&lt;/a&gt;. I hope to see you there!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Hej då Toca Boca, Hello thoughtbot</title>
   <link href="http://localhost:4000/blog/2013/08/19/hej-da-toca-boca-hello-thoughtbot/"/>
   <updated>2013-08-19T23:14:00+02:00</updated>
   <id>http://localhost:4000/blog/2013/08/19/hej-da-toca-boca-hello-thoughtbot</id>
   <content type="html">&lt;p&gt;After two and a half years, the time has come for me to move on. I’m proud to have been a part of Toca Boca’s infancy, and working on some of the &lt;a href=&quot;http://tocaboca.com/game/toca-hair-salon/&quot;&gt;greatest&lt;/a&gt; &lt;a href=&quot;http://tocaboca.com/game/toca-store/&quot;&gt;kids’&lt;/a&gt; &lt;a href=&quot;http://tocaboca.com/game/toca-band/&quot;&gt;apps&lt;/a&gt; the world has ever seen has been fantastic fun, but a few months ago I decided to move on, and today was my final work day at Toca Boca.&lt;/p&gt;

&lt;p&gt;I’ve had plenty of job offers during my time at Toca Boca, so what’s the new shiny that finally caught my eye and pulled me away? None other than &lt;a href=&quot;http://thoughtbot.com&quot;&gt;thoughtbot&lt;/a&gt;, whose work I’ve admired for years. They’ve built a solid reputation in the Ruby world, and are expanding their repertoire to include native iOS development, which is where I fit in. My long history with iOS technologies, along with the &lt;a href=&quot;http://www.amazon.com/Jack-Nutting/e/B003HV9AEQ&quot;&gt;books&lt;/a&gt; and &lt;a href=&quot;http://learncocoa.org/beginning_ios_development_workshop.html&quot;&gt;training&lt;/a&gt; I’ve been doing for several years, seem to be a good fit for where thoughtbot is going, and the new office in Stockholm is right where I want to be. The team has welcomed me with open arms, and I’m looking forward to working with this extremely bright, hardworking crew!&lt;/p&gt;

&lt;p&gt;So, anyone who needs some iOS app development services in Stockholm, or anywhere else for that matter: &lt;a href=&quot;http://www.thoughtbot.com/contact&quot;&gt;Get in touch&lt;/a&gt;!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Another iOS Development Workshop</title>
   <link href="http://localhost:4000/blog/2013/02/14/another-ios-development-workshop/"/>
   <updated>2013-02-14T13:22:00+01:00</updated>
   <id>http://localhost:4000/blog/2013/02/14/another-ios-development-workshop</id>
   <content type="html">&lt;p&gt;I should point out that I’m running another &lt;a href=&quot;http://learncocoa.org/beginning_ios_development_workshop.html&quot;&gt;iOS Development Workshop&lt;/a&gt; next week. The third one since I started doing this as “a real thing”! Pretty excited about this, it’s a lot of fun for me and educational (I hope!) for my students. There’s still time to sign up, just barely.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Could Core Data be a little more concise?</title>
   <link href="http://localhost:4000/blog/2012/11/07/could-core-data-be-a-little-more-concise/"/>
   <updated>2012-11-07T08:42:00+01:00</updated>
   <id>http://localhost:4000/blog/2012/11/07/could-core-data-be-a-little-more-concise</id>
   <content type="html">&lt;p&gt;At the latest &lt;a href=&quot;http://learncocoa.org/beginning_ios_development_workshop.html&quot;&gt;Beginning iOS Dev Workshop&lt;/a&gt; this September, I was showing my students some Core Data by walking through the template application that Xcode gives you if you create a new master-detail Core-Data-backed iOS application. If you haven’t done so yourself, you should check it out, because it presents a pretty nice way of constructing a pair of view controllers that give the user access to a list of Core Data objects.
&lt;!--more--&gt;
&lt;em&gt;(EDIT 2013-02-20: fixed small error in fetchRequestForEntityNamed:sortedByKeys:fetchBatchSize: method)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The downside of that project template is that if you don’t already know how it works, it’s not that straightforward to figure out what’s going on, especially in the “master” controller where a lot of things happen through indirection via delegate methods, etc. Going through all this, I was struck by one method in particular: the fetchedResultsController method in the MasterViewController class:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objc&quot; data-lang=&quot;objc&quot;&gt;&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_fetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_fetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Edit the entity name as appropriate.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSEntityDescription&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSEntityDescription&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;entityForName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;Event&quot;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inManagedObjectContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;managedObjectContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setEntity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Set the batch size to a suitable number.&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setFetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Edit the sort key as appropriate.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSSortDescriptor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSSortDescriptor&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initWithKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;timeStamp&quot;&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ascending&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;NO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;@[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setSortDescriptors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Edit the section name key path and cache name if appropriate.&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// nil for section name key path means &quot;no sections&quot;.&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;aFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initWithFetchRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;managedObjectContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;managedObjectContext&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;Master&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;aFetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;aFetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;NSError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;performFetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;c1&quot;&gt;// Replace this implementation with code to handle the error appropriately.&lt;/span&gt;
         &lt;span class=&quot;c1&quot;&gt;// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. &lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NSLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;Unresolved error %@, %@&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;userInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_fetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Objective-C is known for its verbosity, but that’s pretty extreme, considering what this method is designed to do: return a controller object that is set up to do the equivalent of a very simple SQl query:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objc&quot; data-lang=&quot;objc&quot;&gt;&lt;span class=&quot;n&quot;&gt;SELECT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Event&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ORDER&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BY&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;timeStamep&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DESC&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;LIMIT&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It’s not exactly the same, of course. Core Data also allows us to cluster the results together into sections, something that SQL doesn’t support directly (imagine something like GROUP BY, but instead of lumping results together, it that would still return the same basic list of results, but grouped into multiple arrays based on the content of one column).&lt;/p&gt;

&lt;p&gt;The start of the method contains boilerplate, basically to check whether the method has already been called or not. The end of the method actually kicks off the query which runs in the background and can’t really be cleaned up too much. Everything in between is what seems to be just too big.&lt;/p&gt;

&lt;p&gt;Essentially, lines 7-10 of this method are the “SELECT”, line 13 is the “LIMIT”, lines 15-19 are the “ORDER BY”, and lines 21-25 take care of the sectioning. So we’re looking at roughly 20 lines of Objective-C code (some of them very long lines as well) corresponding to 3 short lines of SQL (which would perhaps be 4 lines if SQL supported the sectioning that Core Data does). Some of my students found this pretty troubling, and I can totally see why. There’s a huge trend in programming toward higher-level APIs that let you do more with fewer lines of code. Objective-C will never be as succinct as SQL, but surely we can do better than this.&lt;/p&gt;

&lt;p&gt;So I started looking at the various pieces used to build up and execute this query, to see what prerequites they have and how they are tied together. The first thing the method creates is an NSFetchRequest. This is a “bare object” that has no context initially, but will eventually contain all the parameters needed for the query we want to run. We start off by grabbing an entity (by name) from the NSManagedObjectContext to assign to the fetch request, then we set its batch size. After that, we create a new NSSortDescriptor, which contains the name of an attribute, and a BOOL indicating the sort order. This object is put into an array, which is then passed to the fetch request (which can take an array so that you can provide multiple sorting attributes). Finally we create an NSFetchResultsController, passing in the fetch request, the managed object context, a sectioning key-path (unused here) and the name of a cache to hold the results.&lt;/p&gt;

&lt;p&gt;Throughout all of that, I found a number of spots where a string is used to grab or create another object simply because it was needed as a parameter to another method. These intermediate objects (an NSEntityDescription and an NSSortDescriptor) are not useful in this method otherwise, they’re just being passed elsewhere. I also found that a couple of the things being grabbed or created need the managed object context. With these things in mind, I created an alternate API, in the form of a new method in NSMangedObjectContext, that would build all these things for us, using simple strings where appropriate instead of intermediaries, and give us back an NSFetchedObjectController. With this API in place, the fetchedResultsController method becomes this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objc&quot; data-lang=&quot;objc&quot;&gt;&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_fetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_fetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;managedObjectContext&lt;/span&gt;
                                     &lt;span class=&quot;nl&quot;&gt;fetchedResultsControllerForEntityNamed:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;Event&quot;&lt;/span&gt;
                                     &lt;span class=&quot;nl&quot;&gt;sortedByKeys:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;-timeStamp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
                                     &lt;span class=&quot;nl&quot;&gt;fetchBatchSize:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;
                                     &lt;span class=&quot;nl&quot;&gt;sectionNameKeyPath:&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;
                                     &lt;span class=&quot;nl&quot;&gt;cacheName:&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;Master&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;delegate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;NSError&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;performFetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Replace this implementation with code to handle the error appropriately.&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NSLog&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;@&quot;Unresolved error %@, %@&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;userInfo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;abort&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_fetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;As you can see, the beginning and ending are identical, but all that stuff in the middle shrunk from 19 lines down to 7. To top it off, it’s now a lot easier to read, since you can see all the pieces together and digest it at once, just like you can with SQL.&lt;/p&gt;

&lt;p&gt;I skipped the NSEntityDescription and just use an entity name instead. I simplified the sorting specification by eliminating the intermediate NSSortDescriptors; Instead, you just pass an array of strings. If the first character is a “-“, it’s the equivalent of using “ascending:NO” when creating an NSSortDescriptor, so sorting for that attribute will be reversed. And even though this example app doesn’t use sections, I included the parameter in this new API (it’s passed straight through to the new fetched results controller) for maximum flexibility.&lt;/p&gt;

&lt;p&gt;I’ve implemented this in a category on NSManagedObjectContext, shown here:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objc&quot; data-lang=&quot;objc&quot;&gt;&lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  NSManagedObjectContext+Simpler.h&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  SimplerCoreData&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  Created by Jack Nutting on 10/31/12.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  Copyright (c) 2012 Rebisoft. All rights reserved.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#import &amp;lt;CoreData/CoreData.h&amp;gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@interface&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSManagedObjectContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Simpler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fetchRequestForEntityNamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;entityName&lt;/span&gt;
                                  &lt;span class=&quot;nf&quot;&gt;sortedByKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;keys&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSUInteger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fetchedResultsControllerForEntityNamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entityName&lt;/span&gt;
                                                          &lt;span class=&quot;n&quot;&gt;sortedByKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;
                                                        &lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSUInteger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;
                                                    &lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt;
                                                             &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-objc&quot; data-lang=&quot;objc&quot;&gt;&lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  NSManagedObjectContext+Simpler.m&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  SimplerCoreData&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  Created by Jack Nutting on 10/31/12.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//  Copyright (c) 2012 Rebisoft. All rights reserved.&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#import &quot;NSManagedObjectContext+Simpler.h&quot;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NSManagedObjectContext&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Simpler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fetchRequestForEntityNamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;entityName&lt;/span&gt;
                                  &lt;span class=&quot;nf&quot;&gt;sortedByKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;keys&lt;/span&gt;
                                &lt;span class=&quot;nf&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSUInteger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;fetchBatchSize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSEntityDescription&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSEntityDescription&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;entityForName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entityName&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;inManagedObjectContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setEntity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setFetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;NSMutableArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptors&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSMutableArray&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;arrayWithCapacity&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]];&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BOOL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ascending&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;YES&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;characterAtIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;'-'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;ascending&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;NO&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;substringFromIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;NSSortDescriptor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptor&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSSortDescriptor&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initWithKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ascending&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ascending&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptors&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;addObject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;setSortDescriptors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sortDescriptors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fetchedResultsControllerForEntityNamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entityName&lt;/span&gt;
                                                          &lt;span class=&quot;n&quot;&gt;sortedByKeys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSArray&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;
                                                        &lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSUInteger&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;
                                                    &lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt;
                                                             &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;NSFetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fetchRequestForEntityNamed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;entityName&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sortedByKeys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchBatchSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NSFetchedResultsController&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initWithFetchRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchRequest&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;managedObjectContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;self&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sectionNameKeyPath&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacheName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fetchedResultsController&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;@end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I broke it up into two methods: The one I showed in the improved fetchResultsController method, which in turn calls another method that creates a fetch request but doesn’t attach it to a controller. This method could be useful in its own right, since it lets you create a fetch request using the same shortcuts for entity and sorting keys that I established earlier.&lt;/p&gt;

&lt;p&gt;I thought about putting this on github, but for such a short example I don’t think there’s really much point. Hopefully this demonstrates how to extend existing classes to give you a nice higher-level API.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Beginning iOS Development Workshop</title>
   <link href="http://localhost:4000/blog/2012/01/13/beginning-ios-development-workshop/"/>
   <updated>2012-01-13T11:15:00+01:00</updated>
   <id>http://localhost:4000/blog/2012/01/13/beginning-ios-development-workshop</id>
   <content type="html">&lt;p&gt;I’ve had this idea floating in my head for a while. How about running some iOS developer training
here in Stockholm, to help newcomers get up to speed with Objective-C, Xcode, and the iOS SDK? This
sort of thing has been done successfully in other parts of Europe and in the U.S., but really hasn’t
been tried much here as far as I know.
&lt;!--more--&gt;
In my career, I’ve done my fair share of training and mentoring
for consulting customers, but not much that’s been open to the public. Well, the time has come to
change that. Next month, from the 22nd to the 24th of February, I’ll be hosting the first-ever
&lt;a href=&quot;http://learncocoa.org/beginning_ios_development_workshop.html&quot;&gt;Beginning iOS Development Workshop&lt;/a&gt; here in Stockholm. Actually just a bit outside the city,
in lovely Norrtälje. In this three-day workshop, I’ll show newcomers how to use these technologies
to get started building their own apps.&lt;/p&gt;

&lt;p&gt;Note that this is &lt;em&gt;not&lt;/em&gt; intended for people who are new to software development. I’ll expect all
attendees to have professional knowledge of object-oriented development in one or more languages, so
we won’t get bogged down in details about “what programming is”. If you’ve got experience in Java, C#,
Ruby, Python, or even C++, you will be well equipped for this course.&lt;/p&gt;

&lt;p&gt;For more details, see the &lt;a href=&quot;http://learncocoa.org/beginning_ios_development_workshop.html&quot;&gt;workshop page&lt;/a&gt;, and please contact me if you have any questions
or concerns. Hope to see you there!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Beginning iOS 5 Development</title>
   <link href="http://localhost:4000/blog/2011/12/30/beginning-ios-5-development/"/>
   <updated>2011-12-30T08:30:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/12/30/beginning-ios-5-development</id>
   <content type="html">&lt;p&gt;I’m pleased to announce that &lt;a href=&quot;http://www.apress.com/9781430236054&quot; title=&quot;Print or ebook at Apress&quot;&gt;Beginning iOS 5 Development&lt;/a&gt; has
made its way into the world. The text was completed in November, the ebook 
was released just before Christmas, and the print book should be shipping any
day now.&lt;/p&gt;

&lt;p&gt;This book is the latest edition of what was previously known as &lt;em&gt;Beginning iPhone X Development&lt;/em&gt;,
where most of those &lt;em&gt;X&lt;/em&gt; values were in sync with the latest released iPhone at the time
of writing.&lt;!--more--&gt; Now times have changed,
iOS has spread from the iPhone to the iPad, and this year brought no new iPhone 5 to keep our
book title in sync, so we took the obvious step of re-naming the book after the latest iOS version instead.&lt;/p&gt;

&lt;p&gt;For the current edition, we’re not only covering lots of the great new things included with
iOS 5, we’ve also updated the entire book to cover Xcode 4.2. This means that you can use
the latest and greatest Apple tools to work your way through the examples in the book, and
everything should look and work just as we describe it in the book. The previous edition
covered Xcode 3.2, and anyone who’s been following the evolution of Xcode is probably
familiar with the huge changes that occurred with the Xcode 4 release. Overall, this edition is
probably the most significant rewrite since the first edition. If you have an older edition of the
book and need a refresher, I think you’ll find this new edition to be a great resource for
expanding your iOS development skills. And of course if you’re a newcomer to the book, I’d absolutely
recommend you start with this latest edition.&lt;/p&gt;

&lt;p&gt;Funny story: We actually did a whole lot of writing for Xcode 4.0 over a year ago, when
we were working on the previous edition of the book, but had to backtrack when the public release
of Xcode 4.0 was delayed. Then, as fate would have it, Xcode 4.0 was released to the public
just a few weeks after the previous edition came out, which really felt like a kick in the rear. 
For the new edition, there were so many changes between Xcode 4.0
and 4.2 that we abandoned the Xcode 4.0 work we had done earlier, and recreated all our examples
and descriptions from scratch for Xcode 4.2. Oh, the things we do for you people!&lt;/p&gt;

&lt;p&gt;Anyway, the book is now available for purchase. If you want the print version, you should probably
get it from &lt;a href=&quot;http://www.amazon.com/gp/product/1430236051/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=rebisoft-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=1430236051&quot; title=&quot;Print book on Amazon&quot;&gt;Amazon&lt;/a&gt; which sells it way below the Apress list price. Amazon also sells
a &lt;a href=&quot;http://www.amazon.com/gp/product/B006LPJY3C/ref=as_li_ss_tl?ie=UTF8&amp;amp;tag=rebisoft-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=B006LPJY3C&quot; title=&quot;Kindle version&quot;&gt;Kindle edition&lt;/a&gt; of course, but if you want to go the ebook route you may want
to buy it directly from &lt;a href=&quot;http://www.apress.com/9781430236054&quot; title=&quot;Print or ebook at Apress&quot;&gt;Apress&lt;/a&gt;, where for a few dollars more you have a choice of formats
(epub, mobi, PDF). And don’t forget to register for free at &lt;a href=&quot;http://iphonedevbook.com&quot; title=&quot;The official forum&quot;&gt;our official forum&lt;/a&gt; 
to get access to the archive containing all source code and other resources used in the book. Happy hacking!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Happy Thanksgiving</title>
   <link href="http://localhost:4000/blog/2011/11/24/happy-thanksgiving/"/>
   <updated>2011-11-24T09:34:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/11/24/happy-thanksgiving</id>
   <content type="html">&lt;p&gt;So, the time has come once again for Americans of all stripes to gather
with their families, have a great meal together, and remember all the
things they’re thankful for in their lives. Of course I live in Sweden
where this is just a normal work day (my family and I celebrate the
holiday with friends on Saturday instead), but hey, it’s the thought
that counts.
&lt;!--more--&gt;
And so I thought: How about skipping the now-traditional holiday app
&lt;em&gt;sale&lt;/em&gt;, and instead have a holiday app &lt;em&gt;giveaway&lt;/em&gt;? And I said to myself,
“what the heck”, and so it is done. All of &lt;a href=&quot;http://rebisoft.com&quot;&gt;Rebisoft&lt;/a&gt;’s paid apps,
normally priced between $0.99 and $2.99, are &lt;em&gt;FREE&lt;/em&gt; today. That means
that the full versions of my games  &lt;a href=&quot;http://itunes.apple.com/us/app/scribattle/id301618970?ls=1&amp;amp;mt=8&quot;&gt;Scribattle&lt;/a&gt; and
&lt;a href=&quot;http://itunes.apple.com/us/app/diabolotros/id315350668?ls=1&amp;amp;mt=8&quot;&gt;Diabolotros&lt;/a&gt;, along with the alternative web browser
&lt;a href=&quot;http://itunes.apple.com/us/app/goldy/id417317449?ls=1&amp;amp;mt=8&quot;&gt;Goldy&lt;/a&gt; can all be had for the low, low price of &lt;em&gt;nothing at
all&lt;/em&gt;. &lt;em&gt;Now&lt;/em&gt; how much would you pay?&lt;/p&gt;

&lt;p&gt;But wait, there’s more! My employer &lt;a href=&quot;http://tocaboca.com&quot;&gt;Toca Boca&lt;/a&gt; is also
joining in on the holiday spirit, putting all our apps on sale for just
$0.99 during the Thanksgiving weekend. Ka-ching!&lt;/p&gt;

&lt;p&gt;So get ‘em now while they’re cheap and/or free! Visit 
&lt;a href=&quot;http://itunes.com/rebisoft&quot;&gt;Rebisoft’s App Store Page&lt;/a&gt; for the freebies, and
&lt;a href=&quot;http://itunes.com/tocaboca&quot;&gt;Toca Boca’s App Store Page&lt;/a&gt; for the cheapies.&lt;/p&gt;

&lt;p&gt;Thank you, and you’re welcome, and happy holidays!&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>The Bones of my Buried Past</title>
   <link href="http://localhost:4000/blog/2011/11/22/the-bones-of-my-buried-past/"/>
   <updated>2011-11-22T01:10:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/11/22/the-bones-of-my-buried-past</id>
   <content type="html">&lt;p&gt;A couple of weeks ago, when I accidentally (and temporarily) wiped out
all the older content on this blog, some other things were disrupted as
well. One of these was a little chunk of the website dedicated to
&lt;a href=&quot;http://scapedog.nuthole.com&quot;&gt;Scapedog&lt;/a&gt;, my old college band from 20 years ago.&lt;!--more--&gt; Nowadays
everyone with a band is typically documenting the hell out of it, but
back then we didn’t have digital cameras or digital recording equipment
of any kind. The things we recorded were on &lt;em&gt;analog tapes&lt;/em&gt;, for heaven’s
sake. Fortunately the other guitar player, &lt;a href=&quot;http://twitter.com/paulhagstrom&quot;&gt;Paul Hagstrom&lt;/a&gt;,
was pretty eager to record what we were doing
with the means at hand, which means that after it was all over in 1993
there was quite a pile of audio tapes and posters. At some point during
the 1990s, Paul went through some of this stuff, picked out and cleaned
up some of the audio, and put together a simple website.&lt;/p&gt;

&lt;p&gt;And there it stands still, the &lt;a href=&quot;http://scapedog.nuthole.com&quot;&gt;Shrine to Scapedog&lt;/a&gt;, now
updated just slightly for the modern era but still showing its 1990s
roots. If you’ve got flash you can listen to the songs in a playlist
doohicky on the page, and if not, you can download or listen to each
track individually by clicking its title. No muss, no fuss. The only
leanings toward modern HTML you’ll find on that page is the inclusion of
a viewport spec in the header to make it display decently on mobile.&lt;/p&gt;

&lt;p&gt;You could say our style was grunge or punk, but we started playing
before most people had heard the term grunge (I know I hadn’t heard it),
and I never called what we were doing “punk” or heard it described that
way until someone said it years later. “Oh yeah,” I replied, “I guess we
&lt;em&gt;were&lt;/em&gt; kind of a punk band.” Whatever, we were just trying to make
awesome music with little means and have a good time, and I think we
succeeded to some degree on all points. My own personal favorite is
definitely &lt;a href=&quot;http://scapedog.nuthole.com/#babayaga&quot;&gt;Baba Yaga&lt;/a&gt;, but by all means, feel free to browse around there,
have a listen to some tunes, and make up your own mind.&lt;/p&gt;

&lt;p&gt;So why do I bring this up now? Well, I had honestly forgot that these
pages were tucked away in the nuthole until it all came tumbling down.
And there’s a part of me that forgets, when I’m sitting in front of a
screen for hour upon hour, day after day, that I used to spend my
weekend evenings (or weekday evenings for that matter, if the
opportunity arose) on stage with a group of friends, rocking the hell
out of the little campus bar we usually played at. What good parts of
your past have you forgotten about? How much do you miss them? Could you
have them back now, if you wanted to? I just wonder.&lt;/p&gt;

</content>
 </entry>
 
 <entry>
   <title>Oredev 2011 reflections</title>
   <link href="http://localhost:4000/blog/2011/11/17/oredev-2011-reflections/"/>
   <updated>2011-11-17T12:52:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/11/17/oredev-2011-reflections</id>
   <content type="html">&lt;p&gt;Last week I attended the [Oredev conference][oredev] for the second time, and thought I’d share some
thoughts about the experience. I wrote a bit about &lt;a href=&quot;/blog/2010/11/24/oredev-2010/&quot;&gt;last year’s conference&lt;/a&gt; a year ago (which at the
current snail’s pace of this blog is just about 4 posts ago).
[oredev]: http://oredev.org
&lt;!--more--&gt;&lt;/p&gt;

&lt;p&gt;For anyone who doesn’t know, Oredev is a software development conference
that brings in speakers from around the globe and from a wide range of
fields. There are expert programmers focused on particular platforms,
there are process people focusing on agile practices, there are testers,
designers, and plenty more. Almost anyone doing modern software
development will find something of interest at Oredev. The conference
has several parallel tracks (you can switch between them at will)
focusing on different fields and technologies, and there’s a quite high
ratio of attendees to speakers (about 10% of the attendees are
speakers), so there are lots of experts around all the time.&lt;/p&gt;

&lt;p&gt;That may all sound a bit dry. But apart from the basic facts, there is
an overall vibe running through Oredev that I haven’t really felt at any
other conference I’ve been to. Attendees and speakers, in general, all
seem to be open to learning and curious about what everyone else is
thinking about and working on. There is a pervasive feeling that
everyone there is really interested in honing their skills and improving
their knowledge, for themselves, for their employers, and more broadly,
for everyone. A rising tide raises all the boats, so to speak.&lt;/p&gt;

&lt;p&gt;Beyond that, Oredev is also a true nerd kingdom, and I mean that in the
best way possible. I’m not the biggest nerd I know, but I consider
myself a “nerd’s nerd” and am most happy in the company of other nerds.
Going to Oredev the first time was a bit like finding a home I didn’t know I had, 
and going a second time was like a “nerd homecoming”, but without the
dance and the football game (whew!). Both times I’ve been there, I’ve
befriended some great people, and had good times all around. Huge thanks
are in order to Emily, Kathy, and Mattias for arranging a great event
this year!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Return of the Old Posts</title>
   <link href="http://localhost:4000/blog/2011/11/12/return-of-the-old-posts/"/>
   <updated>2011-11-12T23:35:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/11/12/return-of-the-old-posts</id>
   <content type="html">&lt;p&gt;OK, calamity averted, I managed to bring all the older entries online.
Fortunately I had written a script months ago to convert them all to
textile, I had just never gotten around to switching to jekyll.
Octopress made it all a bit more straightforward, and I could just drop
all the old posts right in. Hoo. Ray. 4. Everything.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Become a Blockhead</title>
   <link href="http://localhost:4000/blog/2011/11/10/become-a-blockhead/"/>
   <updated>2011-11-10T01:15:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/11/10/become-a-blockhead</id>
   <content type="html">&lt;p&gt;Just started messing with Octopress in the hopes of replacing my old
blog with it, and an rsync accident actually wiped out the old blog
entirely. Oh snap!&lt;/p&gt;

&lt;p&gt;Until I have time to fix that, I guess it’s just time to start blogging
from scratch. Let’s start with the links to the presentation I gave
today at the Oredev 2011 conference:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://assets.nuthole.com/presentations/oredev_2011_blockhead.pdf&quot;&gt;Become a Blockhead (PDF version)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://assets.nuthole.com/presentations/oredev_2011_blockhead.key&quot;&gt;Become a Blockhead (Keynote version)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Beginning iPhone 4 Development on shelves soon!</title>
   <link href="http://localhost:4000/blog/2011/01/24/beginning-iphone-4-development-on-shelves-soon/"/>
   <updated>2011-01-24T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2011/01/24/beginning-iphone-4-development-on-shelves-soon</id>
   <content type="html">&lt;p/&gt;
&lt;p&gt;My latest book project is now done! Unlike what I&amp;#8217;ve done before, this isn&amp;#8217;t an entirely new book, but instead a new update of what&amp;#8217;s been a highly popular series of books [&lt;a href=&quot;http://www.amazon.com/gp/product/1430224592?ie=UTF8&amp;tag=rebisoft-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1430224592&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;http://www.amazon.com/gp/product/B001TM92AW?ie=UTF8&amp;tag=rebisoft-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=B001TM92AW&quot;&gt;2&lt;/a&gt;] by &lt;a href=&quot;http://twitter.com/davemark&quot;&gt;Dave Mark&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/jeff_lamarche&quot;&gt;Jeff Lamarche&lt;/a&gt;. Now I&amp;#8217;ve been added to the mix, and I think that what we&amp;#8217;ve come up with is a great new edition that will appeal to anyone starting off with iPhone/iPad development. Even if you already have a previous edition, there&amp;#8217;s plenty of new stuff:&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;New chapter on background processing, and the use of Grand Central Dispatch for building concurrent applications. Contains what Mark Dalrymple called &lt;q&gt;the best &amp;#8220;quick intro to Blocks and &lt;span class=&quot;caps&quot;&gt;GCD&lt;/span&gt;&amp;#8221; I have seen.&lt;/q&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;New chapter on iPad issues, showing how to use the new splitview and popover components.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;All projects recreated from scratch with latest dev tools and &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; (Xcode 3.2.5, iOS 4.2), so as you follow along you&amp;#8217;ll see nicely matching descriptions.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Every piece of source code has been checked and double-checked to improve efficiency and clarity.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Existing chapters have been re-worked to show you the new methods iOS 4 provides for implementing things that were already covered in previous editions. For example, Chapter 15 (&amp;#8220;Taps, Touches, and Gestures&amp;#8221;) now shows how to use UIGestureRecognizer, and how to make your own subclass for a custom gesture; and Chapter 17 (&amp;#8220;Whee! Gyro and Accelerometer!&amp;#8221;) adds gyroscope input where we previously covered only acceleromter input, and is built around the new APIs introduced in iOS 4 for dealing with both.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;All text has been carefully re-read with an eye towards improving clarity and explanatory power. Hardly a single paragraph has escaped the hammer of our combined intellects.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p/&gt;
&lt;p&gt;The ebook version is available now from &lt;a href=&quot;http://apress.com/book/view/143023024x&quot;&gt;Apress.com&lt;/a&gt;, and the print version is available for pre-order from &lt;a href=&quot;http://www.amazon.com/gp/product/143023024X?ie=UTF8&amp;tag=rebisoft-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=143023024X&quot;&gt;Amazon.com&lt;/a&gt; (should ship within a week). Thanks as usual to the Apress team for getting this book to print within a few short weeks after the text was completed!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Oredev 2010</title>
   <link href="http://localhost:4000/blog/2010/11/24/oredev-2010/"/>
   <updated>2010-11-24T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2010/11/24/oredev-2010</id>
   <content type="html">&lt;p/&gt;
&lt;p&gt;A couple of weeks ago, I had a chance to visit this year&amp;#8217;s &lt;a href=&quot;http://oredev.com&quot;&gt;&amp;Oslash;redev&lt;/a&gt; conference. &amp;Oslash;redev is a software development conference that&amp;#8217;s been held each of the last 6 or 7 years in Malm&amp;ouml;, at the southern tip of Sweden. Not only was this my first time in Malm&amp;ouml;, it was also the first time I&amp;#8217;ve given talks myself at such a large conference, and I thought I&amp;#8217;d share some thoughts with anyone who cares to listen.&lt;br /&gt;
&lt;!--more--&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
The conference started off with a sort of &amp;#8220;pre-conference&amp;#8221;, consisting of a couple of days of lengthy workshops, which my schedule didn&amp;#8217;t allow me to attend. I did get there in time for the speakers&amp;#8217; dinner the day before the main conference started, which was quite nice, and was preceeded by a gl&amp;ouml;gg-drinking session at the tightly-packed apartment of Magnus M&amp;aring;rtensson. The dinner was a great chance to break the ice a bit and meet some interesting people.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
&amp;Oslash;redev 2010 featured 3 days&amp;#8217; worth of speakers split across a number of tracks (smartphones, java, web, agile, etc). You could mix and match things however you liked, and I spent most of my time on the smartphones track, partly because that&amp;#8217;s where I gave my presentations and partly because that&amp;#8217;s where my interests lie. Fortunately, all the presentations will be made available for free online viewing later on (in fact many of them are already up), so it&amp;#8217;s possible to catch up somewhat on whatever you missed during the conference.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
The smartphone track was pretty iOS-centric (which suits me fine), but most of the other smartphone platforms were represented as well. Overall I was pretty pleased with most of what I saw, though most of the iOS presentations were quite basic and didn&amp;#8217;t expect the audience to know much of anything about Objective-C or iOS development in general. This critique covers my own talks as well, by the way. I think that in a way, Java developers have an easier time presenting more advanced topics, because they can assume that everyone has a basic understanding of the language. With Objective-C, that&amp;#8217;s not so much the case, since you may have a number of people who are still stuck in &amp;#8220;what&amp;#8217;s with all the colons and square-brackets&amp;#8221;-mode. At any rate, I felt a little leery of presenting too much advanced material, and I think I perceived the same in my fellow iOS developers&amp;#8217; presentations.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
Apart from the smartphone track, I probably spent the most time in a very different track, something that &amp;Oslash;redev calls Xtrack. Xtrack contains a variety of topics that are quite far from the world of software development, many of them centered on music. Several sessions were hosted by Kathy Compton and Thierry Holweck, who together form the pop duo &lt;a href=&quot;http://www.pandatransport.com&quot;&gt;Panda Transport&lt;/a&gt;. It was really great meeting both of them and talking about music. They also performed one evening, as evidenced by the embedded video here. Too bad this recording didn&amp;#8217;t pick up the audio very well, it really sounded great live.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
&lt;iframe title=&quot;YouTube video player&quot; class=&quot;youtube-player&quot; type=&quot;text/html&quot; width=&quot;640&quot; height=&quot;390&quot; src=&quot;http://www.youtube.com/embed/9oLl5AhcXc0&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
As for my own talks, the first one, on using the Cocos2d framework for making iOS games, unfortunately suffered from too little preparation. I think that the material was solid, but didn&amp;#8217;t have quite enough visual examples to tie things together. I have only myself to blame, but considering how crazy this fall has been for me in many ways, it&amp;#8217;s understandable that I didn&amp;#8217;t have enough prep time (if you knew, you&amp;#8217;d understand too). I hope to remedy this some time by fixing up the slideshow with additional content, and perhaps recording a screencast.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
One thing that stood out for me about this talk, both during and after, is that none other than &lt;a href=&quot;http://en.wikipedia.org/wiki/Nolan_Bushnell &quot;&gt;Nolan Bushnell&lt;/a&gt;, a true pioneer in video gaming and home computing, was sitting in the audience! I&amp;#8217;ve looked up to Nolan since I was a kid, and if you had ever told me that I would some day give a talk about some gaming technology and have Nolan in the audience, I probably wouldn&amp;#8217;t have believed you; but, there it is. Fortunately Nolan is a really nice guy who I got to meet before my talk (and spent quite a bit of time with during the rest of the conference as well), so this unlikely situation didn&amp;#8217;t stress me out one bit.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
My other talk, on the last day of the conference (in the last time-slot as well), seemed to work a lot better, both for me and the audience. This time I was talking about making money on the App Store, a topic that is always in my head anyway, so preparation was easy and hardly necessary. This talk is completely non-technical, not a single line of code is shown, so it should be pretty accessible to anyone interested in how the App Store ecosystem works. It&amp;#8217;s &lt;a href=&quot;http://vimeo.com/16964773&quot;&gt;already online at Vimeo&lt;/a&gt;, so check it out if you&amp;#8217;re interested.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
Apart from the sessions, I learned a lot and got some great insights from a variety of discussions between sessions, at meal breaks, and evenings out with a huge range of people from all across the development spectrum. To me, this sort of thing is really what makes conference attendance worthwhile. It&amp;#8217;s the people you meet and connections you make that really stick with you even after the content of the sessions has faded from memory; I guess we are social animals after all. I met so many great people I couldn&amp;#8217;t properly list them all, but particular shout-outs are in order to &lt;a href=&quot;http://twitter.com/pdcawley&quot;&gt;Piers Cawley&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/chews&quot;&gt;Chris Hughes&lt;/a&gt;, Mattias Rosberg, &lt;a href=&quot;http://twitter.com/peylow&quot;&gt;Fredrik Olsson&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/nolanbushnell&quot;&gt;Nolan Bushnell&lt;/a&gt;, and of course &amp;Oslash;redev organizer &lt;a href=&quot;http://twitter.com/michaeltiberg&quot;&gt;Michael Tiberg&lt;/a&gt;, to name a few.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
I&amp;#8217;m not a regular conference-goer, so I don&amp;#8217;t have much to compare with, but over all I&amp;#8217;d say this conference was a huge success and well worth my time. I&amp;#8217;m already looking forward to &amp;Oslash;redev 2011!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>So long, HostingRails.com</title>
   <link href="http://localhost:4000/blog/2010/10/01/so-long-hostingrails-com/"/>
   <updated>2010-10-01T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2010/10/01/so-long--hostingrails-com</id>
   <content type="html">&lt;p&gt;After trying and failing to get any satisfaction from hostingrails.com about some issues, I discovered that the nice little company whose service I signed up for years ago has been purchased by some bigger company that is totally lousy. So, I&amp;#8217;m in the process of moving all my domains, and perhaps changing the technology that powers this blog. In the interim, I&amp;#8217;ve turned off some features that I haven&amp;#8217;t quite gotten working on the new servers, such as the archives, categories, and comments. Hopefully I&amp;#8217;ll be able to get things squared away before too long.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Nordic Mobile Developers Summit</title>
   <link href="http://localhost:4000/blog/2010/07/01/nordic-mobile-developers-summit/"/>
   <updated>2010-07-01T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2010/07/01/nordic-mobile-developers-summit</id>
   <content type="html">&lt;p&gt;&lt;p/&gt;Spent all day yesterday at the Nordic Mobile Developers Summit, where I gave a talk on developing iPhone/iPad apps, a lightning demo of how some of the dev tools work, and took part in some panel discussions and Q&amp;amp;A.&lt;br /&gt;
&lt;p/&gt;Several of the other speakers and panelists are people who are more deeply involved in the handset manufacturers&amp;#8217; side of things, including representatives from Microsoft, Nokia, and SonyEricsson. I assume the organizers tried to bring in someone from Apple, but it seems that Apple doesn&amp;#8217;t really do that sort of thing much, at least not here in Stockholm; So they got me!&lt;br /&gt;
&lt;p/&gt;I had a great time, and met lots of interesting people during the breaks, and got some new perspectives on what the &amp;#8220;other side&amp;#8221; of the smartphone industry is doing. And let&amp;#8217;s be clear, by &amp;#8220;other side&amp;#8221; I really mean &amp;#8220;losing side&amp;#8221;. It&amp;#8217;s not often that my technology of choice is so clearly on top of the world the way that iPhone and iPad are right now, so I won&amp;#8217;t hesitate to rub that in when I can! I also couldn&amp;#8217;t help but make some unnecessary jabs at Microsoft during my talk. As if it matters what I think about Microsoft! Ha ha.&lt;br /&gt;
&lt;p/&gt;Anyway. A few people were asking yesterday if my slides would be up anywhere. I know that everyone&amp;#8217;s slides were gathered, but I don&amp;#8217;t know when or where the &lt;span class=&quot;caps&quot;&gt;NMDS&lt;/span&gt; people will put them all up, so here are mine, both in the original Keynote format for modern Mac and iPad people, and &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; for everyone else.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
&lt;br/&gt;
&lt;a href=&quot;http://assets.nuthole.com/presentations/NMDS_2010-06-10.key&quot;&gt;Keynote version&lt;/a&gt; (Contains amazing animation on one slide! You have been warned!)&lt;br /&gt;
&lt;br/&gt;
&lt;a href=&quot;http://assets.nuthole.com/presentations/NMDS_2010-06-10.pdf&quot;&gt;&lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; version&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Stockholm</title>
   <link href="http://localhost:4000/blog/2010/04/29/stockholm/"/>
   <updated>2010-04-29T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2010/04/29/stockholm</id>
   <content type="html">&lt;p/&gt;
&lt;p&gt;This is the sort of evening where Stockholm flirts with me. I&amp;#8217;ve spent too long with colleagues I seldom speak to, talking about things we never talk about during work hours. It&amp;#8217;s so entertaining, I lose track of time, and suddenly it&amp;#8217;s too late, I&amp;#8217;m missing my train, and I may as well wait. A few colleagues invite me out to a pub, but I&amp;#8217;m just short of time; going there would mean I&amp;#8217;d miss even the &lt;b&gt;next&lt;/b&gt; train.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
Leaving the office, the air is wet but remarkably warm for late April. I could take off my jacket, but I know that would be an invitation to Thor. In the alley, I witness a short but intense gang-fight. At first I can&amp;#8217;t tell the combatants apart (these people look the same to me in the gray dusk), but eventually I get clear sight of one of them: It&amp;#8217;s a fox. So close to the city. I clap my hands and shout, and he runs off, leaving the cat alone to lick its wounds in the bushes.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
Walking on, here it smells like pipe tobacco. Not a person in sight, just grey concrete, but the scent is unmistakable. When is the last time I smoked tobacco in a pipe? Ten years? Fifteen years? Some habits leave a trail that you can never run from. Stockholm is more than flirting with me, it&amp;#8217;s kissing me hard and grabbing my crotch. Every vista, every beetle, every shout heard around a corner, reminds me why I live here.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>"Learn Cocoa on the Mac" is in print!</title>
   <link href="http://localhost:4000/blog/2010/02/23/learn-cocoa-on-the-mac-is-in-print/"/>
   <updated>2010-02-23T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2010/02/23/-learn-cocoa-on-the-mac--is-in-print-</id>
   <content type="html">&lt;p&gt;&lt;p/&gt;It&amp;#8217;s true!  At long last, after months and months of late nights, the book is done.  Available in digital and paper form from &lt;a href=&quot;http://www.apress.com/book/view/9781430218593&quot;&gt;Apress&lt;/a&gt;, as well as &lt;a href=&quot;http://www.amazon.com/gp/product/1430218592?ie=UTF8&amp;tag=rebisoft-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1430218592&quot;&gt;Amazon.com&lt;/a&gt; and elsewhere.  I&amp;#8217;ve also set up &lt;a href=&quot;http://learncocoa.org&quot;&gt;LearnCocoa.org&lt;/a&gt; to be a gathering-place for readers of the book;  Right now, there&amp;#8217;s not much there except for links to buy the book, and to a discussion forum where you can post questions, and also find the source code to all the example apps created in the book.&lt;br /&gt;
&lt;p/&gt;Big thanks once again to everyone who made this possible!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Goodbye crufty old blosxom comments, hello Disqus</title>
   <link href="http://localhost:4000/blog/2010/01/28/goodbye-crufty-old-blosxom-comments-hello-disqus/"/>
   <updated>2010-01-28T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2010/01/28/goodbye-crufty-old-blosxom-comments--hello-disqus</id>
   <content type="html">&lt;p&gt;For years, I&amp;#8217;ve been running a comment system here that&amp;#8217;s been plagued with a variety of problems. I&amp;#8217;ve gotten tired of fixing it, and it looks like Disqus is a much more capable system anyway, so I&amp;#8217;ve changed.  The old comments are still around, and will probably still be around forever, but for new comments, it&amp;#8217;s all Disqus now.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Learn Cocoa: As good as done</title>
   <link href="http://localhost:4000/blog/2010/01/10/learn-cocoa-as-good-as-done/"/>
   <updated>2010-01-10T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2010/01/10/learn-cocoa--as-good-as-done</id>
   <content type="html">&lt;p&gt;My wife just pointed out that I haven&amp;#8217;t blogged at all since last August!  But, I have a good excuse:  I&amp;#8217;ve been writing &lt;a href=&quot;http://www.apress.com/book/view/9781430218593&quot;&gt;Learn Cocoa on the Mac&lt;/a&gt;.  And to top things off, I&amp;#8217;m basically done!  The book itself isn&amp;#8217;t yet in print (though it will be soon), but as of a couple of days ago, the actual writing is done;  All chapters are complete, all the screenshots are in place, and it&amp;#8217;s all passed off to copy editors and layout people and whatnot (the parts of the publishing process that I really don&amp;#8217;t know anything about).  All that&amp;#8217;s left for me is a bit of proofreading, approving editorial changes, etc.&lt;/p&gt;
&lt;p&gt;So, sometime in January, the book should appear on bookshelves near you!  Or, if not near you, at least it&amp;#8217;s on &lt;a href=&quot;http://www.amazon.com/gp/product/1430218592?ie=UTF8&amp;tag=rebisoft-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1430218592&quot;&gt;Amazon&lt;/a&gt; and elsewhere. More info when I know the exact release date.&lt;/p&gt;
&lt;p&gt;Anyway, this has been a huge project.  Lots of work, and extremely satisfying on any number of levels.  And now that it&amp;#8217;s basically done, I find that I already miss it!  I guess I&amp;#8217;ll have to go on writing.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>On Writing "Learn Cocoa"</title>
   <link href="http://localhost:4000/blog/2009/08/11/on-writing-learn-cocoa/"/>
   <updated>2009-08-11T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/08/11/on-writing--learn-cocoa-</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;It has come to my attention that I haven&amp;#8217;t said a word here about my current side project, which I&amp;#8217;m spending all my spare time working on:  I&amp;#8217;m writing a book!  This comes as a surprise to me as much as anyone, but there it is.  Through a happy set of coincidences, I&amp;#8217;ve been given the opportunity to work on the upcoming Apress book &amp;#8220;&amp;#8221;http://www.apress.com/book/view/1430218592&amp;quot;&amp;gt;Learn Cocoa on the Mac&lt;/a&gt;&amp;quot; along with &lt;a href=&quot;http://www.davemark.com/&quot;&gt;Dave Mark&lt;/a&gt; and &lt;a href=&quot;http://iphonedevelopment.blogspot.com&quot;&gt;Jeff LaMarche&lt;/a&gt;, not to mention &lt;a href=&quot;http://borkwarellc.wordpress.com/&quot;&gt;Mark Dalrymple&lt;/a&gt; doing tech review, and of course &lt;a href=&quot;http://www.linkedin.com/pub/clay-andres/0/a2/8b2&quot;&gt;Clay Andres&lt;/a&gt; and the rest of the team at Apress.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;This opportunity came about through a string of coincidences.  Some of them hinge on things that I&amp;#8217;ve done over time without any hope or intention of writing a book, which goes to show, perhaps, that sometimes when you reap what you sow, the harvest may be quite unexpected!&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Anyway, this is a huge undertaking, and I feel like a bit of a hermit, eschewing the watching of TV and the reading of blogs in favor of the writing of pages, but I am truly having a blast.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The truth about my current appearance</title>
   <link href="http://localhost:4000/blog/2009/08/02/the-truth-about-my-current-appearance/"/>
   <updated>2009-08-02T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/08/02/the-truth-about-my-current-appearance</id>
   <content type="html">&lt;p&gt;At a party last night, a friend of a friend made a startling observation about my current appearance, saying that I resembled a combination of Wolverine and Swedish journalist G&amp;ouml;ran Greider, in terms of mutton-chops and wild-hairedness.  See image below for astonishing proof!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/img/gg_w_jn.jpg&quot;/&gt;&lt;/p&gt;
&lt;p&gt;You have no idea how hilarious this revelation was.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>1000 days with the softest-working band not in show business</title>
   <link href="http://localhost:4000/blog/2009/05/31/1000-days-with-the-softest-working-band-not-in-show-business/"/>
   <updated>2009-05-31T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/05/31/1000-days-with-the-softest-working-band-not-in-show-business</id>
   <content type="html">&lt;p&gt;I don&amp;#8217;t know if it&amp;#8217;s been exactly 1000 days, but sometime during the fall of 2007, some friends and I created &lt;a href=&quot;http://www.bandofnone.com&quot;&gt;Band of None&lt;/a&gt;.  Our first 1000 days of existence have been, frankly, uneventful.  The band&amp;#8217;s members and their families have all socialized on several occasions, and in fact the Band of None new year&amp;#8217;s eve &amp;#8220;we should be performing at this party&amp;#8221; discussion has become an annual tradition of its own.  Our self-confidence and faith in our destined future as rock&amp;#8217;n&amp;#8217;roll superstars is matched only by our lack of available time to pursue our dreams.  At this point, approximately 1000 days into our journey to musical stardom, I&amp;#8217;d like to recap some of our accomplishments thus far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Number of live performances: None&lt;/li&gt;
&lt;li&gt;Number of recording deals signed: None&lt;/li&gt;
&lt;li&gt;Number of paid sales of our songs: None&lt;/li&gt;
&lt;li&gt;Revenue from merchandise sales: None&lt;/li&gt;
&lt;li&gt;Number of rehearsals where all band members were present: None&lt;/li&gt;
&lt;li&gt;Number of drug-related deaths: None&lt;/li&gt;
&lt;li&gt;Number of hotel rooms destroyed: None&lt;/li&gt;
&lt;li&gt;Amount of money spent on equipment: None&lt;/li&gt;
&lt;li&gt;Number of days traveling on the road: None&lt;/li&gt;
&lt;li&gt;Total radio plays of all Band of None singles (approx): None&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can see, we don&amp;#8217;t have a lot to be proud of!  Be that as it may, I&amp;#8217;d strongly encourage you to check out our &lt;a href=&quot;http://www.bandofnone.com&quot;&gt;website&lt;/a&gt; and maybe even &lt;a href=&quot;http://www.myspace.com/bandof0&quot;&gt;our myspace page&lt;/a&gt; and &lt;a href=&quot;http://www.bandofnone.com/hear_none.html&quot;&gt;listen to some of our future classics&lt;/a&gt;.  &amp;#8220;Hoffburger&amp;#8221; may be the best, but &amp;#8220;Your Myspace Page&amp;#8221; has something going for it  as well.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New game released: Diabolotros</title>
   <link href="http://localhost:4000/blog/2009/05/29/new-game-released-diabolotros/"/>
   <updated>2009-05-29T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/05/29/new-game-released--diabolotros</id>
   <content type="html">&lt;p&gt;Yesterday I released a new pair of games for iPhone and iPod touch in the App Store, &lt;a href=&quot;http://rebisoft.com/diabolotros&quot;&gt;Diabolotros and Diabolotros Lite&lt;/a&gt;.  Diabolotros is a retro arcade shooter, most of the gameplay is lifted straight from classics like Space Invaders, but I&amp;#8217;ve given it a few twists of my own, and added iPhonetastic tilt&amp;#8217;n&amp;#8217;shake controls:  You tilt the device to steer your ship, and when you have special weapons available, you fire them by giving the the phone a little shake!&lt;/p&gt;
&lt;p&gt;Things for you to see and do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.rebisoft.com/software/diabolotros.html&quot;&gt;Diabolotros info page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.youtube.com/watch?v=j6QMpBTN8YI&quot;&gt;Diabolotros &amp;#8220;sneak preview&amp;#8221; on YouTube&lt;/a&gt; from a few weeks ago&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.davemark.com/?p=913&quot;&gt;Dave Mark&amp;#8217;s kind words about the game&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=315350668&amp;mt=8&quot;&gt;Purchase Diabolotros on the App Store&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=315938586&amp;mt=8&quot;&gt;Download Diabolotros Lite on the App Store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Excitera Mobile Cup: Ten steps to creating your first iPhone app</title>
   <link href="http://localhost:4000/blog/2009/05/29/excitera-mobile-cup-ten-steps-to-creating-your-first-iphone-app/"/>
   <updated>2009-05-29T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/05/29/excitera-mobile-cup--ten-steps-to-creating-your-first-iphone-app</id>
   <content type="html">&lt;p&gt;Last night, I spoke at an iPhone-themed event hosted by &lt;a href=&quot;http://excitera.se/&quot;&gt;Excitera&lt;/a&gt; as part of their &lt;a href=&quot;http://www.mobilecup.se/&quot;&gt;Mobile Cup&lt;/a&gt;, presenting some information for &amp;#8220;iPhone-curious&amp;#8221; developers and entrepreneurs about the iPhone development process.  I gave a non-technical presentation of the series of steps/tasks that any new iPhone developer will need to go through.  The slides are available &amp;lt;a href=&amp;#8220;http://nuthole.com/app_store_ten_steps.pdf&amp;#8221;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.mobile1up.com/&quot;&gt;Aaron Ardiri&lt;/a&gt; also presented his experiences developing his series of games, and &lt;a href=&quot;http://www.linkedin.com/in/johnrchang&quot;&gt;John Chang&lt;/a&gt; talked about some of the things he&amp;#8217;s dealt with working on Skype&amp;#8217;s iPhone app as well as some insights from his previous work at Apple.   There will be some video available later, I&amp;#8217;ll post a link here when it&amp;#8217;s up!&lt;/p&gt;
&lt;p&gt;Big thanks to &lt;a href=&quot;http://www.linkedin.com/pub/hannes-dernehl/2/920/a43&quot;&gt;Hannes Dernehl&lt;/a&gt; for arranging and hosting the event, and &lt;a href=&quot;http://twitter.com/viedma&quot;&gt;Cristobal Viedma&lt;/a&gt; for asking me to be a part of it!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Scribattle Lite:  More results</title>
   <link href="http://localhost:4000/blog/2009/05/22/scribattle-lite-more-results/"/>
   <updated>2009-05-22T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/05/22/scribattle-lite---more-results</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Some time ago I &lt;a href=&quot;http://www.nuthole.com/compute/programming/scribattle_lite_initial_results.html&quot;&gt;posted some charts&lt;/a&gt; showing how my first iPhone game, &lt;a href=&quot;http://www.itunes.com/app/Scribattle&quot;&gt;Scribattle&lt;/a&gt;, was doing after the release of its free sibling, &lt;a href=&quot;http://www.itunes.com/app/ScribattleLite&quot;&gt;Scribattle Lite&lt;/a&gt;.  It turns out that the game was at that time already nearing the heights of its popularity (but oh, what heights it hit!)  The absolute peak occurred on March 3rd and 4th;  during that 2-day period, the full version sold 800 copies and the free version was downloaded &lt;b&gt;a quarter of a million times&lt;/b&gt; (that&amp;#8217;s 250,000 times).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;The charts below show the progression of events after that.  Unlike the previous charts, here I&amp;#8217;ve chosen to include the actual numbers of sales and downloads, instead of just showing them in relative terms.  In both charts you&amp;#8217;ll see a temporary sales up-swing, lasting about 5 days, from the 13th to the 18th of March;  That&amp;#8217;s the time period I ran a &amp;#8220;sale&amp;#8221; on Scribattle, selling it for $0.99 instead of $2.99.  It didn&amp;#8217;t impact my revenue much during those days (roughly triple the sales numbers, but each sale yielding in one-third the revenue), but it may have temporarily delayed the inevitable decline, since the increased sales numbers helped keep it in the charts a little longer.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/img/ScribattleLiteResults2.png&quot;/&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;The chart on the left is a plain linear plot of Scribattle purchase and Scribattle Lite free downloads, with the downloads for Scribattle Lite divided by 100.  Without doing that division, you wouldn&amp;#8217;t see any difference in sales of Scribattle, just a solid blue line along the bottom, because the ratio of Scribattle purchases to Scribattle Lite downloads has normally hovered between 1:200 and 1:100.  So, on the big peak day, March 3rd, Scribattle was bought 373 times, and Scribattle Lite was downloaded 131,000 times.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;The chart on the right is the raw data (no dividing anything by 100), but this time plotted on a logarithmic scale.  Doing this tends to flatten out the peaks, while at the same time accentuating the differences in the smaller ranges.  Here you can more clearly see the nature of the &amp;#8220;long tail&amp;#8221; that Scribattle and Scribattle Lite are currently experiencing;  free downloads and sales have both been holding pretty steady for about a month!  Granted, I&amp;#8217;d be happy to see the steady-state numbers be higher, but I really can&amp;#8217;t complain about it either.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;One interesting spot in these graphs is April 9th.  That&amp;#8217;s when I released an update to Scribattle Lite containing ads (they don&amp;#8217;t affect the gameplay, but instead turn up between levels every few minutes).  Looking at the logarithmic chart, you may detect a slight spike in sales, followed by a slightly sharper decline, leading down to the current steady state a few days later.  I&amp;#8217;m not sure if this was caused by the inclusion of ads, or just happened anyway, but there it is.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I Can't Believe I'm Not a Millionaire</title>
   <link href="http://localhost:4000/blog/2009/04/07/i-can-t-believe-i-m-not-a-millionaire/"/>
   <updated>2009-04-07T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2009/04/07/i-can-t-believe-i-m-not-a-millionaire</id>
   <content type="html">&lt;p&gt;Last night, I gave a presentation at the &lt;a href=&quot;http://cocoaheads.org/se/Stockholm/index.html&quot;&gt;Stockholm Cocoaheads meeting&lt;/a&gt; entitled &amp;#8220;I Can&amp;#8217;t Believe I&amp;#8217;m Not a Millionaire&amp;#8221;about my experiences with Scribattle and Scribattle Lite on the App Store.  Scribattle Lite had a short but intense &amp;#8220;hit&amp;#8221; period when it reached the #1 or #2 spot in most countries, and has now been downloaded over 1.5 million times!  See more in &lt;a href=&quot;http://assets.nuthole.com/presentations/i_cant_believe_im_not_a_millionaire.pdf&quot;&gt;the slideshow&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Scribattle Lite:  Initial results</title>
   <link href="http://localhost:4000/blog/2009/03/02/scribattle-lite-initial-results/"/>
   <updated>2009-03-02T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2009/03/02/scribattle-lite---initial-results</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;I&amp;#8217;ve been collecting data for both Scribattle purchases and Scribattle Lite downloads, and have some results to share.  Like most other reports of this nature that I&amp;#8217;ve seen, I&amp;#8217;m going to be coy and not show any precise numbers, but rather some graphs that show the relative growth for these products.  These charts begin on February 10 (the day Scribattle first appeared on the App Store) and March 1.  Blue dots are Scribattle, green dots are Scribattle Lite.  Scribattle Lite was only available during the last five days of this period.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/img/ScribattleLiteResults1.png&quot;/&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;The first chart shows a nice rising slope for Scribattle Lite, and what seems to be a complete flatline for Scribattle.  This is due to the fact that the free downloads completely dwarf the paid downloads, so that none of the changes in paid downloads equate to even a single pixel on this scale.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;The second chart reveals the true growth in Scribattle sales by scaling them up to match the Scribattle Lite downloads.  Basically, if you plotted Scribattle sales by themselves, and then overlaid that on top of a plot of Scribattle Lite downloads by themselves, this is what you would see.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Finally, for the sake of showing both sets of numbers relative to each other, while still allowing some viewing of the smaller values in the Scribattle sales, here are is a logarithmic view of the same data shown in the first chart.  The nice straight rising lines toward the end, especially for Scribattle Lite, show periods of exponential growth.  What you&amp;#8217;re seeing is basically a doubling of the number of Scribattle Lite downloads each of the last 4 days, and nearly the same kind of increase for Scribattle sales!&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve only had my Lite version on the App Store for 5 days, but even at this early stage I feel safe in saying that in my case, releasing a Lite version has been a huge win for sales of the full version.  Not an epic win (yet), but still a huge win.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Jumping on the Lite bandwagon</title>
   <link href="http://localhost:4000/blog/2009/02/26/jumping-on-the-lite-bandwagon/"/>
   <updated>2009-02-26T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2009/02/26/jumping-on-the-lite-bandwagon</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Since Scribattle never got any &amp;#8220;new releases&amp;#8221; exposure on the App Store (see &lt;a href=&quot;http://www.nuthole.com/compute/programming/6th_tip_for_prospective_iphone_developers.html&quot;&gt;previous entry&lt;/a&gt;), I decided to go ahead an put out a &lt;a href=&quot;http://www.itunes.com/app/ScribattleLite&quot;&gt;free &amp;#8220;Lite&amp;#8221; version&lt;/a&gt;.  Still a highly playable game, but with a few key features stripped out, and including a few strategically placed &amp;#8220;Buy Scribattle&amp;#8221; buttons.  Hopefully this will be downloaded far and wide, and lead to some sales of the original!  At some point I will post some sales data.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The sixth tip for prospective iPhone developers</title>
   <link href="http://localhost:4000/blog/2009/02/18/the-sixth-tip-for-prospective-iphone-developers/"/>
   <updated>2009-02-18T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2009/02/18/the-sixth-tip-for-prospective-iphone-developers</id>
   <content type="html">&lt;p&gt;A while ago I posted &lt;a href=&quot;http://www.nuthole.com/compute/programming/5_tips_for_prospective_iphone_developers.html&quot;&gt;five tips for prospective iPhone developers&lt;/a&gt;, and with a little more experience under my belt I&amp;#8217;ve got one more:&lt;/p&gt;
&lt;h3&gt;6: Post-date your first app&amp;#8217;s release date&lt;/h3&gt;
&lt;p&gt;When I wrote tip 5, it had been nine days since my app was approved for sale, but it wasn&amp;#8217;t in the App Store due to Apple&amp;#8217;s unknown delays in finalizing my sales contract.  I ended up waiting another 19 days, a total of 4 weeks after I got the &amp;#8220;your app is approved for sale&amp;#8221; message, until the app appeared in the App Store!&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;OK, a four week wait isn&amp;#8217;t the end of the world, but in these days where 5000 new apps appear in the App Store each month, every day counts.  And worst of all, according to the App Store, the &amp;#8220;release date&amp;#8221; is not the day my app appeared in the App Store, but the day, 4 weeks earlier, that it was &amp;#8220;approved for sale&amp;#8221;!  So, on my app&amp;#8217;s first day in the App Store, if you drilled down into Games/Action and sorted by Release Date, you wouldn&amp;#8217;t see &lt;a href=&quot;http://www.rebisoft.com/software/scribattle.html&quot;&gt;Scribattle&lt;/a&gt; on the first page.  If you clicked the little arrow to go to the next page, you still wouldn&amp;#8217;t see it.  In fact, you&amp;#8217;d have to click that little arrow &lt;b&gt;fifteen times&lt;/b&gt; to get to Scribattle.  Which means, effectively, that &lt;b&gt;no one&lt;/b&gt; will see Scribattle just by browsing around the App Store.  I had one sure chance of exposure near the top of a category, and lost it due to the workings of the App Store.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Incidentally, I emailed Apple to complain about this, and they sent me a courteous reply, telling me that it &amp;#8220;is operating as expected&amp;#8221;, i.e. it&amp;#8217;s not a bug, it&amp;#8217;s a feature.  Great feature, Apple!&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So finally, the tip:  When you submit your very first app, before your contracts are finalized, don&amp;#8217;t set the release date to &amp;#8220;today&amp;#8221;.  Put it a month or two out into the future.  Then, after your app is approved and your sales contract is finalized, you can go back into iTunes Connect, change the release date to the current date, and have your first app actually show up as a new app in the App Store.  I&amp;#8217;m telling you this now, gentle reader, because I wish someone would have told me this months ago.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Scribattle in the wild</title>
   <link href="http://localhost:4000/blog/2009/02/10/scribattle-in-the-wild/"/>
   <updated>2009-02-10T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2009/02/10/scribattle-in-the-wild</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;At long last, &lt;a href=&quot;http://www.rebisoft.com/software/scribattle.html&quot;&gt;Scribattle&lt;/a&gt; is available!  iPhone and iPod Touch users can now &lt;a href=&quot;http://www.itunes.com/app/Scribattle&quot;&gt;get it from the App Store&lt;/a&gt;, load it up, and start blasting away at Scri and Flingers and Pent (oh my!)&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;It&amp;#8217;s been quite a journey getting this game to market.  I&amp;#8217;ve had very few programming challenges, but a number of small delays due to various technical details involved to package and &amp;#8220;sign&amp;#8221; the app during development, test, and distribution, and a few large delays related to how Apple implements their developer program and handles their contracts.  There&amp;#8217;s a lot of extra hassle compared to releasing desktop software, but a number of friends and colleagues assure me that the system Apple has put in place is still miles ahead of the process for most other embedded and mobile platforms, so hey.  I&amp;#8217;m not complaining (very much).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Now then, if you have an iPhone or iPod Touch, it&amp;#8217;s time to &lt;a href=&quot;http://www.itunes.com/app/Scribattle&quot;&gt;go get yourself some Scribattle&lt;/a&gt;.  OK?&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The folly of executive pay caps</title>
   <link href="http://localhost:4000/blog/2009/02/05/the-folly-of-executive-pay-caps/"/>
   <updated>2009-02-05T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2009/02/05/the-folly-of-executive-pay-caps</id>
   <content type="html">&lt;p&gt;Obama&amp;#8217;s new proposal of imposing executive pay caps on firms that receive government bailout money has a problem as seen in &lt;a href=&quot;http://www.usatoday.com/money/companies/management/2009-02-04-executive-pay-cap-consequences_N.htm&quot;&gt;&lt;span class=&quot;caps&quot;&gt;USA&lt;/span&gt; Today&lt;/a&gt; and other places:  Since firms that are doing well don&amp;#8217;t have the pay caps, there may be a &amp;#8220;brain drain&amp;#8221; wherein the &amp;#8220;best people&amp;#8221; won&amp;#8217;t want to work for the companies where the limits are in place.  According to a &amp;#8220;compensation consultant&amp;#8221; named Alan Johnson, &amp;#8220;[&amp;#8230;] you end up killing the institution you tried to save [&amp;#8230;] You drive away the good people.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Hard to deny that.  You want to &amp;#8220;save&amp;#8221; a company via cash injection, but at the same time you put a limit in place that will tend, over time, to lead the best people away from the company.  The implied upshot of this is that we shouldn&amp;#8217;t be imposing a salary cap.  I&amp;#8217;d like to take this a step farther, and suggest that &lt;em&gt;we shoudn&amp;#8217;t be trying to &amp;#8220;save&amp;#8221; them with cash in the first place&lt;/em&gt;!  Clearly, there is a range of results in the financial industry, where lots of companies feel like they need a handout to keep going, whereas some are apparently doing OK (e.g. the ones who would theoretically pull talent from the ones where the caps would be applied).  It seems to me that we should let the market take care of this.  Those companies that are doing the worst should risk going under, just like any other industry.  If they do, their competitors can buy up their assets, including their previous customers, etc.&lt;/p&gt;
&lt;p&gt;The fact that we even consider bailouts for behemoths like the automobile industry and the financial services industry seems to prove that the US &amp;#8220;market economy&amp;#8221; is anything but.  Like Newton&amp;#8217;s laws of physics which break down in conditions with extreme velocities or extreme scales, our concept of the free market seems to break down when actors in the marketplace are extremely large.</content>
 </entry>
 
 <entry>
   <title>Five tips for prospective iPhone developers</title>
   <link href="http://localhost:4000/blog/2009/01/22/five-tips-for-prospective-iphone-developers/"/>
   <updated>2009-01-22T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2009/01/22/five-tips-for-prospective-iphone-developers</id>
   <content type="html">&lt;p/&gt;
&lt;p&gt;I&amp;#8217;ve been working on an iPhone game called &lt;a href=&quot;http://www.rebisoft.com/software/scribattle.html&quot;&gt;Scribattle&lt;/a&gt; in my spare time since late last summer.  After years of Mac OS X and previously OpenStep and NeXTStep programming, it seemed that stepping into the iPhone development path should be a piece of cake, and as far as the programming is concerned, it has been;  However, there are a number of hoops that every iPhone developer has to jump through in order to get up and running, and get their software published on the App Store.  Based on my experience so far, here&amp;#8217;s some advice for anyone thinking about developing for iPhone.&lt;br /&gt;
&lt;h3&gt;1: Sign up for the paid developer program &lt;em&gt;now&lt;/em&gt;&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
If you&amp;#8217;re thinking about doing iPhone development, but haven&amp;#8217;t signed up yet, then scurry &lt;b&gt;immediately&lt;/b&gt; over to Apple&amp;#8217;s site and &lt;a href=&quot;http://developer.apple.com/iphone/program/apply.html&quot;&gt;sign up&lt;/a&gt;.  After you sign up, there is a waiting period while Apple checks out your information, and this can take &lt;b&gt;months&lt;/b&gt;.  It&amp;#8217;s not that the process actually takes them months, but rather that you end up in a big queue (or maybe just a pile) of applicants, and it takes Apple some time to get through them all.  In my case, after waiting 6 or 7 weeks, I called Apple&amp;#8217;s developer support number, had a brief conversation with a woman who told me that I was just about ready, and that I needed to send them a particular government form proving the validity of my company.  72 hours later I was up and running.  I&amp;#8217;m not sure if my call is what actually broke me free from the pile, or if I just happened to call right when they were about to call me, but in any case you should be prepared for a wait.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
&amp;#8220;But,&amp;#8221; you may say, &amp;#8220;I&amp;#8217;m not even &lt;em&gt;sure&lt;/em&gt; I want to develop for iPhone, so I&amp;#8217;m not ready to pay the fee!&amp;#8221;  Yes, it costs $99, but don&amp;#8217;t worry about that right now;  You don&amp;#8217;t pay until you&amp;#8217;ve been approved, which can take months, and if at that point you decide you don&amp;#8217;t want to continue, all you have to do is &lt;b&gt;not&lt;/b&gt; follow the link they send you, &lt;b&gt;not&lt;/b&gt; enter your credit card info, and &lt;b&gt;not&lt;/b&gt; purchase the $99 developer license.&lt;br /&gt;
&lt;h3&gt;2: Download the developer tools, and start building something&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
While you&amp;#8217;re waiting to be approved as a developer, go &lt;a href=&quot;http://developer.apple.com/iphone/sdk1/&quot;&gt;download the free iPhone &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;&lt;/a&gt; (requires you to create a free registration if you haven&amp;#8217;t already) and start working with it.  The &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; lets you do everything &lt;b&gt;except&lt;/b&gt; build a real, installable app;  Until you have purchased a developer license, you can only run in the iPhone simulator that is part of the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;.  This has some limitations, but works well enough to get you started, especially on your first app.  Give yourself as much time as you need to get a feel for things, especially if you&amp;#8217;re new to Xcode and/or Objective-C.&lt;br /&gt;
&lt;h3&gt;3: Objects in simulator may be slower than they appear&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
One caveat about the SDK&amp;#8217;s iPhone simulator:  The apps you build and run on the simulator are not &amp;#8220;throttled&amp;#8221; at all to simulate the performance of an actual device, so you may see things that seem to work great in the simulator, but fail miserably on an actual device.  The first app I was toying with, doing some simulated physics and drawing everything with CoreGraphics, was nice and smooth on the simulator, but as soon as I put it on a device, it was horrendously slow.  For your first apps this may not be an issue, but it&amp;#8217;s something to be aware of if you&amp;#8217;re working on anything time-critical such as a game&lt;br /&gt;
&lt;h3&gt;4: Learn to love CoreGraphics, but use OpenGL anyway&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
Apple&amp;#8217;s drawing &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; for both Mac OS X and iPhone, CoreGraphics, is really nice; a modern C interface to a great compositing engine.  For basic drawing, including simple animation in response to user actions, this is great.  The problem is that if you need more performance (for example, for a game that you want running at 60 fps), CoreGraphics will probably not cut it.  I performed a simple test, of just drawing a screen-size rectangle full bore, with nothing else going on (no game engine running, and nothing else being drawn), and I could barely get more than 100 draws/second.  So, I started working with OpenGL, using some of Apple&amp;#8217;s example code as a starting point.  The same test, drawing a full-screen rectangle, easily surpassed 10,000 draws/second!  Most people associate OpenGL with 3D graphics, but it works equally well for 2D, so if most of your drawing consists of compositing bitmaps, as opposed to using the curves, fills, and other goodies you get with CoreGraphics, OpenGL will be a huge win for you.&lt;br /&gt;
&lt;h3&gt;5: The first app you release should be non-free &amp;#8220;shovelware&amp;#8221;&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
While you&amp;#8217;re pouring your heart and soul into your first real app, do yourself a favor and quickly slap together a meaningless app that takes basically zero time to create, and offers nearly no functionality.  Whether you create the 23rd &lt;a href=&quot;http://cameron.moon.net.au/2008/08/02/choosing-a-flashlight-app-for-the-iphone/&quot;&gt;flashlight app&lt;/a&gt;, or the 47th &lt;a href=&quot;http://venturebeat.com/2008/12/18/apple-approved-14-new-iphone-fart-apps-yesterday-alone/&quot;&gt;fart app&lt;/a&gt;, or some whole new concept in useless crapdom is up to you.  The reason for doing this is that in spite of all the hardship you went through earlier to get approved as an iPhone app developer, there is still another hurdle:  Your sales contract.  You probably know by now that each app you release is going to sit in a queue until apple approves it for sale, a process that seems to usually take about a week.  For the very first app you release, however, Apple needs to &amp;#8220;finalize&amp;#8221; your sales contract.  They won&amp;#8217;t do that until you have a non-free app submitted and approved for sale.  As of this writing, I&amp;#8217;m still waiting for my contracts to be finalized.  It&amp;#8217;s been 9 days since my app was approved for sale, and now I&amp;#8217;m just twiddling my thumbs, waiting for Apple to do whatever it is they&amp;#8217;re going to do.  Seems like it shouldn&amp;#8217;t be too hard to rubber-stamp the same sales contract that they have for every other iPhone developer, but I&amp;#8217;m not a lawyer, so who knows.  The point is that if i&amp;#8217;d released some crappy shovelware months ago, I wouldn&amp;#8217;t be in this predicament, and you&amp;#8217;d already be able to go and buy &lt;a href=&quot;http://www.rebisoft.com/software/scribattle.html&quot;&gt;Scribattle&lt;/a&gt; in the App Store!&lt;br /&gt;
&lt;hr&gt;&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
There you go.  Hopefully these tips will help some aspiring iPhone developers to get up and running with a minimum of delay.  Now go sign up for the dev program, and keep your eyes peeled for &lt;a href=&quot;http://www.rebisoft.com/software/scribattle.html&quot;&gt;Scribattle&lt;/a&gt;!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Line Item</title>
   <link href="http://localhost:4000/blog/2008/12/17/a-line-item/"/>
   <updated>2008-12-17T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2008/12/17/a-line-item</id>
   <content type="html">&lt;p&gt;I reported a bug in Mail.app, Apple fixed it, and it was specifically mentioned in the &lt;a href=&quot;http://support.apple.com/kb/HT3194&quot;&gt;10.5.6 release notes&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;Mail:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;br /&gt;
Addresses an issue that could prevent Mail from quitting.&lt;/li&gt;&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I coudn&amp;#8217;t be more proud of myself!  Actually that&amp;#8217;s not true.  I&amp;#8217;ll be prouder when I finally get &lt;b&gt;Scribattle&lt;/b&gt; released, for example.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Comics in my Pants</title>
   <link href="http://localhost:4000/blog/2008/08/07/comics-in-my-pants/"/>
   <updated>2008-08-07T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2008/08/07/comics-in-my-pants</id>
   <content type="html">&lt;p&gt;Some time ago, perhaps inspired by the daily comics-watching antics of &lt;a href=&quot;http://joshreads.com/&quot;&gt;The Comics Curmudgeon&lt;/a&gt; and &lt;a href=&quot;http://garfieldminusgarfield.net/&quot;&gt;Garfield Minus Garfield&lt;/a&gt;, I started a new comics-oriented blog.  The premise of this blog is simple:  Most of these so-called &amp;#8220;comics&amp;#8221; or &amp;#8220;funnies&amp;#8221; are anything but funny;  Many of them can be enhanced (I&amp;#8217;ll stop short of saying &amp;#8220;improved&amp;#8221; or &amp;#8220;made funnier&amp;#8221;) by replacing the last text bubble with a single stupid punchline.  The results can be humorous, absurd, ribald, or scatological.  See for yourself at &lt;a href=&quot;http://comicsinmypants.blogspot.com&quot;&gt;Comics In My Pants&lt;/a&gt;.  I&amp;#8217;ve kept it going for a month now, dredging through the daily strips looking for spots where my punchline of choice seems to fit, at least syntactically.  Enjoy!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>iPhone at 23 (days)</title>
   <link href="http://localhost:4000/blog/2008/08/03/iphone-at-23-days/"/>
   <updated>2008-08-03T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2008/08/03/iphone-at-23--days-</id>
   <content type="html">&lt;p&gt;&lt;p/&gt;Now that I&amp;#8217;ve had my iPhone 3G for just over three weeks, I figure it&amp;#8217;s time for me to share some thoughts.&lt;br /&gt;
&lt;p/&gt;Anyone reading this probably already has some idea of the iPhone, just from the constant media attention, so I won&amp;#8217;t mention the most well-known features (touch interface, hi-res display, &lt;span class=&quot;caps&quot;&gt;GPS&lt;/span&gt;) except in passing.&lt;br /&gt;
&lt;h3&gt;The Good&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;The web, everywhere.&lt;/b&gt;  For years I&amp;#8217;ve had phones that supported web-browsing in some form, first with &lt;span class=&quot;caps&quot;&gt;GPRS&lt;/span&gt; and more recently with 3G.  The problem was always the browser itself.  The built-in browser in most phones often feels like a bad joke, like surfing today&amp;#8217;s web with Netscape 1.1, over a 1200 bps modem.  Opera Mini changes the game considerably, providing a decent browser experience for almost any modern phone, but the fact that it&amp;#8217;s not integrated into the phone means that as soon as you click a link in an &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt; or email, or do anything else that the phone considers an internet-related event, you are thrown back into the phone&amp;#8217;s caveman browser.  With the iPhone, you&amp;#8217;re using Safari, which is an established browser with a great javascript interpreter, so it works well with most existing websites.  So far I haven&amp;#8217;t seen any sites that trip it up, and I really don&amp;#8217;t expect to.  The only drawbacks are the lack of Flash (which I do miss in a few spots;  I can&amp;#8217;t play Scrabulous without it!) and Java (really only a drawback in theory, since usage of Java in the browser seems to have vanished from the face of the earth).&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;Pervasive contacts.&lt;/b&gt;  Your contact database, imported automatically from Mac OS&amp;#8217;s Address Book (or Windows&amp;#8217; Outlook, though I haven&amp;#8217;t tested), is readily available for applications to use, both built-in and third-party.  For example, if I&amp;#8217;m using the maps application and need direction&amp;#8217;s to a friend&amp;#8217;s house, I don&amp;#8217;t have to enter his address, since I can just pick it from the address book.  Similarly, I&amp;#8217;ve already got email addresses and phone numbers for most of my friends and family in my address book, so they&amp;#8217;re all just a few taps away.&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;Offloading resources.&lt;/b&gt;  One of the working assumptions of the iPhone is perpetual internet access.  This is put to good use in, for example, the maps application.  Unlike most previous standalone &lt;span class=&quot;caps&quot;&gt;GPS&lt;/span&gt; units or telephones with &lt;span class=&quot;caps&quot;&gt;GPS&lt;/span&gt;, the iPhone doesn&amp;#8217;t need to be preloaded with map data, it gets it live from google just like your web browser does.  This also goes for route planning, that&amp;#8217;s handled by google&amp;#8217;s servers instead of the phone itself.&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;The built-in speaker.&lt;/b&gt;  This baby is surprisingly loud.  Combined with talk-radio podcasts, you can convincingly reproduce the experience of listening to AM talk-radio on a tinny kitchen radio!  This is actually more useful than I&amp;#8217;d imagined;  If it&amp;#8217;s placed on a surface a few feet away I can hear it even over the noise of babbling children, a running dishwasher, etc.  Not a great hi-fidelity music listening experience obviously, but for talk podcasts or just to have some music playing in the background, it&amp;#8217;s pretty good.&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;The App Store.&lt;/b&gt;  Being able to quickly and easily download software for the phone, both free and commercial, via a built-in application, is a big win.  Sure, lots of the applications are similar to one another, and you sometimes sift through commercial apps that are bested by free competitors, but that&amp;#8217;s true of desktop software as well.  If you buy any non-free applications, you probably won&amp;#8217;t need to break out a credit card, since the App Store will charge the credit card you&amp;#8217;ve previously registered with Apple for either a .mac membership or iTunes Music Store purchases.&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;Some great apps.&lt;/b&gt;  There are some great apps available already in the App Store, with more to come.  Chief among these, perhaps, is Apple&amp;#8217;s own Remote app, which lets you control iTunes on any Mac or PC on your wireless network.  For years I&amp;#8217;ve envisioned smarter remote controls, that would actually be aware of the state of the devices they&amp;#8217;re controlling (instead of just blindly sending commands in response to button presses that may or may not be relevant at the moment, as current remotes do), and this is actually a step in that direction.  &lt;br /&gt;
&lt;h3&gt;The &amp;#8220;Bad&amp;#8221;&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;Missing 3G features.&lt;/b&gt;  The iPhone is missing some features that many people have come to expect from 3G phones, particularly &lt;span class=&quot;caps&quot;&gt;MMS&lt;/span&gt;, video calls, and FM radio (not really a 3G feature at all, but something that many people expect in a modern phone in any case).  For me, the absence of those features has no effect.  I&amp;#8217;ve been using 3G phones for several years, and during that time I made a video call once (to a friend in the same room, just to try it out), sent an &lt;span class=&quot;caps&quot;&gt;MMS&lt;/span&gt;  maybe once, and received &lt;span class=&quot;caps&quot;&gt;MMS&lt;/span&gt; messages a handful of times (literally, I can count them on one hand).  &lt;span class=&quot;caps&quot;&gt;IMHO&lt;/span&gt;, video calls and &lt;span class=&quot;caps&quot;&gt;MMS&lt;/span&gt; are actually mis-features, created by the telephone carriers as another way to charge high service fees.  As for FM radio, well I did listen to it a few times with my previous phone, but now I&amp;#8217;ve got 8 gigs of space to fill with my own music and podcasts!  Who wants to listen to commercial radio when they can choose themselves?&lt;br /&gt;
&lt;h3&gt;The (truly) Bad&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;Some things just won&amp;#8217;t sync.&lt;/b&gt;  At least for me.  For some reason any apps I download straight from the phone aren&amp;#8217;t synced back to iTunes, so in the event of a full restore (see below) I am forced to manually download them again.&lt;br /&gt;
&lt;h3&gt;The Ugly&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;Full restore.&lt;/b&gt;  I ended up having a problem where every app I had downloaded (including Apple&amp;#8217;s own Remote app) crashed right after startup, sending me back to the home screen.  A bit of googling revealed the solution:  Sync everything, and do a full restore.  Ugh.  That&amp;#8217;s the sort of thing that makes me hate Windows, where the general solution to any problem starts with &amp;#8220;reinstall Windows&amp;#8221;, and it pains me to see this &amp;#8220;solution&amp;#8221; on the iPhone.  Hopefully things will stabilize.  On a plus note, the full restore was quite painless, if a bit slow.  The only problem is that none of my third-party apps were synced to iTunes, so I had to reinstall them all.  If I&amp;#8217;d had any valuable data saved in any of these apps, then I&amp;#8217;d probably consider that to be a much bigger problem.&lt;br /&gt;
&lt;p/&gt;&lt;b&gt;The Battery.&lt;/b&gt;  Oh, good gracious me, this phone sucks juice.  I was aware that it would do so, I&amp;#8217;d heard that many smartphone users need to charge their phones every day, but still.  The speed with which that battery gauge dives into the red is truly frightening.  I&amp;#8217;m thinking forward a year or two when, if this battery deteriorates anything like my  first MacBookPro battery, I&amp;#8217;ll be down to 3-4 hours of standby time, or maybe 15 minutes of actually using the phone before the battery is completely drained.  Turning off 3G seems to help (and surprisingly doesn&amp;#8217;t seem to effect the speed of mobile surfing too much), and turning off wi-fi helps even more, but how fun is that?&lt;br /&gt;
&lt;h3&gt;In Conclusion&lt;/h3&gt;&lt;br /&gt;
&lt;p/&gt;I think the iPhone 3G represents a milestone, of sorts.  While I don&amp;#8217;t suppose that everyone, or even a large minority, will have an iPhone in the next few years, I do think that it raises the bar in many areas, and when other phones start reaching the iPhone&amp;#8217;s level of integration and internet capabilities, it&amp;#8217;ll be better for everyone.  Rising tides and all that.  In any case, if you want a sneak peek at the future of mobile telephony, buy an iPhone today.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>the great iPhone swindle</title>
   <link href="http://localhost:4000/blog/2008/06/28/the-great-iphone-swindle/"/>
   <updated>2008-06-28T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2008/06/28/the-great-iphone-swindle</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Tech Sweden is abuzz with news of Telia&amp;#8217;s &lt;a href=&quot;http://www.telia.se/iphone&quot;&gt;iPhone pricing plans&lt;/a&gt; having been released today.  Unlike the AT&amp;amp;T contracts in the U.S., Telia&amp;#8217;s contracts for Sweden don&amp;#8217;t directly include unlimited data transfer.  Also unlike the AT&amp;amp;T contracts, at first blush (and subsequent for that matter) the Telia contracts seem really pretty expensive, especially the iMaxi plan, which starts at about $150/month!&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So, looking to maximize my bang for the buck, I worked up a little spreadsheet showing the monthly and total costs for the various phone models and plans.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/img/iPhoneTeliaSwedenPricing.png&quot;&gt;&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;The figures in &lt;b&gt;bold&lt;/b&gt; are prices straight from Telia&amp;#8217;s site.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The figures in light blue are monthly recurring costs for the stated data amounts, and a second row for unlimited data amounts (arrived at by adding in the cost of Telia&amp;#8217;s 9kr/day &amp;#8220;maxtaxa&amp;#8221;;  Note that this represents the &lt;em&gt;maximum&lt;/em&gt; amount you&amp;#8217;d pay in a month, assuming you blew past the free amount in the first day and kept using some amount of data transfer every single day of the month)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The pale green figures show the absolute smallest total cost for each of the two models, and the pale purple figures show the smallest total cost for each of the two assuming unlimited data.  Note that these all wind up being for 18-month contracts, so for comparison&amp;#8217;s sake I&amp;#8217;ve included extended calculations for the 18-month contracts, adding a row for what you&amp;#8217;d pay if you continued with a normal Telia &amp;#8220;fastpris&amp;#8221; account at 199/month, and another row that adds in that &lt;i&gt;plus&lt;/i&gt; the &amp;#8220;maxtaxa&amp;#8221; to arrive at the costs for unlimited data.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The dark green figures show the smallest total 24-month cost for each model, and the dark purple figures show the smallest total 24-month cost for each model assuming unlimited data.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;I haven&amp;#8217;t calculated anything around extra minutes or extra &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt;, since I (and probably many other iPhone users) assume that data usage will be a much more important factor, and in my case I&amp;#8217;m sure that I&amp;#8217;ll seldom use more than 100 minutes or 100 &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt; per month.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;p&gt;Some interesting points pop out when looking at this.  For one thing, the more expensive plans really seem &lt;em&gt;disastrously&lt;/em&gt; expensive, especially iMaxi.  If you&amp;#8217;re not planning on calling for 16 hours a month or sending 1000 &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt;/month (who does that?) then those really seem like a waste.  Even if you were using that much, it seems like the standard tariffs, combined with the iMini plan, would still be much cheaper.  Again, for my anticipated usage I really don&amp;#8217;t care, but maybe someone who really is a big voice or &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt; user will calculate these things.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Another thing that strikes me is that there is an interesting pattern to these numbers.  If you look at the dark purple and dark green figures, the cheapest totals (for minimum and unlimited data) for each model, they both are for a 24-month contract.  Compared to building an equivalent usage period by combining an 18-month contract and a 6-month &amp;#8220;fastpris&amp;#8221;, they are just &lt;b&gt;barely&lt;/b&gt; cheaper;  precisely 200kr in each case.  And that&amp;#8217;s all assuming that Telia&amp;#8217;s &amp;#8220;fastpris&amp;#8221; and &amp;#8220;maxtaxa&amp;#8221; will remain at their current levels for the next 18 months.  If they get even just a tiny bit cheaper, or if another operator has a better deal for iPhone users 18 months from now, then the 18-month contract will turn out to be a better deal in the long run.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So, it seems that financially, whichever of the two models you&amp;#8217;re looking to buy, the iMini 18-month plan seems like the way to go.  Again, things may be different if you plan on doing lots of voice calls or &lt;span class=&quot;caps&quot;&gt;SMS&lt;/span&gt;, but I&amp;#8217;ll leave that for someone else to figure out.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Twitter? Twucket.</title>
   <link href="http://localhost:4000/blog/2008/06/09/twitter-twucket/"/>
   <updated>2008-06-09T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2008/06/09/twitter--twucket-</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Just in time for &lt;span class=&quot;caps&quot;&gt;WWDC&lt;/span&gt; &amp;#8217;08, allow me to introduce you to &lt;a href=&quot;http://www.rebisoft.com/software/twucket.html&quot;&gt;Twucket&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Twucket is a new Twitter client for Mac OS X that I am releasing as freeware.  I created Twucket because I wasn&amp;#8217;t happy with any of the available ways to view my Twitter page.  The actual twitter website is a hugely-rendered page, and requires you to go to the browser now and then to see if anything has come in;  The standalone clients I tried were either wasteful of screen real estate, or didn&amp;#8217;t fit in with the overall Mac &lt;span class=&quot;caps&quot;&gt;GUI&lt;/span&gt;, or contained ads.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Twucket suffers from none of those problems.  Its interface is minimalist and small, it behaves like a normal Mac application, and it doesn&amp;#8217;t insert ads into the display.  What it does offer is a compact, simple Twitter interface with a few features that Twitter users will probably appreciate.  It uses a relatively small amount of screen real estate per message, so you can leave a small window open in a corner of your screen that is still large enough to show the latest 4 or 5 messages you&amp;#8217;ve received.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;I do have additional plans for future versions of Twucket, but today is the day for 1.0.0.  If you&amp;#8217;re a Twitter user, please &lt;a href=&quot;http://www.rebisoft.com/software/twucket.html&quot;&gt;give it a try&lt;/a&gt; and let me know what you think!&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Demand JoCo</title>
   <link href="http://localhost:4000/blog/2008/04/08/demand-joco/"/>
   <updated>2008-04-08T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2008/04/08/demand-joco</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://www.nuthole.com/music/nothing_about_the_iPhone.html&quot;&gt;I&amp;#8217;ve told you before&lt;/a&gt; about &lt;a href=&quot;http://www.jonathancoulton.com/&quot;&gt;Jonathan Coulton&lt;/a&gt; and why you must love him and &lt;a href=&quot;http://www.jonathancoulton.com/store&quot;&gt;give him your money&lt;/a&gt;.  Lately Jonathan has been extending the range of his touring outside the U.S. with a recent show in England, and he&amp;#8217;s thinking about coming to Europe again and &lt;a href=&quot;http://www.jonathancoulton.com/2008/04/02/over-there-again/&quot;&gt;wonders where his fans are&lt;/a&gt;.  He&amp;#8217;s even set himself up on &lt;a href=&quot;http://eventful.com&quot;&gt;Eventful&lt;/a&gt; to figure it out.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Obviously it&amp;#8217;s time to rouse the Nuthole Army out of its slumber.  Arise, Nutholios, and commence with the clicking!&lt;/p&gt;
&lt;/p&gt;
&lt;h3&gt;
&lt;p&gt;&lt;a href=&quot;http://eventful.com/demand/D0-001-000296315-5&quot;&gt;Click here to demand Jonathan Coulton in Stockholm!&lt;/a&gt;&lt;/p&gt;
&lt;/h3&gt;
&lt;p&gt;
&lt;p&gt;Of course you could probably click through there and demand him for some other city instead.  But I won&amp;#8217;t help you there.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Your New Favorite Podcasts</title>
   <link href="http://localhost:4000/blog/2008/02/11/your-new-favorite-podcasts/"/>
   <updated>2008-02-11T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2008/02/11/your-new-favorite-podcasts</id>
   <content type="html">&lt;p/&gt;
&lt;p&gt;Podcasts.  Either you&amp;#8217;re listening to them, or you&amp;#8217;re not.  For me, living geographically removed from the American mediasphere, podcasts are a great way to keep up with American and other English-language professionally-produced audio content, not to mention all the stuff that people are putting out there on their own.  &lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
It&amp;#8217;s a bit like having your own radio station, just full of stuff you actually want to hear, that you can listen to whenever you want.  I&amp;#8217;ve usually got my iPod half-full with a variety of shows;  I don&amp;#8217;t listen to each episode of each show, but I&amp;#8217;ve got a pretty wide span so I can pick whatever I want at whatever moment I feel like listening.&lt;br /&gt;
&lt;p/&gt;&lt;br /&gt;
I don&amp;#8217;t often see people writing about what podcasts they&amp;#8217;re listening to, and randomly browsing podcast sites looking for good shows takes time, so it&amp;#8217;s not always easy to find the good stuff that&amp;#8217;s out there.  Just for the sake for sharing, here are a few of my favorites.&lt;/p&gt;
&lt;/p&gt;
&lt;dl class=&quot;podcastlist&quot;&gt;
&lt;dt&gt;
&lt;div class=&quot;title&quot;&gt;&lt;b&gt;Le Show&lt;/b&gt;&lt;/div&gt; 
&lt;div class=&quot;external&quot;&gt;
&lt;a href=&quot;http://www.harryshearer.com/news/le_show/&quot;&gt;website&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
&lt;div class=&quot;itunes&quot;&gt;&lt;br /&gt;
&lt;a href=&quot;http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=73331688&quot;&gt;&lt;br /&gt;
  &lt;img border=&quot;0&quot; height=&quot;15&quot; width=&quot;61&quot; alt=&quot;Harry Shearer - KCRW&amp;#39;s Le Show - KCRW&amp;#39;s Le Show&quot; src=&quot;http://ax.phobos.apple.com.edgesuite.net/images/badgeitunes61x15dark.gif&quot;&gt;&lt;/img&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/dt&gt;
&lt;dd&gt;Harry Shearer, the voice of many of the Simpsons characters, and one of the co-stars of the classic film Spinal Tap (in the role of Derek Smalls, the one with the incredible sideburns/mustasche combo) gives us this weekly glimpse into the news, focusing on politics and entertainment, rounded off with a bit of sketch comedy.  Satirical, insightful, almost always funny.&lt;/dd&gt;
&lt;dt&gt;
&lt;div class=&quot;title&quot;&gt;&lt;b&gt; This American Life &lt;/b&gt;&lt;/div&gt; 
&lt;div class=&quot;external&quot;&gt;
&lt;a href=&quot;http://www.thislife.org/&quot;&gt;website&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
&lt;div class=&quot;itunes&quot;&gt;&lt;br /&gt;
&lt;a href=&quot;http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=201671138&quot;&gt;&lt;br /&gt;
  &lt;img border=&quot;0&quot; height=&quot;15&quot; width=&quot;61&quot; alt=&quot;Chicago Public Radio - This American Life - This American Life&quot; src=&quot;http://ax.phobos.apple.com.edgesuite.net/images/badgeitunes61x15dark.gif&quot;&gt;&lt;/img&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/dt&gt;
&lt;dd class=&quot;description&quot;&gt;
&lt;p&gt;Each week, This American Life picks a topic, and presents a handful of segments about it using interviews, short-story readings, or other forms of audio journalism.  No matter what the subject matter, it always feels like an hour well-spent.  Chicago Public Radio produces this (mostly-)weekly show.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;
&lt;div class=&quot;title&quot;&gt;&lt;b&gt; Undercover Songs &lt;/b&gt;&lt;/div&gt; 
&lt;div class=&quot;external&quot;&gt;
&lt;a href=&quot;http://undercoversongs.com/&quot;&gt;website&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
&lt;div class=&quot;itunes&quot;&gt;&lt;br /&gt;
&lt;a href=&quot;http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=179236038&quot;&gt;&lt;br /&gt;
  &lt;img border=&quot;0&quot; height=&quot;15&quot; width=&quot;61&quot; alt=&quot;Unknown - Undercover Songs - Undercover Songs&quot; src=&quot;http://ax.phobos.apple.com.edgesuite.net/images/badgeitunes61x15dark.gif&quot;&gt;&lt;/img&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/dt&gt;
&lt;dd class=&quot;description&quot;&gt;
&lt;p&gt;This is one of the very first podcasts I ever subscribed to.  Nuno Nunes presents a handful of covers, songs performed by someone other than the original artists.  This is huge fun!  Although the frequency of updates has declined steadily&amp;mdash;first weekly, then bi-weekly, now basically bi-annually&amp;mdash;the content is great, and you will always hear something new and unexpected.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;
&lt;div class=&quot;title&quot;&gt;&lt;b&gt; Savage Love &lt;/b&gt;&lt;/div&gt; 
&lt;div class=&quot;external&quot;&gt;
&lt;a href=&quot;http://podcasts.thestranger.com/savagelove/&quot;&gt;website&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
&lt;div class=&quot;itunes&quot;&gt;&lt;br /&gt;
&lt;a href=&quot;http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=201376301&quot;&gt;&lt;br /&gt;
  &lt;img border=&quot;0&quot; height=&quot;15&quot; width=&quot;61&quot; alt=&quot;Dan Savage - Savage Love Podcast - Savage Love Podcast&quot; src=&quot;http://ax.phobos.apple.com.edgesuite.net/images/badgeitunes61x15dark.gif&quot;&gt;&lt;/img&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/dt&gt;
&lt;dd class=&quot;description&quot;&gt;
&lt;p&gt;Many people have seen Dan Savage&amp;#8217;s &lt;a href=&quot;http://www.thestranger.com/seattle/SavageLove&quot;&gt;Savage Love advice column&lt;/a&gt; in the alternative press;  I read it for years in one of the Minneapolis/StPaul free papers before moving to Sweden.  Fortunately Dan has embraced this new digital age, and now offers a phone number where people can call in and record their questions, and he offers them advice, sometimes calling them back to get more info.  Though the vast majority of the callers have problems and concerns far from my own life, it&amp;#8217;s pretty interesting to hear the concerns of bisexual grammar fetishists living in poly relationships with jesus freaks.  If this sounds vaguely Jerry Springer-esque, don&amp;#8217;t worry, it&amp;#8217;s not.&lt;/p&gt;
&lt;/dd&gt;
&lt;p&gt;&amp;lt;!&amp;#8212;&lt;br /&gt;
&lt;dt&gt;&lt;br /&gt;
&lt;div class=&quot;title&quot;&gt;&lt;b&gt; &lt;span class=&quot;caps&quot;&gt;XXXXXXXXXXXXXXXXXXXXXXXXXX&lt;/span&gt; &lt;/b&gt;&lt;/div&gt; &lt;br /&gt;
&lt;div class=&quot;external&quot;&gt;&lt;br /&gt;
  &lt;a href=&quot;XXXXXXXXXXXXXXXXXXXXXXXXXX&quot;&gt;website&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
&lt;div class=&quot;itunes&quot;&gt;&lt;br /&gt;
&lt;span class=&quot;caps&quot;&gt;XXXXXXXXXXXXXXXXXXXXXXXXXX&lt;/span&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/dt&gt;
&lt;dd class=&quot;description&quot;&gt;
&lt;p&gt;&lt;span class=&quot;caps&quot;&gt;XXXXXXXXXXXXXXXXXXXXXXXXXX&lt;/span&gt;&lt;/p&gt;
&lt;/dd&gt;
&lt;p&gt;&amp;#8212;&amp;gt;&lt;/p&gt;
&lt;/dl&gt;
&lt;p&gt;Well, that&amp;#8217;ll do for now.  If anyone else feels like sharing, don&amp;#8217;t forget to use the comments, &lt;em&gt;now less-broken than they&amp;#8217;ve been in months&lt;/em&gt;!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>wake up, patriots</title>
   <link href="http://localhost:4000/blog/2007/12/07/wake-up-patriots/"/>
   <updated>2007-12-07T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2007/12/07/wake-up--patriots</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I&amp;#8217;ve been so busy (and having so much fun with) work lately, that I&amp;#8217;ve been neglecting politics to some extent, especially here.  In fact, I now see that my latest entry filed under politics was 19 months ago!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Well, time to catch up.  Here&amp;#8217;s an interview with Naomi Wolf, discussing topics from her latest book, &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/1933392797/rebisoft-20&quot;&gt;The End of America&lt;/a&gt;.  In this interview, she describes having discerned 10 steps that tyrants of the 20th century used to subvert democratic systems in their own countries, converting them to dictatorships.  It shouldn&amp;#8217;t surprise anyone to learn that the piratical crew at the helm of the U.S. government have already implemented a number of these items, with more on the way.&lt;/p&gt;
&lt;p&gt;&lt;object width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/aW9PulYpjGs&amp;rel=1&amp;border=0&quot;&gt;&lt;/param&gt;&lt;param name=&quot;wmode&quot; value=&quot;transparent&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/aW9PulYpjGs&amp;rel=1&amp;border=0&quot; type=&quot;application/x-shockwave-flash&quot; wmode=&quot;transparent&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;
&lt;p /&gt;
&lt;p&gt;Near the end she mentions the &lt;a href=&quot;http://www.americanfreedomcampaign.org/&quot;&gt;American Freedom Campaign&lt;/a&gt;, a bi-partisan movement determined to take away the powers that Bush has grabbed for himself, and restore the checks and balances described by the constitution.  This seems like a good thing to me.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Really, it&amp;#8217;s hard for me to understand head-in-the-sand republicans who willfully ignore the power imbalance that the current administration has created, giving so much power to the executive branch.  It works out well for republicans as long as there&amp;#8217;s a republican president, but what if (&lt;em&gt;gasp&lt;/em&gt;) a democrat actually wins the presidency the next time?  Do they want a democratic president having the same kinds of powers that Bush now has, but applying them towards the progressive goals they so despise?  Or is there a unspoken understanding amongst this crowd that things have been sufficiently &amp;#8220;fixed&amp;#8221; that there simply &lt;em&gt;cannot be&lt;/em&gt; anything but republicans in the presidency, come hell or high water?&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
(via &lt;a href=&quot;gilesbowkett.blogspot.com&quot;&gt;Giles&lt;/a&gt;)&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Defective C++</title>
   <link href="http://localhost:4000/blog/2007/10/29/defective-c/"/>
   <updated>2007-10-29T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2007/10/29/defective-c--</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;At my previous job, I worked as a C++ programmer.  The job, which started out primarily working with Objective-C and Objective-C++ to port a Windows application to Mac OS X, became progressively more a C++ job as time went on.  I came to learn C++ fairly well, just enough to realize how much I dislike it.  I haven&amp;#8217;t properly been able to summarize just why I dislike C++ so much, but fortunately someone else has:  The &lt;a href=&quot;http://yosefk.com/c++fqa/defective.html&quot;&gt;Defective C++&lt;/a&gt; page, part of the larger &lt;a href=&quot;http://yosefk.com/c++fqa/index.html&quot;&gt;&amp;#8220;C++ &lt;span class=&quot;caps&quot;&gt;FQA&lt;/span&gt;&amp;#8221;&lt;/a&gt;, lays bare a number of problems inherent to the design of the C++ language.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
In less than two years of C++ usage, I encountered nearly every one of these problems.  Some of them can be dealt with by deciding upon and following &amp;#8220;best practices&amp;#8221; within the team, which we did (to give credit where credit is due, the more experienced C++ developers I was working with pretty much laid out the best practices for the rest of us to follow), but some of them are just things that you pretty much have to live with, and end up turning the development process into a real straightjacket.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;em&gt;(via &lt;a href=&quot;http://codemines.blogspot.com/2007/10/no-updates-for-6-months-then-two-in-day.html&quot;&gt;Another Day in the Code Mines&lt;/a&gt;, which had picked it up from a &lt;a href=&quot;http://discuss.joelonsoftware.com/default.asp?joel.3.557377.62&quot;&gt;discussion at Joel On Software&lt;/a&gt;;  check out the comments in that discussion if you want to see some extremely blindered C++ apologists in action&amp;#8230;)&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New Apple Logic Studio:  Bigger but smaller</title>
   <link href="http://localhost:4000/blog/2007/10/16/new-apple-logic-studio-bigger-but-smaller/"/>
   <updated>2007-10-16T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/10/16/new-apple-logic-studio---bigger-but-smaller</id>
   <content type="html">&lt;p&gt;Yesterday I installed Apple&amp;#8217;s new &lt;a href=&quot;http://www.apple.com/logicstudio/&quot;&gt;Logic Studio&lt;/a&gt;.  The system I was installing it on was already crowded, with the first four Jam Packs among other things, and I only had about 11 gigs free.  To top it off, the Jam Packs weren&amp;#8217;t properly installed;  I had manually copied them from an older machine, but in a slightly non-standard location, without the .pkg files etc, so the Logic Studio installer couldn&amp;#8217;t see them and wanted to do a fresh install of the new versions included with Logic Studio.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So I figured I&amp;#8217;d wipe out the old Jam Packs manually, and let Logic reinstall them, and hope I&amp;#8217;d have room for all the parts of Logic I wanted.  I stumbled across &lt;a href=&quot;http://discussions.apple.com/thread.jspa?threadID=1134325&amp;tstart=0&quot;&gt;this thread&lt;/a&gt; on Apple&amp;#8217;s support site, which mentioned that the new versions of the Jam Packs in Logic Studio now have audio saved in compressed (but lossless) format, so they&amp;#8217;re a bit smaller.  Cool!&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;So, I wiped out my old Jam Packs, and installed most of Logic Studio, including all software and all  5 Jam Packs, but not the new extra audio content (which as far as I can tell seems to be intended mostly for soundtrack use).  After installing all that, I ended up with 17 gigs of free space!  Installing the new version, with more stuff, saved me 6 gigs!   Woot!</content>
 </entry>
 
 <entry>
   <title>Ruby metaprogramming:  Not scary at all</title>
   <link href="http://localhost:4000/blog/2007/10/11/ruby-metaprogramming-not-scary-at-all/"/>
   <updated>2007-10-11T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/10/11/ruby-metaprogramming---not-scary-at-all</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;There seems to be a sort of mystique around the concept of metaprogramming, but in Ruby it&amp;#8217;s really not mystical at all.  It&amp;#8217;s all about leveraging a few existing methods in smart ways to let you eliminate boring code.  This sort of thing is possible in my &amp;#8220;native language&amp;#8221; of Objective-C, but in Ruby it turns out to be even easier.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Today I&amp;#8217;m going to talk about how to use the &lt;code&gt;method_missing&lt;/code&gt; method to eliminate repetitive boilerplate code.  &lt;code&gt;method_missing&lt;/code&gt; is Ruby&amp;#8217;s fallback strategy for unresolvable method names encountered at runtime.  If you try to call a non-existent method on any object, the Ruby runtime will instead call &lt;code&gt;method_missing&lt;/code&gt; on that object;  The default behavior of this method is to raise an exception, but we can override it to do smart things based on the method name.&lt;/p&gt;
&lt;/p&gt;
&lt;h4&gt;The Badness&lt;/h4&gt;
&lt;p&gt;
&lt;p&gt;The Rails application I&amp;#8217;m working on has a role-based permissions scheme, with a ManagementRole model that sits between User and Program models, allowing us to define roles that a User can have relative to a given Program, which in turn constrain what they&amp;#8217;re allowed to do with the application.  These roles are expressed concretely as simple subclasses of ManagementRole, with names like RoleSearchMembers and RoleCreateMemberships.  Up until recently, checking whether a User were allowed to perform certain tasks within a Program consisted of calling one of several nearly-identical class methods defined on ManagementRole, such as these:&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  def self.allow_search_members?(user, program)
    return User.is_administrator?(user) ||
      self.program_role_exists?(user, program, &quot;RoleSearchMembers&quot;)
  end
  
  def self.allow_create_memberships?(user, program)
    return User.is_administrator?(user) ||
      self.program_role_exists?(user, program, &quot;RoleCreateMemberships&quot;)
  end

  # etc
  
  # the program_role_exists? method, not listed here, simply checks
  # for the existence of a matching ManagementRole object
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;As you can see, this is extremely repetitive, and adding new types of permissions means adding new, nearly-identical methods.  As of now there are 18 methods like this, and that number will just go up in the future, leading to even more boilerplate code.  Where will this madness end?&lt;/p&gt;
&lt;/p&gt;
&lt;h4&gt;The Goodness&lt;/h4&gt;
&lt;p&gt;
&lt;p&gt;Providing a simple definition for &lt;code&gt;method_missing&lt;/code&gt; in the same class lets me eliminate all those 18 methods, and will automatically deal with any new ManagementRole subclasses.  It looks like this:&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  # instead of a bunch of allow_xxx_xxx_xxx? methods that differ only slightly, 
  # we just catch all such calls here.
  def self.method_missing(method_id, *args)
    if match = /allow_([_a-zA-Z]\w*)\?/.match(method_id.to_s) and args.size==2
      return User.is_administrator?(args[0]) || 
        self.program_role_exists?(args[0], args[1], &quot;Role#{match[1].camelize}&quot;)
    else
      super
    end
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;The first thing this does is examine the method and the argument list, to determine if it looks like the kind of method we are trying to replace.  If the method name looks anything like &amp;#8220;&lt;code&gt;allow_xxx_yyy_zzz?&lt;/code&gt;&amp;#8221;, and if there are exactly 2 arguments, then we&amp;#8217;ll do something interesting.  Otherwise, we&amp;#8217;ll just call &lt;code&gt;super&lt;/code&gt; and let the parent class deal with it.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;In the &amp;#8220;interesting&amp;#8221; case, we simply perform the same checks we did before to determine whether we return true or false, but now we&amp;#8217;re using indexed values from the args array, and constructing the string naming the MangementRole subclass by using the result of the earlier regexp match.  Voila!&lt;/p&gt;
&lt;/p&gt;
&lt;h4&gt;The Even-Betterness&lt;/h4&gt;
&lt;p&gt;
&lt;p&gt;Of course, software development being what it is, any time you revisit an old design to try to improve it, the act of improving it can lead you to discover new, further improvements.  While writing this, I realized something that would have avoided all this boilerplate code, and the metaprogramming it led to, in the first place:  Instead of asking the ManagementRole class explicitly about each of these permissions, I&amp;#8217;ll be better off writing a single method called &lt;code&gt;allow?&lt;/code&gt; in the ManagementRole class, which will do a lookup based on the recipient&amp;#8217;s class-name, e.g. RoleSearchMembers, RoleCreateMemberships.  And then instead of calling &lt;code&gt;ManagementRole.allow_search_members?(u,p)&lt;/code&gt;  , I will call &lt;code&gt;RoleSearchMembers.allow?(u,p)&lt;/code&gt;.  That will lead to even less code than the metaprogramming version, and &lt;a href=&quot;http://lesscode.org/&quot;&gt;less code&lt;/a&gt; is always better code.  I haven&amp;#8217;t written it yet, but it&amp;#8217;ll probably look something like this:&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
  def self.allow?(user, program)
    return User.is_administrator?(user) ||
      self.find_by_user_and_program(user, program)
  end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;So this problem, with its metaprogramming-to-the-rescue solution, turned out to be easily solvable with more traditional object-orientation, but that&amp;#8217;s OK!  Hopefully this post will be helpful anyway, for someone else whose problem doesn&amp;#8217;t have the same easy solution that mine turned out to have&amp;#8230;&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RailsConf Europe notes</title>
   <link href="http://localhost:4000/blog/2007/09/26/railsconf-europe-notes/"/>
   <updated>2007-09-26T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/09/26/railsconf-europe-notes</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;I attended RailsConf Europe 2007 in Berlin last week.  This has already been blogged to death I suppose, but here&amp;#8217;s my take on a few items:&lt;br /&gt;
&lt;dl&gt;&lt;br /&gt;
&lt;dt&gt;Bratwurst on Rails&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;The local Berlin ruby brigade organized this event;  The night before the conference began, over &lt;a href=&quot;http://www.flickr.com/search/?q=railsconf%20bratwurst&amp;w=all&quot;&gt;400 rails nerds&lt;/a&gt; gathered to eat &lt;a href=&quot;http://www.flickr.com/photos/thomasritz/1398488694/&quot;&gt;freshly-made sausage&lt;/a&gt; and drink beer.  This was a great way to start things off, I had lots of interesting conversations with a variety of people.&lt;/dd&gt;&lt;br /&gt;
&lt;dt&gt;Networking, in general&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;All throughought the 3+ days I was there, I had the opportunity to meet and speak to so many people doing so many interesting things.  Anywhere you turned, you could find people ready and willing to strike up a conversation about rails, programming in general, business strategies, or anything else you might think of.  This was just a great, friendly crowd to hang out with.  Extra props to &lt;a href=&quot;http://www.thoughtworks.com&quot;&gt;Thoughtworks&lt;/a&gt; for picking up the tab for everyone to get a beer or two at the hotel bar one evening!&lt;/dd&gt;&lt;br /&gt;
&lt;dt&gt;JRuby&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;There was lots of emphasis on JRuby.  Thoughtworks and others are pushing JRuby on Rails as an easy way to get Rails into the enterprise, since you can deploy on any standard Java app server;  Sun includes support for JRuby (as well as normal Ruby) in NetBeans;  and &lt;a href=&quot;http://www.amazon.com/Practical-JRuby-Rails-Web-Projects/dp/1590598814/&quot;&gt;Ola Bini&amp;#8217;s new book&lt;/a&gt; on the topic has just hit the shelves, and there&amp;#8217;s a lot of interest and potential in JRuby overall.  But at the same time, I&amp;#8217;m somewhat skeptical of Sun&amp;#8217;s involvement.  It seems great that they&amp;#8217;re embracing JRuby, but hopefully they won&amp;#8217;t somehow turn it into the sort of bloated mess that Java has become.  And frankly, I&amp;#8217;m not convinced that the Java app server stack isn&amp;#8217;t a part of the IT bloatware beast that Thoughtworks&amp;#8217; own Cyndi Mitchell was railing against during her short talk.&lt;/dd&gt;&lt;br /&gt;
&lt;dt&gt;RejectConf&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;This was a hoot.  The idea is that any presentation that had been rejected by the conference organizers, plus anything else that anyone wanted to present, could be shown in a severely time-limited format (20 seconds per slide).  Lots of interesting presentations, in a short time and fun, friendly atmosphere.  Unfortunately the venue was a little too small, it was tough to get close enough to be able to see and hear much, but hey.&lt;/dd&gt;&lt;br /&gt;
&lt;dt&gt;Australians&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;Throughout the conference (including RejectConf), the presentations that were the most consistently funny and entertaining, while remaining informative and valuable, were almost always led by Australians.  Make of that what you will.&lt;/dd&gt;&lt;br /&gt;
&lt;dt&gt;The occasional bad presentation&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;I&amp;#8217;m not going to name names here.  But one presentation, held on the final day, was really a waste.  The guy started off by telling us that some time after his topic was approved for the conference, further development of the topic revealed to him that what he was going to present really wasn&amp;#8217;t working out that well in practice.  Now this could have been interesting in and of itself, to see in detail how a seemingly-sound concept breaks down when pushed a bit farther.  Instead of that, however, the audience were treated to a lot of hand-waving and disclaimers of &amp;#8220;I&amp;#8217;m not going to show you the code because it won&amp;#8217;t work for you anyway&amp;#8221;.  When there was still half an hour of time left, he was completely out of material and stopped;  At that point, at least a third of the audience had already given up and left.  &lt;/dd&gt;&lt;br /&gt;
&lt;dt&gt;&lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt; Keynote&lt;/dt&gt;&lt;br /&gt;
&lt;dd&gt;I don&amp;#8217;t think I&amp;#8217;m going out on a limb if I say that DHH&amp;#8217;s public speaking is known for balancing a fine line between self-confidence and arrogance.  I think this one was edging towards the latter.  Sure, it&amp;#8217;s great to hear that Rails 2.0 is approaching quickly, etc, but the part of the speech where he was proclaiming that the Rails revolution is already over, we&amp;#8217;ve won, and now we can rest on our laurels and &amp;#8220;enjoy Rails&amp;#8221;?  I think he&amp;#8217;s putting the cart before the horse.  Maybe &lt;span class=&quot;caps&quot;&gt;DHH&lt;/span&gt; is at this point surrounded by so many yes-men that to him, Rails seems like it&amp;#8217;s truly the only game in town, but in reality it can still go so much farther, be applied to so many areas, that it strikes me as premature to proclaim victory.  In some places and markets, Rails is still a very difficult sell;  In Stockholm where I live, for example, as far as I can tell most of the big consulting firms that have dipped a toe into Rails development have had a really hard time making inroads into the Swedish enterprise market.&lt;/dd&gt;&lt;/p&gt;
&lt;/dl&gt;</content>
 </entry>
 
 <entry>
   <title>Installing RMagick on Mac OS X and Ubuntu</title>
   <link href="http://localhost:4000/blog/2007/08/31/installing-rmagick-on-mac-os-x-and-ubuntu/"/>
   <updated>2007-08-31T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/08/31/installing-rmagick-on-mac-os-x-and-ubuntu</id>
   <content type="html">&lt;p&gt;&lt;p/&gt;I haven&amp;#8217;t done anything with &lt;a href=&quot;http://rmagick.rubyforge.org/&quot;&gt;RMagick&lt;/a&gt; at all, partly because it relies on &lt;a href=&quot;http://www.imagemagick.org/&quot;&gt;ImageMagick&lt;/a&gt; which many consider difficult to install on Mac OS X.  Lately I&amp;#8217;ve had a reason to use the excellent &lt;a href=&quot;http://nubyonrails.com/pages/gruff&quot;&gt;Gruff&lt;/a&gt; charting library, so it was time to buckle down and install this stuff.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
As it turns out, it&amp;#8217;s really not as complicated as some people say.  Assuming you&amp;#8217;ve already got &lt;a href=&quot;http://www.macports.org/&quot;&gt;macports&lt;/a&gt; and &lt;a href=&quot;http://www.rubygems.org/&quot;&gt;rubygems&lt;/a&gt; installed, it basically comes down to this:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
sudo port install freetype&lt;br /&gt;
sudo port install ghostscript&lt;br /&gt;
sudo port install imagemagick&lt;br /&gt;
#sudo port install graphicsmagick&lt;br /&gt;
sudo gem install rmagick&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;a href=&quot;http://www.elctech.com/blog/archives/2007/2&quot;&gt;Somewhere&lt;/a&gt; I got the idea to also install &lt;a href=&quot;http://www.graphicsmagick.org/&quot;&gt;graphicsmagick&lt;/a&gt; after imagemagick, but for some reason port doesn&amp;#8217;t seem to be able to find the package;  It tries a few dozen sites and fails, so I commented it out above, but feel free to try it yourself.  But no matter, it seems to not be necessary;  I can now create images, render text, write them to disk, etc.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
On Ubuntu (6.10), the incantation is different, but even simpler (via &lt;a href=&quot;http://expressica.com/2007/07/04/how-to-install-rmagick-gem-on-linuxubuntu/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;EXPRESSICA&lt;/span&gt;&lt;/a&gt;:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
sudo apt-get install imagemagick&lt;br /&gt;
sudo apt-get install libmagick9-dev ruby1.8-dev&lt;br /&gt;
sudo gem install rmagick&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;The only caveat is that if you&amp;#8217;re running without swap space and have less than a couple hundred megs of free &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt; (e.g. on a &lt;span class=&quot;caps&quot;&gt;VPS&lt;/span&gt; server) you may need to stop some of your processes before attempting that last line, or you&amp;#8217;ll get this not-so-helpful set of errors after it runs for a while, consumes all available &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt;, and subsequently crashes:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
Building native extensions.  This could take a while&amp;#8230;&lt;br /&gt;
&lt;span class=&quot;caps&quot;&gt;ERROR&lt;/span&gt;:  While executing gem &amp;#8230; (Gem::Installer::ExtensionBuildError)&lt;br /&gt;
    &lt;span class=&quot;caps&quot;&gt;ERROR&lt;/span&gt;: Failed to build gem native extension.&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
Hopefully this will save someone a few hours.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>My first home-made rake task</title>
   <link href="http://localhost:4000/blog/2007/08/15/my-first-home-made-rake-task/"/>
   <updated>2007-08-15T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/08/15/my-first-home-made-rake-task</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I wanted to be able to examine my development log for rails deprecation warnings, and came up with this handy one-liner:&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;pre&gt;grep &amp;#8220;^&lt;span class=&quot;caps&quot;&gt;DEPRECATION&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;WARNING&lt;/span&gt;:&amp;#8221; development.log | awk &amp;#8216;{print $3, $4, $5, &amp;#8220;:&amp;#8221;, $NF}&amp;#8217; | sort | uniq&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
This gives me output something like this:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
@params is deprecated! : script/../config/../app/views/waiting_messages/prepare_reply.rhtml:9)&lt;br /&gt;
@request is deprecated! : ./script/../config/../app/controllers/account_controller.rb:10)&lt;br /&gt;
You called render(&amp;#8216;new_member_in_program&amp;#8217;), : /opt/local/lib/ruby/gems/1.8/gems/actionpack-1.13.3/li [&amp;#8230;]&lt;br /&gt;
end_form_tag is deprecated : script/../config/../app/views/members/bulknew.rhtml:10)&lt;br /&gt;
find_all is deprecated : (irb):3)&lt;br /&gt;
start_form_tag is deprecated : script/../config/../app/views/members/bulknew.rhtml:2)&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
It&amp;#8217;s not perfect; I&amp;#8217;m missing some useful info from some of the lines (such as the &amp;#8216;You called render&amp;#8230;&amp;#8217;) that I&amp;#8217;ll have to go back and pick over.  But in broad strokes, it gives me a fairly concise list of some things that need to be cleaned up.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
However, that one-liner is fairly meaty.  Who wants to remember that, or make an alias for it, or need to look it up?  Yuck.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
How about a rake task?  I&amp;#8217;ve never written one before, but everyone&amp;#8217;s always raving about how simple it is, so I figured I&amp;#8217;d go ahead.  Hopefully this helps show how simple it is.  While I&amp;#8217;m at it, I&amp;#8217;ll go ahead and include the full text of the warning (except for the redundant &amp;#8220;&lt;span class=&quot;caps&quot;&gt;DEPRECATION&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;WARNING&lt;/span&gt;&amp;#8221; at the beginning, since we already know we&amp;#8217;re looking for that) instead of truncating it like I did in my awk-based one-liner.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Here it is:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
namespace :utils do
  desc &quot;List deprecation warnings in development log&quot;
  task :find_deprecated do
    File.open('log/development.log') do |file|
      lines = file.select {|line| line =~ /^DEPRECATION WARNING:/}
      lines.sort.uniq.each {|line| puts line.split('DEPRECATION WARNING: ')[1]}
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Put that in a file called &lt;code&gt;utils.rake&lt;/code&gt;  inside your &lt;code&gt;lib/tasks&lt;/code&gt; directory, and call it by typing &lt;code&gt;rake utils:find_deprecated&lt;/code&gt;, and you&amp;#8217;ll get something like this (lines chomped for presentation purposes):&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
@params is deprecated! Call params.[] instead of @params.[]. Args: [:response_text]  See http://www. [...]
@request is deprecated! Call request.accepts instead of @request.accepts. Args: []  See http://www.r [...]
You called render('new_member_in_program'), which is a deprecated API call. Instead you use render : [...]
end_form_tag is deprecated and will be removed from Rails 2.0  See http://www.rubyonrails.org/deprec [...]
find_all is deprecated and will be removed from Rails 2.0 (use find(:all, ...))  See http://www.ruby [...]
start_form_tag is deprecated and will be removed from Rails 2.0 (use form_tag instead)  See http://w [...]
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt; &lt;br /&gt;
There are certainly improvements that could be made, such as adding the ability to search test.log and production.log as well, but this&amp;#8217;ll do for now.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Hoffburger</title>
   <link href="http://localhost:4000/blog/2007/06/11/hoffburger/"/>
   <updated>2007-06-11T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/06/11/hoffburger</id>
   <content type="html">&lt;p&gt;Hot on the heels of the release of &lt;a href=&quot;/music/jack.your_myspace_page&quot;&gt;Your Myspace Page&lt;/a&gt;, we at &lt;a href=&quot;http://www.bandofnone.com&quot;&gt;Band of None&lt;/a&gt; have now released yet another single, &lt;em&gt;Hoffburger&lt;/em&gt;.  Download the mp3 &lt;a href=&quot;http://www.bandofnone.com/Hoffburger.mp3&quot;&gt;with the clicking action here&lt;/a&gt;, or use the fun thingy below to listen to it immediately:&lt;/p&gt;
&lt;p&gt;&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://www.bandofnone.com/player.swf&quot; width=&quot;290&quot; height=&quot;24&quot; id=&quot;audioplayer8&quot;&gt;&lt;br /&gt;  &lt;param name=&quot;movie&quot; value=&quot;http://www.bandofnone.com/player.swf&quot; /&gt;  &lt;param name=&quot;FlashVars&quot; value=&quot;soundFile=http://www.bandofnone.com/Hoffburger.mp3&quot; /&gt;&lt;br /&gt;  &lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;  &lt;param name=&quot;menu&quot; value=&quot;false&quot; /&gt;&lt;br /&gt;  &lt;param name=&quot;wmode&quot; value=&quot;transparent&quot; /&gt;&lt;br /&gt;&lt;/object&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
&lt;em&gt;Hoffburger&lt;/em&gt; is inspired, as you may imagine, by David Hasselhoff&amp;#8217;s drunken hamburger-eating escapade, captured on &lt;a href=&quot;http://www.youtube.com/watch?v=BPYDOam_qec&quot;&gt;video&lt;/a&gt; by his daughter and reported widely throughout all media.  &lt;em&gt;Band of None&lt;/em&gt; considers it an honor (and a duty) to take that feel-bad viral video of the late spring and turn it into the feel-good hit of the summer.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Sing it with me!  &lt;strong&gt;Hoffburger with extra cheese!&lt;/strong&gt;&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Your Myspace Page</title>
   <link href="http://localhost:4000/blog/2007/05/15/your-myspace-page/"/>
   <updated>2007-05-15T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/05/15/your-myspace-page</id>
   <content type="html">&lt;p&gt;After much hemming and hawing, the second single from Band of None is hereby foisted upon the world.  It&amp;#8217;s called &lt;em&gt;Your Myspace Page&lt;/em&gt;, and you can &lt;a href=&quot;http://www.bandofnone.com/YourMyspacePage.mp3&quot;&gt;download it here&lt;/a&gt; or listen to it with the following gadget:&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://www.bandofnone.com/player.swf&quot; width=&quot;290&quot; height=&quot;24&quot; id=&quot;audioplayer8&quot;&gt;&lt;br /&gt;  &lt;param name=&quot;movie&quot; value=&quot;http://www.bandofnone.com/player.swf&quot; /&gt;  &lt;param name=&quot;FlashVars&quot; value=&quot;soundFile=http://www.bandofnone.com/YourMyspacePage.mp3&quot; /&gt;&lt;br /&gt;  &lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;  &lt;param name=&quot;menu&quot; value=&quot;false&quot; /&gt;&lt;br /&gt;  &lt;param name=&quot;wmode&quot; value=&quot;transparent&quot; /&gt;&lt;br /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;This is a pretty big departure from &lt;a href=&quot;/music/jack.darksided.html&quot;&gt;the previous single&lt;/a&gt;.  I don&amp;#8217;t know what, if anything, this implies about Band of None&amp;#8217;s &amp;#8220;musical direction&amp;#8221;, but time will tell.  Meanwhile, comments are welcome!&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Introducing RUMP</title>
   <link href="http://localhost:4000/blog/2007/05/02/introducing-rump/"/>
   <updated>2007-05-02T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/05/02/introducing-rump</id>
   <content type="html">&lt;p&gt;Many of you have heard of web application deployment using the &lt;a href=&quot;http://en.wikipedia.org/wiki/LAMP_(software_bundle)&quot;&gt;&lt;span class=&quot;caps&quot;&gt;LAMP&lt;/span&gt;&lt;/a&gt; set of technologies that came into vogue a few years ago.  Later, &lt;a href=&quot;https://store.joyent.com/products/show/4&quot;&gt;&lt;span class=&quot;caps&quot;&gt;MARS&lt;/span&gt;&lt;/a&gt; was thrown about as a four-letter acronym to describe a Rails-centric deployment scheme, but some of the choices (Solaris?  Apache?  Please.) leave me cold.&lt;/p&gt;
&lt;p&gt;So, without further ado, let me introduce you to &lt;b&gt;&lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt;&lt;/b&gt;:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;R&lt;/b&gt;ails&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;U&lt;/b&gt;buntu&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;M&lt;/b&gt;ongrel&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;P&lt;/b&gt;ostgresql&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Why these choices?  Well, &lt;b&gt;Rails&lt;/b&gt; goes without saying (if you aren&amp;#8217;t interested in Rails, then &lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt; is not for you);  &lt;b&gt;Ubuntu&lt;/b&gt; because it offers a lightweight server config with a package system that is even better than Debian&amp;#8217;s; &lt;b&gt;Mongrel&lt;/b&gt; because it&amp;#8217;s currently the best web server targetted at Ruby application deployment and is getting better all the time; and &lt;b&gt;Postgresql&lt;/b&gt; because MySQL, despite all the good it&amp;#8217;s done for the world, still falls behind on a number of features.&lt;/p&gt;
&lt;p&gt;To help get you started, what follows is a reasonably accurate description of what I went through to get my &lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt; in gear.  I had occasion to do this a couple times within a few days a little while ago, and kept some reasonably complete notes as I went along.  Hopefully this will help others experience the satisfaction of a nice, fit &lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;Wherever possible, I&amp;#8217;ve tried to find the simplest configuration that works.  Of course each component can be installed and configured in a variety of ways, and &lt;span class=&quot;caps&quot;&gt;YMMV&lt;/span&gt;.  For what it&amp;#8217;s worth, the following is what seems to be working well for me.&lt;/p&gt;
&lt;h2&gt;Installation notes for &lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt; deployment server (running ubuntu 6.10 &amp;#8220;edgy eft&amp;#8221;)&lt;/h2&gt;
&lt;p&gt;I started off with an empty image installed by my hosting company of choice.  This was a bare-bones Ubuntu server install, containing a single root account with ssh enabled, and pretty much nothing else.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;First, log in to your new system and use &lt;code&gt;adduser&lt;/code&gt; to create a user named &amp;#8220;deploy&amp;#8221; with homedir &lt;code&gt;/home/deploy&lt;/code&gt;, and then run &lt;code&gt;visudo&lt;/code&gt; to let the &amp;#8220;deploy&amp;#8221; user run commands with &lt;code&gt;sudo&lt;/code&gt;.  Then log in as &amp;#8220;deploy&amp;#8221; and do the rest of this.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Start off with editing &lt;code&gt;/etc/apt/sources.list&lt;/code&gt; to enable some packages:&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;
deb http://se.archive.ubuntu.com/ubuntu/ edgy main restricted
deb-src http://se.archive.ubuntu.com/ubuntu/ edgy main restricted

## Major bug fix updates produced after the final release of the
## distribution.
deb http://se.archive.ubuntu.com/ubuntu/ edgy-updates main restricted
deb-src http://se.archive.ubuntu.com/ubuntu/ edgy-updates main restricted

## Uncomment the following two lines to add software from the 'universe'
## repository.
## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu
## team, and may not be under a free licence. Please satisfy yourself as to
## your rights to use the software. Also, please note that software in
## universe WILL NOT receive any review or updates from the Ubuntu security
## team.
 deb http://se.archive.ubuntu.com/ubuntu/ edgy universe
# deb-src http://se.archive.ubuntu.com/ubuntu/ edgy universe

## Uncomment the following two lines to add software from the 'backports'
## repository.
## N.B. software from this repository may not have been tested as
## extensively as that contained in the main release, although it includes
## newer versions of some applications which may provide useful features.
## Also, please note that software in backports WILL NOT receive any review
## or updates from the Ubuntu security team.
 deb http://se.archive.ubuntu.com/ubuntu/ edgy-backports main restricted universe multiverse
# deb-src http://se.archive.ubuntu.com/ubuntu/ edgy-backports main restricted universe multiverse


deb http://security.ubuntu.com/ubuntu edgy-security main restricted
deb-src http://security.ubuntu.com/ubuntu edgy-security main restricted
# deb http://security.ubuntu.com/ubuntu edgy-security universe
# deb-src http://security.ubuntu.com/ubuntu edgy-security universe
&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;After that, run &lt;code&gt;sudo apt-get update&lt;/code&gt; to get the latest package definitions, and then start installing:&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;Some common tools you will surely need at some point:&lt;/p&gt;
&lt;pre&gt;sudo apt-get install man curl wget
&lt;/pre&gt;
&lt;p&gt;and some dev tools for later compilation steps&lt;/p&gt;
&lt;pre&gt;sudo aptitude install build-essential
&lt;/pre&gt;
&lt;p&gt;Time for ruby:&lt;/p&gt;
&lt;pre&gt;sudo apt-get install ruby ri rdoc irb ri1.8 ruby1.8-dev libzlib-ruby zlib1g
&lt;/pre&gt;
&lt;p&gt;and then postgres:&lt;/p&gt;
&lt;pre&gt;sudo apt-get install postgresql-8.2
sudo apt-get install postgres82-dev
&lt;/pre&gt;
&lt;h3&gt;&lt;a name=&quot;postgres&quot;&gt;Configuring Postgres&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Now we&amp;#8217;ll configure postgres for our purposes.  Creating a role with the same name as the user we&amp;#8217;re running with makes everything a little easier:&lt;/p&gt;
&lt;pre&gt;sudo -u postgres createdb NAME_OF_YOUR_APP_HERE_production
sudo -u postgres createuser -P
Enter name of role to add: deploy
Enter password for new role: 
Enter it again: 
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) y
Shall the new role be allowed to create more new roles? (y/n) n
&lt;/pre&gt;
&lt;p&gt;after that you should be able to do execute &lt;code&gt;psql NAME_OF_YOUR_APP_HERE_production&lt;/code&gt; as the deploy user and get right in.&lt;br /&gt;
&lt;h3&gt;&lt;a name=&quot;pound&quot;&gt;Pound this.&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
&lt;p&gt;One piece of the puzzle that didn&amp;#8217;t quite make it into the &lt;b&gt;&lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt;&lt;/b&gt; moniker is &lt;b&gt;pound&lt;/b&gt;, a handy reverse-&lt;span class=&quot;caps&quot;&gt;DNS&lt;/span&gt; and load-balancer that fronts for our multiple mongrels.  Install it thusly:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sudo apt-get install pound&lt;br /&gt;
sudo vi /etc/default/pound&lt;/pre&gt; &lt;br /&gt;
&lt;p&gt;setting startup=1 in there, and then:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sudo vi /etc/pound/pound.cfg&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;making it something like this:&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;
## Minimal sample pound.cfg
##
## see pound(8) for details


######################################################################
## global options:

User            &quot;www-data&quot;
Group           &quot;www-data&quot;
#RootJail        /chroot/pound

## allow PUT and DELETE also (by default only GET, POST and HEAD)?:
#ExtendedHTTP    0

#WebDAV          0

## Logging: (goes to syslog by default)
##      0       no logging
##      1       normal
##      2       extended
##      3       Apache-style (common log format)
LogLevel        1

## check backend every X secs:
Alive           30

## use hardware-accelleration card supported by openssl(1):
#SSLEngine       &amp;amp;lt;hw&amp;amp;gt;


######################################################################
## listen, redirect and ... to:

## redirect all requests on port 8888 (&quot;ListenHTTP&quot;) to the local webserver see &quot;UrlGroup&quot; below):
#ListenHTTP 127.0.0.1,8080

##
#UrlGroup &quot;.*&quot;
#BackEnd 127.0.0.1,80,1
#EndGroup

ListenHTTP
  Address 0.0.0.0
  Port    80
  Service
    BackEnd
      Address 127.0.0.1
      Port    8000
    End
    BackEnd
      Address 127.0.0.1
      Port    8001
    End
    BackEnd
      Address 127.0.0.1
      Port    8002
    End
    Session
      Type COOKIE
      TTL 900
      ID &quot;_myappname_session_id&quot;
    End
  End
End
&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;That sets us up with pound listening on port 80, transferring the request to one of our three mongrel instances (see Mongrel section).  Note the &lt;code&gt;Session&lt;/code&gt; section, which may help keep things sorted out for some Rails session schemes.&lt;/p&gt;&lt;br /&gt;
&lt;p&gt;Now start pound, like this:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sudo /etc/init.d/pound start&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Try to connect to the site with a browser.  you should get a 503 error, and something like this in /var/log/syslog:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
Mar 15 23:51:31 ubuntu pound: backend 127.0.0.1:8000 connect: Connection refused&lt;br /&gt;
Mar 15 23:51:31 ubuntu pound: backend 127.0.0.1:8001 connect: Connection refused&lt;br /&gt;
Mar 15 23:51:31 ubuntu pound: backend 127.0.0.1:8002 connect: Connection refused&lt;br /&gt;
Mar 15 23:51:31 ubuntu pound: no back-end &amp;#8220;&lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; / &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1&amp;#8221; from 123.123.123.123&lt;br /&gt;
Mar 15 23:51:31 ubuntu pound: no back-end &amp;#8220;&lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; /favicon.ico &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1&amp;#8221; from 123.123.123.123&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;&lt;a name=&quot;Subversion&quot;&gt;Subversion&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
&lt;p&gt;If you want to run subversion on this server, here&amp;#8217;s how to do it.  If you are running subversion elsewhere and don&amp;#8217;t want to move it, skip this section.&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sudo apt-get install subversion xinetd&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Create a user that will own the repositories:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sudo adduser &amp;#8212;system &amp;#8212;no-create-home &amp;#8212;home /var/svn &amp;#8212;group &amp;#8212;disabled-login svn&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Create the directory that will hold the repositories:&lt;/p&gt;&lt;br /&gt;
&lt;pre&gt;sudo mkdir /var/svn&lt;br /&gt;
sudo chown svn:svn /var/svn&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p&gt;Create file &lt;code&gt;/etc/xinetd.d/svnserve&lt;/code&gt; with the following content, to autolaunch svn when it&amp;#8217;s called upon:&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;service svn
{
       port = 3690
       socket_type = stream
       protocol = tcp
       wait = no
       user = svn
       server = /usr/bin/svnserve
       server_args = -i -r /var/svn
}
&lt;/pre&gt;
&lt;p&gt;Restart &lt;b&gt;xinetd&lt;/b&gt; so that svn will work&lt;/p&gt;

&lt;pre&gt;sudo /etc/init.d/xinetd restart
&lt;/pre&gt;
&lt;p&gt;Create a test repository:&lt;/p&gt;

&lt;pre&gt;sudo -u svn svnadmin create /var/svn/testrepo
&lt;/pre&gt;
&lt;p&gt;It should be possible to check out the repository and work on it:&lt;/p&gt;

&lt;pre&gt;svn co svn://localhost/testrepo
&lt;/pre&gt;
&lt;p&gt;Assuming that worked, create the real repository for your project:&lt;/p&gt;

&lt;pre&gt;sudo -u svn svnadmin create /var/svn/myproject
&lt;/pre&gt;
&lt;p&gt;Add a little security:&lt;/p&gt;

&lt;pre&gt;cd /var/svn/myproject/conf
sudo vi svnserve.conf&lt;/pre&gt;
&lt;p&gt;Set up like this:&lt;/p&gt;
&lt;pre&gt;    anon-access = none
    auth-access = write
    password-db = passwd
&lt;/pre&gt;
&lt;p&gt;Create users for your remote username(s), and the local deploy user.  This simplifies login for everyone, and makes it easier to spot changes that were committed from the production server!  &lt;code&gt;sudo vi passwd&lt;/code&gt;, making it look about like this:&lt;/p&gt;
&lt;pre&gt;
    # create a user/pw or two
    joe_user = superseekrit
    deploy = soopersecret
&lt;/pre&gt;
&lt;p&gt;Now try to check out, it should demand a valid username/password:&lt;/p&gt;

&lt;pre&gt;svn co svn://localhost/myproject
&lt;/pre&gt;
&lt;p&gt;Assuming you have an existing repository you&amp;#8217;d like to bring over, go to the old server and do this:&lt;/p&gt;
&lt;pre&gt;svnadmin dump /path/to/repos &amp;amp;gt; my_repos.dump
gzip my_repos.dump
scp my_repos.dump.gz deploy@my_ubuntu_host:/home/deploy
&lt;/pre&gt;
&lt;p&gt;Then, on the new machine:&lt;/p&gt;
&lt;pre&gt;cd /home/deploy
gunzip my_repos.dump.gz
cd /var/svn
sudo -u svn svnadmin load myproject &amp;amp;lt; /home/deploy/my_repos.dump 
&lt;/pre&gt;
&lt;p&gt;Then make sure you can check it out:&lt;/p&gt;
&lt;pre&gt;cd /home/deploy
# delete the myproject directory if it's there, then:
svn co svn://localhost/myproject
&lt;/pre&gt;
&lt;h3&gt;&lt;a name=&quot;wrap&quot;&gt;Wrapping it up&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Finally it&amp;#8217;s time to install rails etc.  I&amp;#8217;ve installed them with rubygems:&lt;/p&gt;

&lt;pre&gt;curl -O http://rubyforge.org/frs/download.php/17190/rubygems-0.9.2.tgz
tar xzf rubygems-0.9.2.tgz ; cd rubygems-0.9.2
sudo ruby setup.rb
sudo gem update
&lt;/pre&gt;
&lt;pre&gt;sudo gem install rails --include-dependencies
sudo gem install postgres-pr
sudo gem install mongrel&lt;/pre&gt;
&lt;p&gt;
&lt;p&gt;(ignore warnings about not being able to compile fastthread stuff, it&amp;#8217;s optional)&lt;/p&gt;
&lt;/p&gt;
&lt;pre&gt;
sudo gem install mongrel_cluster
&lt;/pre&gt;
&lt;p&gt;If you&amp;#8217;re using BackgroundRb, you&amp;#8217;ll want these:&lt;/p&gt;
&lt;pre&gt;sudo gem install slave
sudo gem install daemons
&lt;/pre&gt;
&lt;p&gt;Very soon we&amp;#8217;ll have our app up and running.  Create the database schema:&lt;/p&gt;
&lt;pre&gt;
cd ~/myproject
rake db:schema:load
&lt;/pre&gt;
&lt;p&gt;Configure a little mongrel cluster:&lt;/p&gt;
&lt;pre&gt;
cd ~/myproject
mongrel_rails cluster::configure -p 8000 -N 3
&lt;/pre&gt;
&lt;p&gt;As of this writing (May 2007), there&amp;#8217;s a small bug that will bite you if you&amp;#8217;re using both postgres and BackgroundRb.  This is fixed in edge rails, but not yet in the released version.  If you fall into this category, patch this file, as shown in &lt;code&gt;&amp;lt;a href=&quot;http://dev.rubyonrails.org/attachment/ticket/7727/postgres_async_patch.diff&quot;&amp;gt;http://dev.rubyonrails.org/attachment/ticket/7727/postgres_async_patch.diff&amp;lt;/a&amp;gt;&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;sudo vi /usr/lib/ruby/gems/1.8/gems/activerecord-1.15.2/lib/active_record/connection_adapters/postgresql_adapter.rb 
&lt;/pre&gt;
&lt;p&gt;Make sure you&amp;#8217;re always running in production on this machine by  putting the following line into your .bashrc:&lt;/p&gt;
&lt;pre&gt;export RAILS_ENV=production
&lt;/pre&gt;
&lt;p&gt;If you&amp;#8217;re using BackgroundRb, start the background processes:&lt;/p&gt;
&lt;pre&gt;
cd ~/myproject
script/backgroundrb start
&lt;/pre&gt;
&lt;p&gt;Tail log/backgroundrb.log to make sure it looks OK.  Something like:&lt;/p&gt;
&lt;pre&gt;
	20070316-13:56:35 (12680) Starting WorkerLogger
	20070316-13:56:35 (12681) In ResultsWorker
	...
&lt;/pre&gt;
&lt;p&gt;At long last, start the mongrel cluster:&lt;/p&gt;
&lt;pre&gt;
cd ~/myproject
mongrel_rails cluster::start
&lt;/pre&gt;
&lt;p&gt;At this point you should be able to smack your &lt;span class=&quot;caps&quot;&gt;RUMP&lt;/span&gt; on port 80 and watch it wiggle!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;In no particular order, here are some of the sites where I found information to put this all together:&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://wiki.rubyonrails.org/rails/pages/PostgreSQL/&quot;&gt;http://wiki.rubyonrails.org/rails/pages/PostgreSQL/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://happycodr.com/blog/view/13-putting-a-ruby-on-rails-application-into-production&quot;&gt;http://happycodr.com/blog/view/13-putting-a-ruby-on-rails-application-into-production&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://mongrel.rubyforge.org/docs/pound.html&quot;&gt;http://mongrel.rubyforge.org/docs/pound.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://www.die.net/doc/linux/man/man8/pound.8.html&quot;&gt;http://www.die.net/doc/linux/man/man8/pound.8.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://kurup.org/blog/tag/pound&quot;&gt;http://kurup.org/blog/tag/pound&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://ubuntuguide.org/wiki/Ubuntu_Edgy#How_to_install_Subversion_version_control_server_.28svnserve.29&quot;&gt;http://ubuntuguide.org/wiki/Ubuntu_Edgy#How_to_install_Subversion_version_control_server_.28svnserve.29&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;	&lt;a href=&quot;http://blog.tupleshop.com/2006/7/8/deploying-rails-with-pound-in-front-of-mongrel-lighttpd-and-apache&quot;&gt;http://blog.tupleshop.com/2006/7/8/deploying-rails-with-pound-in-front-of-mongrel-lighttpd-and-apache&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s it, I guess.  I hope this proves helpful to someone.  Feel free to leave feedback in the comments below!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>An Open Letter to Mr. Abibe Yala</title>
   <link href="http://localhost:4000/blog/2007/04/27/an-open-letter-to-mr-abibe-yala/"/>
   <updated>2007-04-27T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/04/27/an-open-letter-to-mr--abibe-yala</id>
   <content type="html">&lt;p&gt;This &amp;#8220;nigeria letter&amp;#8221; (aka &lt;a href=&quot;http://www.urgentmessage.org/highlyconfidential/_l38323.html&quot;&gt;advance fee fraud&lt;/a&gt;) arrived in my inbox today:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From Mr. Abibe Yala&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Dear Friend,&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Very Urgent &amp;amp; Confidential&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
I know you do not know me before, I am Mr. Abibe Yala, younger brother to&lt;br /&gt;
Mr. Kumba Yala the Ex-President of Guinea-Bissau. I got your contact&lt;br /&gt;
information during my private search for a reliable and trustworthy person&lt;br /&gt;
to carry out this urgent transaction with.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
In view of the political crisis happening in my country today, I&lt;br /&gt;
discovered that my brother Mr. Kumba is just trying to impose himself as a&lt;br /&gt;
leader on his people who are not proud and satisfied with his past&lt;br /&gt;
administration.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;b&gt;My brother sent me on a mission&lt;/b&gt; to South Africa to purchase fire arms&lt;br /&gt;
which he intend to use in fighting a political war against his opponent so&lt;br /&gt;
he can become the President again. I am not in support of his intensions&lt;br /&gt;
but I do not have any other options than to do what he asked me. &lt;b&gt;He&lt;br /&gt;
provided the sum of US$22,100,000.00&lt;/b&gt; (Twenty Two Million, One Hundred&lt;br /&gt;
Thousand United States Dollars), which we brought into South Africa&lt;br /&gt;
through diplomatic means. On getting to South Africa, I found out that the&lt;br /&gt;
person (Mr. Jacob Zuma Ex- Vice President of South Africa) whom he&lt;br /&gt;
instructed me to meet for the operation was under government probation for&lt;br /&gt;
related crime and never want to get himself involved in such deals&lt;br /&gt;
anymore. Since I have never been in support of my brother&amp;#8217;s intentions, I&lt;br /&gt;
made up my mind never to go back to my country (Guinea-Bissau). &lt;b&gt;I want to&lt;br /&gt;
relocate&lt;/b&gt; immediately to a better country especially in the Europe or Asia,&lt;br /&gt;
&lt;b&gt;where I can have good investment with this money&lt;/b&gt; since I cannot stay here&lt;br /&gt;
in Africa.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
My reason of contacting you is that, I want you to support me as my&lt;br /&gt;
foreign partner to move the funds and myself out of Africa as soon as&lt;br /&gt;
possible. Presently, the funds are deposited as consignment with a&lt;br /&gt;
depository company in Johannesburg South Africa for safekeeping. Why I am&lt;br /&gt;
presently residing in West Africa for security reasons. I am willing to&lt;br /&gt;
offer you 40% of the whole money for the inconveniences this will cost you&lt;br /&gt;
and for your support in this transaction, while the remaining 60% will be&lt;br /&gt;
for me to setup a profitable investment in your country through your&lt;br /&gt;
guidance and directions.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
As a matter of urgency, please do let me know if you can assist me in&lt;br /&gt;
handling this transaction and the investment involve.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
I anticipate your quick response.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Best Regards.&lt;br /&gt;
Mr. Abibe Yala&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The funny thing about this is how the story he tells to gain our sympathies is basically about how he wants to steal his brother&amp;#8217;s money and move to Europe. (See the bold bits above)  Nice guy!  Here&amp;#8217;s my response:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;OK, I&amp;#8217;m not stupid, I recognize a so-called &amp;#8220;Nigeria letter&amp;#8221; when I see one.  You&amp;#8217;re obviously a con-man, and if that&amp;#8217;s what works for you, fine.  I just hope you don&amp;#8217;t hurt anybody.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
But anyway:  You really need to work on your story.  The way you describe it, it sounds like you&amp;#8217;re basically trying to steal $22 million from your brother.  It makes you sound like a thief.  Even with the part about your brother trying to become a dictator, etc.  He&amp;#8217;s supposed to be your &lt;span class=&quot;caps&quot;&gt;BROTHER&lt;/span&gt; for god&amp;#8217;s sake.  He &lt;span class=&quot;caps&quot;&gt;TRUSTED&lt;/span&gt; you with the money, right?  And you respond with &lt;span class=&quot;caps&quot;&gt;BETRAYAL&lt;/span&gt;?  No one will sympathize with you about that.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Instead, you need to first make it seem that HE betrayed &lt;span class=&quot;caps&quot;&gt;YOU&lt;/span&gt;.  Say that your brother decided to kill you, and you&amp;#8217;re fleeing from his paramilitary death squads.  Then maybe someone will say, &amp;#8220;Wow, that poor Mr Yala, he needs my help&amp;#8221;.  With the story you sent me, anyone too stupid too realize you&amp;#8217;re a con-man will probably just think, &amp;#8220;This Abibe seems like a real asshole, trying to steal his brother&amp;#8217;s money&amp;#8221;.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&amp;#8212; &lt;br /&gt;
// jack&lt;br /&gt;
// http://www.nuthole.com&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content>
 </entry>
 
 <entry>
   <title>RoR etc</title>
   <link href="http://localhost:4000/blog/2007/04/19/ror-etc/"/>
   <updated>2007-04-19T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2007/04/19/ror-etc</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;OK, i haven&amp;#8217;t posted in ages, but what can I say, life is keeping me busy.  Recovering from a bit of minor surgery, followed by a long Easter break, followed by stomach flu, consumed the past few weeks.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;But, more importantly than all that, I changed jobs at the end of January, and am now spending most of my work time (not to mention free time) programming with &lt;a href=&quot;http://www.rubyonrails.org&quot;&gt;Ruby on Rails&lt;/a&gt;!&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Ah, ruby.  I&amp;#8217;ve used python for a variety of side projects over the past few years, and I&amp;#8217;ve long held the opinion that the two languages are largely equal, but in the short time since I started using ruby full-time, I&amp;#8217;ll admit that I&amp;#8217;ve started acquiring a definite ruby bias.  Things like ruby&amp;#8217;s &lt;a href=&quot;http://weblog.jamisbuck.org/2007/1/19/blocks-rock&quot;&gt;block syntax&lt;/a&gt;, for instance, don&amp;#8217;t really have a corresponding language feature in python (at least, not anything quite as succinct).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Above all though, I&amp;#8217;m mainly happy to be back in the world of dynamic languages.  At my last job, I spent two years using C++, which taught me a lot:  mainly that &lt;a href=&quot;http://www.nuthole.com/compute/programming/jack.expressiveness.comments&quot;&gt;I don&amp;#8217;t like C++&lt;/a&gt;.  In fact, I&amp;#8217;ve started to get the feeling that using C++ at all, when other options are available, is in many cases a textbook example of premature optimization.  You end up consuming lots more programmer-hours (which means greater expense, and later releases) chasing the chimera of an end-product which &amp;#8220;runs faster&amp;#8221; than a similar program written in a dynamic language would run.  I put &amp;#8220;runs faster&amp;#8221; in quotes because in reality, most software is I/O-bound most of the time (either waiting for user input, or waiting for disk or network traffic), so the amount of time that your particular program is actually &lt;i&gt;running&lt;/i&gt; is probably pretty small (and getting smaller as &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; speeds increase), no matter what language it&amp;#8217;s written in.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Notes from mirror-world</title>
   <link href="http://localhost:4000/blog/2007/02/07/notes-from-mirror-world/"/>
   <updated>2007-02-07T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2007/02/07/notes-from-mirror-world</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;In London on business this week, first time in England.  Here are some observations:&lt;/p&gt;
&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;This whole cars-driving-on-the-wrong-side-of-the-road thing is really disconcerting.  I thought it would be easy to deal with!  Notions about traffic, and which way cars will be coming from, seem to be more ingrained than I thought.&lt;/li&gt;
	&lt;li&gt;Hyde Park is &lt;b&gt;really&lt;/b&gt; bloody dark at night.  And the gates are closed.  I believe these two facts are related.&lt;/li&gt;
	&lt;li&gt;England has some great chips (which I&amp;#8217;ll not yet call &amp;#8216;crisps&amp;#8217;), such as the &amp;#8220;Walkers Sensations Vintage Cheddar &amp;amp; Red Onion Chutney flavour crisps&amp;#8221; I&amp;#8217;m eating right now.&lt;/li&gt;
	&lt;li&gt;My fellow Americans are just as conspicuous in England as they are in Sweden, with the loud talking and whatnot.&lt;/li&gt;
	&lt;li&gt;I feel nervous sitting in a pub by myself for any length of time, for fear of being that conspicuous.  I keep to myself, consume my consumables, and leave quickly.&lt;/li&gt;
	&lt;li&gt;Shops are open until 7! or 8!  Marvellous! &lt;i&gt;(&amp;lt;- note olde englyshe spelling)&lt;/i&gt;&lt;/li&gt;
	&lt;li&gt;It&amp;#8217;s tempting, when I see the small numbers (compared to Swedish currency) on price-tags in shops, to think I&amp;#8217;m looking at dollar amounts.  If only.&lt;/li&gt;
	&lt;li&gt;English taxis are much bigger on the inside than you&amp;#8217;d think just by looking at them.  I think this is the true origin of the Tardis.&lt;/li&gt;
	&lt;li&gt;Whoever&amp;#8217;s doing up my hotel room wants me cold.  Last night before going to bed it was just 20 degrees C in here.  I cranked it up to 23 but was cold all night.  Coming back from work today, I found that the heat was off, the window was open, and it was down to 16.  Brrr.&lt;/li&gt;
	&lt;li&gt;The curse of &amp;#8220;reality TV&amp;#8221; seems to afflict England at least as much as Sweden.  Based on casual channel-flipping a few times the past few nights, it seems like at least 2 of the 5 channels on the hotel TV are showing some sort of &amp;#8220;reality TV&amp;#8221; at any given time.&lt;/li&gt;
	&lt;li&gt;A surprising number of bathroom sinks here feature double faucets, one for hot and one for cold.  This invariably leads to comically waving hands back and forth, Mr-Bean-style, to get the right mix of temperatures.&lt;/li&gt;
	&lt;li&gt;I miss my family.  This is the first time I&amp;#8217;ve been away from my kids longer than, say, a long workday followed by an evening out!  Dang.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>nothing about the iPhone</title>
   <link href="http://localhost:4000/blog/2007/01/11/nothing-about-the-iphone/"/>
   <updated>2007-01-11T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2007/01/11/nothing-about-the-iphone</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;I&amp;#8217;m going to resist the urge to blog about the iPhone by instead blogging about a man named &lt;a href=&quot;http://www.jonathancoulton.com&quot;&gt;Jonathan Coulton&lt;/a&gt;, who could just as well be me in an alternate universe.  Jonathan has a burgeoning career as an internet troubadour going on, with an impressive online &lt;a href=&quot;http://www.jonathancoulton.com/songs&quot;&gt;song catalog&lt;/a&gt;, most of which turned up during a one-year period from September 2005 to September 2006, in which time he recorded a song a week, every week.  Some people sure do have spare time!&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;I just heard about &lt;b&gt;JoCo&lt;/b&gt; (as his fans call him) from my old friend and collaborator &lt;a href=&quot;http://apps.carleton.edu/curricular/ling/alumni/paulhagstrom/&quot;&gt;Paul Hagstrom&lt;/a&gt; about a week ago, and I have to tell you that the nuthole household has been revolutionized by the power of JoCo&amp;#8217;s music.  Finally, music that both my children, my wife, and I all think is entertaining, catchy, and rewarding to listen to!  JoCo&amp;#8217;s songs wander across all sorts of genres, and many of them are obvious homages to one well-known group or another;  most of them are also very, very funny.  Some of my personal faves:&lt;/p&gt;&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/code-monkey&quot;&gt;Code Monkey&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/tom-cruise-crazy&quot;&gt;Tom Cruise Crazy&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/soft-rocked-by-me&quot;&gt;Soft Rocked By Me&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/curl&quot;&gt;Curl&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/chiron-beta-prime&quot;&gt;Chiron Beta Prime&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/shop-vac&quot;&gt;Shop Vac&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/the-town-crotch&quot;&gt;The Town Crotch&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/skullcrusher-mountain&quot;&gt;Skullcrusher Mountain&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/ikea&quot;&gt;Ikea&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/millionaire-girlfriend&quot;&gt;Millionaire Girlfriend&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/first-of-may&quot;&gt;First of May&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jonathancoulton.com/lyrics/a-laptop-like-you-demo&quot;&gt;A Laptop Like You&lt;/a&gt;&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;p&gt;And those are just the best 50% or so of what I&amp;#8217;ve listened to &lt;b&gt;SO &lt;span class=&quot;caps&quot;&gt;FAR&lt;/span&gt;&lt;/b&gt;!  I&amp;#8217;m sure by the time I&amp;#8217;ve listened to all the songs, I&amp;#8217;ll have over 30 &amp;#8220;faves&amp;#8221;.  Oh well.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So, why do I think that JoCo is actually an alternate version of myself?  For one thing, similar dashing good looks:&lt;/p&gt;
&lt;/p&gt;
&lt;center&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/img/JaNu_bw.png&quot; alt=&quot;janu&quot; /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&amp;lt;=&amp;gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/img/JoCo_bw.png&quot; alt=&quot;joco&quot; /&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td colspan=&quot;3&quot; align=&quot;center&quot;&gt;
&lt;p&gt;&lt;i&gt;separated at birth?&lt;/i&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p&gt;Then, there are the startling similarities in our musical histories.  A little background info is in order.  Consider this narrative, &lt;del&gt;which I did not write but&lt;/del&gt; which pretty well describes a chunk of my teen years:&lt;/p&gt;
&lt;blockquote&gt; I played quad drums in the high school marching band, which was fun, but did not attract any girls (even when I played my tender quad arrangement of &amp;#8220;Flight of the Bumblebee&amp;#8221;). I switched to guitar and wrote a series of sweet and sad songs about being a teenager and having a vague feeling of overwhelming sadness and sweetness. This worked only marginally better.&lt;/blockquote&gt;
&lt;p&gt;
&lt;p&gt;Now consider this direct quote from Jonathan&amp;#8217;s bio page:&lt;/p&gt;
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I played snare drum in the high school marching band, which was fun, but did not attract any girls (even when I played my tender snare drum arrangement of &amp;#8220;You&amp;#8217;ve Got a Friend&amp;#8221;). I switched to guitar and wrote a series of sweet and sad songs about being a teenager and having a vague feeling of overwhelming sadness and sweetness. This worked only marginally better.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;p&gt;The discerning reader may notice a number of similarities between these two life stories.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;In any case, I hereby declare Jonathon Coulton an honorary &lt;b&gt;Nuthole Boltmaster&lt;/b&gt; (the first ever!) and send the rest of you off on your way to &lt;a href=&quot;http://www.jonathancoulton.com/donations&quot;&gt;pay tribute&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;i&gt;OK, obligatory bloggage about yesterday&amp;#8217;s big product announcement.  I&amp;#8217;ll just say that iWant an iPhone.  That&amp;#8217;s all I have to say about that for now.&lt;/i&gt;&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Darksided: The Clarification</title>
   <link href="http://localhost:4000/blog/2006/10/21/darksided-the-clarification/"/>
   <updated>2006-10-21T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/10/21/darksided--the-clarification</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Some people, upon hearing &lt;a href=&quot;jack.darksided.html&quot;&gt;Darksided&lt;/a&gt;, wonder what the hell the lyrics are all about, and who the crazy screaming woman is.  Though it&amp;#8217;s already mentioned on the &lt;a href=&quot;http://www.bandofnone.com&quot;&gt;Band of None website&lt;/a&gt;, for the sake of completion here I&amp;#8217;ll tell you to &lt;a href=&quot;http://alexk.imeem.com/video/E5z8fTM_/trading_spouces_margret/&quot;&gt;go here&lt;/a&gt; for a full exposition.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Band of None - Darksided</title>
   <link href="http://localhost:4000/blog/2006/10/15/band-of-none-darksided/"/>
   <updated>2006-10-15T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/10/15/band-of-none---darksided</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;To my continual surprise, I find that I&amp;#8217;m involved in the first teetering baby-steps of a new band.  Early days, but we do have a name (&amp;#8220;Band of None&amp;#8221;), a &lt;a href=&quot;http://www.bandofnone.com&quot;&gt;website&lt;/a&gt;, and a first single: &amp;#8220;Darksided&amp;#8221;.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;object type=&quot;application/x-shockwave-flash&quot; data=&quot;http://www.bandofnone.com/player.swf&quot; width=&quot;290&quot; height=&quot;24&quot; id=&quot;audioplayer8&quot;&gt;&lt;br /&gt;  &lt;param name=&quot;movie&quot; value=&quot;http://www.bandofnone.com/player.swf&quot; /&gt;  &lt;param name=&quot;FlashVars&quot; value=&quot;soundFile=http://www.bandofnone.com/Darksided.mp3&quot; /&gt;&lt;br /&gt;  &lt;param name=&quot;quality&quot; value=&quot;high&quot; /&gt;  &lt;param name=&quot;menu&quot; value=&quot;false&quot; /&gt;&lt;br /&gt;  &lt;param name=&quot;wmode&quot; value=&quot;transparent&quot; /&gt;&lt;br /&gt;&lt;/object&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;I don&amp;#8217;t know how to categorize our music so far.  Industrial?  Techno?  Rock?   Somewhere around there.  Please poke around &lt;a href=&quot;http://www.bandofnone.com&quot;&gt;the website&lt;/a&gt;, have a listen, and let us know what you think.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&lt;b&gt;[&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;: added inline music player]&lt;/b&gt;&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>is that a mod in your pocket?</title>
   <link href="http://localhost:4000/blog/2006/10/03/is-that-a-mod-in-your-pocket/"/>
   <updated>2006-10-03T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/10/03/is-that-a-mod-in-your-pocket-</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;I used to be a big &lt;a href=&quot;http://www.palm.com&quot;&gt;Palm&lt;/a&gt; user, keeping all my contacts and calendars in sync between my desktop machine and my handheld.  Over the years though, I&amp;#8217;ve switched almost exclusively to using a laptop instead of a desktop machine, and always have a bluetooth cellphone with all my contacts in my pocket.  The final nail in my Palm&amp;#8217;s coffin, though, was &lt;a href=&quot;/compute/jack.iskinduo.html&quot;&gt;getting an iPod&lt;/a&gt; which took over the last regular use I had for my Palm (&lt;a href=&quot;http://www.chocopoolp.com/bj_index.php&quot;&gt;Bhajis Loops&lt;/a&gt; notwithstanding).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So now that I&amp;#8217;ve got no Palm in my pocket, I&amp;#8217;ve got a new problem.  What do I do if I want to just jot down a name, phone number, or &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; when I&amp;#8217;m on the go?  Use my cellphone keypad?  Eek. Thanks to a tip from &lt;a href=&quot;http://www.toolshed.com/blog/&quot;&gt;Andy Hunt&lt;/a&gt;, I&amp;#8217;ve found an excellent technology:  Paper!  &lt;a href=&quot;http://www.pocketmod.com&quot;&gt;PocketMod&lt;/a&gt; lets you create your own personal folded notepad/calendar/whatever to carry in your pocket.  Just pick what you want  to have on your pages, and print.  An online guide shows you how to fold and cut the paper, and off you go.  Normally I never carry a pen or pencil around, but since I started using PocketMods, keeping one in the same place at home where I keep my wallet and keys, I can&amp;#8217;t help but stick it in my pocket along with a pencil in the morning.  Now I can once again capture those important yet fleeting ideas that will surely lead to fame and fortune.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>building a playhouse</title>
   <link href="http://localhost:4000/blog/2006/08/27/building-a-playhouse/"/>
   <updated>2006-08-27T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/08/27/building-a-playhouse</id>
   <content type="html">&lt;div class='tabblo'&gt;
&lt;p&gt;&lt;a href='http://app.tabblo.com/studio/stories/view/103116/'&gt;&lt;br /&gt;
&lt;img hspace='5' vspace='5' align='right' src='http://app.tabblo.com/studio/image/public/19560/2b37fa55af53d6e89e90f71346e0d308.png' alt='Tabblo: the playhouse' height='410' width='207.5'/&gt;&lt;br /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p /&gt;
&lt;p&gt;Together with my father-in-law, we built a playhouse this summer!  Instead of just dumping the pictures into a ready-formatted .mac page template or something, I decided to share them using &lt;a href=&quot;http://www.tabblo.com&quot;&gt;Tabblo&lt;/a&gt;.   Click the thumbnail image to the right to get to all the pictures.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
All in all, this new &lt;a href=&quot;http://www.tabblo.com&quot;&gt;Tabblo&lt;/a&gt; service is pretty cool.  You can upload a bunch of pictures, create a nice layout of your own design (including text boxes of varying sizes), and Tabblo provides slideshows, downloads of the original fullsize images, etc.  And of course it&amp;#8217;s free!&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>pythong</title>
   <link href="http://localhost:4000/blog/2006/08/17/pythong/"/>
   <updated>2006-08-17T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/08/17/pythong</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I think I can safely call myself a &amp;#8220;&amp;#8221;http://www.python.org&amp;quot;&amp;gt;python&lt;/a&gt; programmer&amp;quot;.  And a &amp;#8220;touch typist&amp;#8221;.  And a &amp;#8220;good speller&amp;#8221;.  And yet, hardly a day goes by that I don&amp;#8217;t mistype &amp;#8220;python&amp;#8221; as &amp;#8220;pythong&amp;#8221;.  I nearly did it while typing that sentence.  I don&amp;#8217;t know why, it&amp;#8217;s just the way it is.  At least I can console myself with the knowledge that &lt;a href=&quot;http://www.pythong.org&quot;&gt;I&amp;#8217;m not alone&lt;/a&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now I&amp;#8217;ve decided to capitalize on this shortcoming with a novelty product that will surely make me rich.  Behold, &lt;a href=&quot;http://www.cafepress.com/nuthole.70630906&quot;&gt;the PyThong&lt;/a&gt;!!!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;img src=&quot;http://www.nuthole.com/img/PyThongPic.png&quot; alt=&quot;the pythong&quot; border=&quot;0&quot; align=&quot;right&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Please buy several for yourself and everyone you know.  Christmas is just around the corner!  Who wouldn&amp;#8217;t want a PyThong in their stocking?!  This is also, of course, the perfect attire for the next &lt;a href=&quot;http://www.python.org/pycon/&quot;&gt;pycon&lt;/a&gt; or &lt;a href=&quot;http://www.europython.org/&quot;&gt;EuroPython&lt;/a&gt; conference.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>three cheers for the curmudgeon!</title>
   <link href="http://localhost:4000/blog/2006/08/10/three-cheers-for-the-curmudgeon/"/>
   <updated>2006-08-10T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/08/10/three-cheers-for-the-curmudgeon-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;As a child, I was often puzzled by the existence of some really lame comic strips in the newspapers.  I could not for the life of me imagine why anyone would want to read strips like &lt;a href=&quot;http://chicagosports.chicagotribune.com/sports/custom/gilthorp/&quot;&gt;Gil Thorp&lt;/a&gt;, &lt;a href=&quot;http://www.kingfeatures.com/features/comics/rmorgan/about.htm&quot;&gt;Rex Morgan M.D.&lt;/a&gt;, or &lt;a href=&quot;http://www.kingfeatures.com/features/comics/mworth/about.htm&quot;&gt;Mary Worth&lt;/a&gt;.  Compared to the comics I loved best at the time, such as &lt;a href=&quot;http://en.wikipedia.org/wiki/Bloom_County&quot;&gt;Bloom County&lt;/a&gt; and (yes, I&amp;#8217;m man enough to admit it) &lt;a href=&quot;http://www.garfield.com/&quot;&gt;Garfield&lt;/a&gt;, these print versions of soap operas just seemed completely useless.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now I know the ultimate purpose of these comics:  to be bitterly, hilariously mocked by &lt;a href=&quot;http://joshreads.com/&quot;&gt;The Comics Curmudgeon&lt;/a&gt;.  This site not only pokes fun at the soap-opera-style comics mentioned above, it also highlights &lt;a href=&quot;http://joshreads.com/?p=697&quot;&gt;foolishness in Mark Trail&lt;/a&gt;, &lt;a href=&quot;http://joshreads.com/?p=680&quot;&gt;timeless stereotypes in Crock&lt;/a&gt;, and &lt;a href=&quot;http://joshreads.com/?p=657&quot;&gt;fearful grandparenting in Gasoline Alley&lt;/a&gt;.  Go get your Josh on.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>fram och tillbaka</title>
   <link href="http://localhost:4000/blog/2006/06/21/fram-och-tillbaka/"/>
   <updated>2006-06-21T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/06/21/fram-och-tillbaka</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Last weekend, I took part in a film-making project sponsored by &lt;a href=&quot;http://www.stockholms.lans.museum/&quot;&gt;Stockholms L&amp;auml;ns Museum&lt;/a&gt; and &lt;a href=&quot;http://www.filmstockholm.se/&quot;&gt;Film Stockholm&lt;/a&gt;.  Here&amp;#8217;s what I made.  The voiceover is in Swedish, though I may do an English version later as well.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;&lt;embed style=&quot;width:400px; height:326px;&quot; id=&quot;VideoPlayback&quot; align=&quot;middle&quot; type=&quot;application/x-shockwave-flash&quot; src=&quot;http://video.google.com/googleplayer.swf?docId=3779784757751255677&quot; allowScriptAccess=&quot;sameDomain&quot; quality=&quot;best&quot; bgcolor=&quot;#ffffff&quot; scale=&quot;noScale&quot; salign=&quot;TL&quot;  FlashVars=&quot;playerMode=embedded&quot;&gt; &lt;/embed&gt;&lt;br /&gt;
&lt;p /&gt;The idea behind the project is to have 100 people living in Stockholm create a digital story about some aspect of their lives.  The project is executed entirely on Macs running &lt;a href=&quot;http://www.apple.com/ilife/imovie&quot;&gt;iMovie&lt;/a&gt;.  I&amp;#8217;ve used iMovie plenty in the past, but this is the first time I&amp;#8217;ve so heavily abused the &lt;a href=&quot;http://en.wikipedia.org/wiki/Ken_Burns&quot;&gt;Ken Burns effect&lt;/a&gt;!  See more about the project, and watch other participants&amp;#8217; creations, at &lt;a href=&quot;http://www.hundrahistorier.se&quot;&gt;www.hundrahistorier.se&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>huge volumes of pointless syntax</title>
   <link href="http://localhost:4000/blog/2006/06/13/huge-volumes-of-pointless-syntax/"/>
   <updated>2006-06-13T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/06/13/huge-volumes-of-pointless-syntax</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;It&amp;#8217;s high time for the next installment in my irregular series of C++ rants.  This time I&amp;#8217;m going to talk about expressiveness (or rather, C++&amp;#8217;s lack thereof)&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Expressiveness indicates a capability to accurately and briefly express something.  A human being is considered to be expressive if they are able to speak in such a way that someone listening to them can quickly understand the person&amp;#8217;s message.  A computer language&amp;#8217;s expressiveness is a measure of how quickly a programmer can write code that is unambiguous and a correct reflection of the design in the programmer&amp;#8217;s mind.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Let&amp;#8217;s illustrate this with an example.  Imagine we&amp;#8217;ve got a class with an instance variable containing an array (or list, or vector, or what have you) of some other type.  We want to give our class a method that takes another array, iterates through all the objects in it, and adds them to its own array.  Obviously this is a contrived example, since nearly all container classes in all languages must include functionality for adding the contents of one array to another, but the point here is to demonstrate how a simple iteration is done.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Let&amp;#8217;s start off with the C++ version, something like this:&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;
class ValueContainer
{
    // a vector containing Value objects
    std::vector&amp;amp;lt;boost::shared_ptr&amp;amp;lt;Value&amp;amp;gt; &amp;amp;gt; m_values;&lt;/p&gt;
void addValues(std::vector&amp;lt;boost::shared_ptr&amp;lt;Value&amp;gt; &amp;gt;values)
{
// an iterator pointing at the first value
std::vector&amp;lt;boost::shared_ptr&amp;lt;Value&amp;gt; &amp;gt;::const_iterator it = values.begin();
// an iterator pointing at the special &amp;#8220;end&amp;#8221; value indicating we&amp;#8217;ve reached the end
std::vector&amp;lt;boost::shared_ptr&amp;lt;Value&amp;gt; &amp;gt;::const_iterator endIt = values.end();
// step through the entire array
for (; it != endIt; ++it)
{
// add the value to our array
m_values.push_back(*it);
}
}
&lt;p&gt;};&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Some of you may be unfamiliar with the &lt;code&gt;boost::shared_ptr&lt;/code&gt; stuff in there.  The boost project is a sort of proving ground for classes that are probably destined for the standard c++ library in the future, and shared pointers are a very valuable concept that make c++ development a little more do-able, by helping you manage object ownership.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Anyway, that&amp;#8217;s quite a pile of code, isn&amp;#8217;t it?  All we&amp;#8217;re doing is walking through a list of things!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Some may balk at this, saying that the boost shared pointers are overkill here.  OK, fine, let&amp;#8217;s take those away, and take away the comments, and stuff all we can into the &lt;code&gt;for&lt;/code&gt;, getting this down as tight as we can:&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;
class ValueContainer
{
    std::vector&amp;amp;lt;Value&amp;amp;gt; m_values;&lt;/p&gt;
void addValues(std::vector&amp;lt;Value&amp;gt; values)
{
for (std::vector&amp;lt;Value &amp;gt;::const_iterator it = values.begin(); it != values.end(); ++it)
{
m_values.push_back(*it);
}
}
&lt;p&gt;};&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now let&amp;#8217;s see how a similar class might look in python:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
class ValueContainer:
    def __init__(self):
        self.values = []&lt;/p&gt;
def addValues(self, values):
for v in values:
self.values.append(v)
&lt;p&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Unlike C++, Python has no free-standing declarations of instance variables&amp;#8212;they&amp;#8217;re defined only as they&amp;#8217;re referenced inside of methods, and the best practice is typically to provide an initial definition inside the initilializer method &lt;code&gt;__init__&lt;/code&gt; as I&amp;#8217;ve done here.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
There are several nice things about Python that this highlights:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt; the syntactic indicator that we&amp;#8217;re dealing with an instance variable by always prepending &lt;code&gt;self.&lt;/code&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; the more sensible method names in Python&amp;#8217;s array class compared to C++&amp;#8217;s std::vector class (&lt;code&gt;append&lt;/code&gt; vs &lt;code&gt;push_back&lt;/code&gt;)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; the &lt;code&gt;values&lt;/code&gt; parameter isn&amp;#8217;t statically typed, so it doesn&amp;#8217;t need to actually be a standard python array, but can be any class that implements the methods required for iteration&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;but the big win I want to point out here is really the difference in the &lt;code&gt;for&lt;/code&gt; constructs.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Look at the mass of ugliness in the C++ &lt;code&gt;for&lt;/code&gt; construct.    To start off with, you&amp;#8217;re forced to declare a variable with a bizarre &lt;code&gt;iterator&lt;/code&gt; type.  Why should I have to care about that?  I&amp;#8217;m not using it in any way; that type is completely irrelevant to my code.  Later, to iterate I have to use &lt;code&gt;it++&lt;/code&gt;, which may not be pointer arithmetic, but at least &lt;b&gt;looks&lt;/b&gt; like pointer arithmetic, and that is just &lt;b&gt;so&lt;/b&gt; 1985.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Then, take a look at the simplicity of the Python &lt;code&gt;for&lt;/code&gt; construct.  The designers of Python built iteration right into the language!  You simply give &lt;code&gt;for&lt;/code&gt; the name of the variable that should be used to hold a value from the array, and the array itself, and off it goes.  Behind the scenes, iteration occurs through well-defined methods, and if you&amp;#8217;re making your own collection class you can define your own iteration scheme, but all of that is completely invisible to a user of the class.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;span class=&quot;caps&quot;&gt;IMHO&lt;/span&gt;, this sort of thing is really one of the biggest wins for languages like Python.  You get to leave out all sorts of meaningless busy-work, since the language includes useful mechanisms that C-based languages don&amp;#8217;t, and you are left with the job of programming the actual functionality you&amp;#8217;re after.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Steven Colbert goes to Washington - and kills it</title>
   <link href="http://localhost:4000/blog/2006/05/02/steven-colbert-goes-to-washington-and-kills-it/"/>
   <updated>2006-05-02T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/05/02/steven-colbert-goes-to-washington---and-kills-it</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;This has already been linked-to all over the place, but anyone who already hasn&amp;#8217;t should go check out Steven Colbert&amp;#8217;s speech (especially parts &lt;a href=&quot;http://www.youtube.com/watch?v=jbeDu_JEd2A&amp;search=colbert%20correspondents%20dinner&quot;&gt;one&lt;/a&gt; and &lt;a href=&quot;http://www.youtube.com/watch?v=h4Y9fO2TpYg&amp;search=colbert%20correspondents%20dinner&quot;&gt;two&lt;/a&gt;;  I thought &lt;a href=&quot;http://www.youtube.com/watch?v=vtkLY-S-6Bs&amp;search=colbert%20correspondents%20dinner&quot;&gt; part three&lt;/a&gt; kind of fell flat) from the White House Corresponts&amp;#8217; Dinner held last weekend.  It takes some serious balls to stand there, just a few feet away from ol&amp;#8217; monkey-boy, and lower him a notch or ten like that.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Horror of Compile-Time Binding</title>
   <link href="http://localhost:4000/blog/2006/04/11/the-horror-of-compile-time-binding/"/>
   <updated>2006-04-11T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/04/11/the-horror-of-compile-time-binding</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I&amp;#8217;m working on this C++ project, and suddenly realize how much we&amp;#8217;re using the &lt;a href=&quot;http://en.wikipedia.org/wiki/Visitor_pattern&quot;&gt;visitor pattern&lt;/a&gt;.  The point of the visitor pattern is to extract non-core functionality out of data-bearing classes, instead gathering that functionality into a visitor class that knows how to operate on all the data-bearing classes.  You do this by making each &amp;#8220;visitable&amp;#8221; class implement a method that accepts a visitor object, which in turn calls a method in the visitor to do its work, along these lines:&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;
void MyClass::accept(Visitor &amp;amp;v)
{
    v.visitMyClass(this);
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
That way, new visitors can be created to implement new functionality involving visitable classes, without the visitable classes needing to be changed or even recompiled. Here&amp;#8217;s where the fun kicks in.  For each new &amp;#8220;visitable&amp;#8221; class I add, I need to add a member function for each existing visitor, which means editing dozens of .h and .cpp files, adding a small &amp;#8220;visitXXX&amp;#8221; member function to each.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The kicker is that most of the functionality we&amp;#8217;re implementing with visitors consists of either trivial one-liners or empty implementations for most of the visitable types.  So we have visitor classes containing dozens of identical member functions.  Nothing quite like the joy of editing dozens of files to insert meaningless boilerplate code!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
At first I wondered what my co-workers were thinking when they set out on this path, but eventually I came to realize, much to my chagrin, that this is an inescapable reality of C++ programming in many situtations, thanks to the compile-time binding that C++ does.  The compile-time binding actually precludes you from doing certain things without this sort of indirection.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
To see why this is, first consider an example that demonstrates how things &lt;em&gt;can&lt;/em&gt; work in a more full-featured OO language, such as python.  Consider the following python program:&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;
class A:
    def emit(self):
        print &quot;Class A&quot;&lt;/p&gt;
&lt;p&gt;class B (A):&lt;br /&gt;
    def emit(self):&lt;br /&gt;
        print &amp;#8220;Class B&amp;#8221;&lt;/p&gt;
&lt;p&gt;a = A()&lt;br /&gt;
b = B()&lt;br /&gt;
a.emit()&lt;br /&gt;
b.emit()&lt;br /&gt;
print &amp;#8220;&lt;del&gt;-&lt;/del&gt;&amp;#8212;&amp;#8221;&lt;br /&gt;
objects = [a, b]&lt;br /&gt;
objects&lt;sup class=&quot;footnote&quot; id=&quot;fnr0&quot;&gt;&lt;a href=&quot;#fn0&quot;&gt;0&lt;/a&gt;&lt;/sup&gt;.emit()&lt;br /&gt;
objects&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.emit()&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
This code snippet defines and manipulates a simple class hierarchy, with B inheriting from A.  Common sense tells you what the output of this program may be:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
Class A&lt;br /&gt;
Class B&lt;br /&gt;
&lt;del&gt;-&lt;/del&gt;&amp;#8212;&lt;br /&gt;
Class A&lt;br /&gt;
Class B&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
And your common sense would be right.  Whe calling the &lt;em&gt;emit&lt;/em&gt; method on the &lt;em&gt;a&lt;/em&gt; and &lt;em&gt;b&lt;/em&gt; objects, the correct method is triggered and the corresponding class names are output.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now then, considering the following C++ program:&lt;br /&gt;
&lt;pre&gt;&lt;code class=&quot;cpp&quot;&gt;
#include &amp;lt;iostream&amp;gt;
class A
{
public:
    virtual void emit() {
        std::cout &amp;lt;&amp;lt; &quot;Class A\n&quot;;
    }
};
class B : public A
{
public:
    virtual void emit() {
        std::cout &amp;lt;&amp;lt; &quot;Class B\n&quot;;
    }
};
int main (int argc, char * const argv[]) {
    A a;
    B b;
    a.emit();
    b.emit();
    std::cout &amp;lt;&amp;lt; &quot;-----\n&quot;;
    A objects[] = {a, b};
    objects[0].emit();
    objects[1].emit();&lt;/p&gt;
return 0;
&lt;p&gt;}&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Does your common sense tell you this program should have the same output as the earlier python version?  Think again:&lt;br /&gt;
&lt;pre&gt;&lt;br /&gt;
Class A&lt;br /&gt;
Class B&lt;br /&gt;
&lt;del&gt;-&lt;/del&gt;&amp;#8212;&lt;br /&gt;
Class A&lt;br /&gt;
Class A&lt;br /&gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Say what?  &amp;#8220;But, but, but, I put an instance of &lt;b&gt;B&lt;/b&gt; in that array, wtf?&amp;#8221;  Well, here&amp;#8217;s where C++&amp;#8217;s compile-time binding came and shot you in the foot.  Note that C++ doesn&amp;#8217;t offer any sort of generic array of objects.  Whether using a C array as I&amp;#8217;ve done, or a std::vector object, you must indicate the type of the object, in this case the root of our hierarchy, &lt;b&gt;A&lt;/b&gt;.  C++ then makes use of this type information when your program is compiled to match up the call to &lt;em&gt;emit&lt;/em&gt; with the implementation in the named class, rather than the implementation in the derived class you&amp;#8217;re actually instantiating!  Doh!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
This has dire consequences for any situation where you&amp;#8217;ve got a collection of objects of varying types.  Say you&amp;#8217;ve got a bunch of model classes, and you&amp;#8217;d like each class to emit an xml string containing its values.  In Objective-C, Python, Ruby, Smalltalk, and probably even Perl and Javascript, this is pretty straightforward;  You just give each class a method that emits a string (and, assuming you&amp;#8217;ve got an acyclic directed graph, calls the emitting method in each of its &amp;#8220;child&amp;#8221; objects).  Then you just call the emitting method in the root object, and away you go.  For example, once again consider some python:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
class RootElement:
    def emitXml(self):
        print &quot;&amp;lt;root&amp;gt;&quot;
        for child in self.children:
            child.emitXml()
        print &quot;&amp;lt;/root&amp;gt;&quot;
class SomethingElement:
    def emitXml(self):
        print '&amp;lt;something value=&quot;', self.value, '&quot;/&amp;gt;'
class SomeoneElement:
    def emitXml(self):
        print '&amp;lt;someone value=&quot;', self.value, '&quot;/&amp;gt;'&lt;/p&gt;
&lt;p&gt;r = RootElement()&lt;br /&gt;
c1 = SomethingElement()&lt;br /&gt;
c2 = SomeoneElement()&lt;br /&gt;
c1.value = &amp;#8220;first child&amp;#8221;&lt;br /&gt;
c2.value = &amp;#8220;second child&amp;#8221;&lt;br /&gt;
r.children = [c1, c2]&lt;br /&gt;
r.emitXml()&lt;br /&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;em&gt;(Note that this code breaks encapsulation quite a bit in setting attributes on the objects, and is not what I&amp;#8217;d do in production code.  But python lets you do it, and it makes examples short and sweet, so there you have it.)&lt;/em&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now then, that code outputs about what you might expect:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
&amp;lt;root&amp;gt;
&amp;lt;something value=&quot; first child &quot;/&amp;gt;
&amp;lt;someone value=&quot; second child &quot;/&amp;gt;&lt;/p&gt;
&lt;/root&gt;
&lt;p&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Simple, right?  Well, if you try to do something similar in C++ (or Java for that matter), you&amp;#8217;ll run into trouble.  You can start by giving your element classes a common parent declaring &lt;em&gt;emitXml&lt;/em&gt; (don&amp;#8217;t need to bother with such a thing in python, where method calls aren&amp;#8217;t bound to implementations until runtime), but as soon as you have something like RootElement maintaining a list of child elements, you&amp;#8217;ll hit the same snag in our earlier example;  the relevant implementations of &lt;em&gt;emitXml&lt;/em&gt; will be passed over in favor of the generic implementation in the parent class.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Which is where the visitor pattern comes in.  It&amp;#8217;s basically a kludge to work around the compile-time binding limitation of C++.  Even when there are times you&amp;#8217;d &lt;em&gt;want&lt;/em&gt; to use it in order to extract responsibilities out of a data-bearing class, you still end up with this ridiculous double-dispatch syntax (compare with Objective-C, where you can actually add methods to an existing class by using a category, so you can accomplish the same design feat of grouping functionally-related methods together, yet outside the classes they operate on, without the artifices of the visitor pattern).&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The moral of this story is that the visitor pattern is a necessary evil for statically-bound languages like C++.  And that if you want to avoid this evil thing, start by avoiding C++.  Really, pick up python or ruby or Objective-C or whatever.  Really!&lt;br /&gt;
&lt;p /&gt;&lt;em&gt;&lt;br /&gt;
&lt;b&gt;[update]&lt;/b&gt; fixed some typos, thanks weinholt&lt;/em&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Here's Where I Tell You What's Wrong With The Music Industry</title>
   <link href="http://localhost:4000/blog/2006/04/02/here-s-where-i-tell-you-what-s-wrong-with-the-music-industry/"/>
   <updated>2006-04-02T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2006/04/02/here-s-where-i-tell-you-what-s-wrong-with-the-music-industry</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I&amp;#8217;ve been thinking about this for a while, been meaning to blog about it, and some recent conversations have brought it to the forefront of my mind.  Here goes.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Surely no one has missed the fact that the music industry has gone through some changes in the past few years.  Things like the iTunes music store have dragged the record labels, kicking and screaming, into the 21st century.  Most of them are onboard by now, but there&amp;#8217;s still an undertone of terror visible in their actions;  More and more of the CDs they sell have been whammied so they sometimes &lt;a href=&quot;http://blogs.zdnet.com/BTL/?p=1890&quot;&gt;won&amp;#8217;t work on a computer&lt;/a&gt; at all.  Or, if they do work on a computer, they may install &lt;a href=&quot;http://www.boingboing.net/2005/11/14/sony_anticustomer_te.html&quot;&gt;deadly evil mojo&lt;/a&gt; on your machine in the process.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The reason for these paranoid practices on the part of the record labels is pretty easy to suss out:  For decades, they&amp;#8217;ve built their businesses around selling  bits of plastic or vinyl.  They&amp;#8217;ve taken for granted that they&amp;#8217;ll be able to continue doing this forever, and that this will always be their most important source of revenue.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
So naturally they&amp;#8217;re worried about mp3 and similar technologies robbing them of some of their profits.  I think it may be instructive to consider what happened around the birth of the recording industry.  At that time, many live performers became concerned for their livelihoods, worrying that if people could hear music on demand at any time, they&amp;#8217;d no longer bother going to performances, and these live performers would be out of work.  Of course, this turned out not to be the case;  If anything, recorded music has served to propel any number of performers to a level of fame and fortune that would have been impossible without recordings.  I believe that the music industry&amp;#8217;s concerns about losing revenues due to illegal digital distribution are similarly unfounded.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
For one thing, there is a notion that the people who download lots of music illegally are probably the people who also buy some of the largest amounts of legitimate copies of music.  Downloading doesn&amp;#8217;t replace their music-purchasing, but rather enhances it by letting them sample music from unfamiliar artists (potentially leading to future purchases) or downloading unavailable-for-purchase bootleg recordings of familiar artists (which increases the &amp;#8220;bonding&amp;#8221; between a listener and a favorite artist even more).&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Perhaps more importantly, the music industry is sitting on the keys to unlocking its own future potential.  For instance:  Propelling public awareness of artists through cross-promotion.  Let&amp;#8217;s say you&amp;#8217;re a big Nine Inch Nails fan, having heard their music on the radio, maybe gone to a show or two, etc.  At some point you point your browser at &lt;a href=&quot;http://www.nin.com&quot;&gt;http://www.nin.com&lt;/a&gt;, look around a bit at some lyrics and whatnot, and then you end up backtracking and surfing on somewhere else;   Your interest in &lt;span class=&quot;caps&quot;&gt;NIN&lt;/span&gt; didn&amp;#8217;t lead to any info about anything non-&lt;span class=&quot;caps&quot;&gt;NIN&lt;/span&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
How could this be improved?  Well, &lt;span class=&quot;caps&quot;&gt;NIN&lt;/span&gt; is currently on Interscope.  What if Interscope stipulated that all of its artists needed to provide linkage (in the form of a side-bar, or a dismissable slide-over graphic) to other, similar Interscope artists?  Then you might find out about &lt;a href=&quot;http://www.helmetmusic.com/&quot;&gt;Helmet&lt;/a&gt; or &lt;a href=&quot;http://www.audioslave.com&quot;&gt;Audioslave&lt;/a&gt; or, perhaps, some up-and-coming band that you&amp;#8217;ve really never heard of.  Some would complain that Interscope infringing on their artists websites would be a terrible, terrible thing, but considering all the &lt;a href=&quot;http://archive.salon.com/tech/feature/2000/06/14/love/index.html&quot;&gt;other shit they pull&lt;/a&gt; on the artists in their stables, this would be pretty minor.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
A bigger problem is that relationships between artists come and go.  As of this writing, for instance, the above-mentioned &lt;a href=&quot;http://www.helmetmusic.com/&quot;&gt;Helmet&lt;/a&gt; is still listed on Interscopes &lt;a href=&quot;http://www.interscope.com/artists/&quot;&gt;Artists&lt;/a&gt; page, despite the fact that one of the latest entries on Helmet&amp;#8217;s page mentions that they&amp;#8217;ve left Interscope.   Oops!  So Interscope&amp;#8217;s (hypothetical) forced linkage from &lt;span class=&quot;caps&quot;&gt;NIN&lt;/span&gt; to Helmet now isn&amp;#8217;t helping Interscope any more.  But&amp;#8230; what if it wasn&amp;#8217;t just Interscope?  What if the industry as a whole were presenting interesting ways for listeners to find similar artists?  That way Interscope would still benefit from a &lt;span class=&quot;caps&quot;&gt;NIN&lt;/span&gt;&amp;lt;-&amp;gt;Helmet linkage since in the future, visitors to Helmet&amp;#8217;s site would still get back to &lt;span class=&quot;caps&quot;&gt;NIN&lt;/span&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Apart from just a plain old list of links between similar bands, things could be user-tailored so that sites would bring to the user&amp;#8217;s attention news about upcoming local concerts with relevant artists, eventually including (gasp) unsigned artists as well (which the industry as a whole benefits from promoting since one day, presumably, any decent unsigned artist will be under contract with one of the labels).&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now all someone has to do is convince the music industry that I&amp;#8217;m right, and implement a solution for them, giving them an offer that&amp;#8217;s so good they can&amp;#8217;t say no.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Best. Mobile. Game. Evar.</title>
   <link href="http://localhost:4000/blog/2006/03/20/the-best-mobile-game-evar/"/>
   <updated>2006-03-20T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2006/03/20/the-best--mobile--game--evar-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Since back in the 80&amp;#8217;s, this funky Welsh dude (complete with an unhealthy fascination with farmyard animals) named Jeff Minter (aka &lt;a href=&quot;http://stinkygoat.livejournal.com/&quot;&gt;yak&lt;/a&gt;) has produced videogames and software toys for the platform du jour, starting with the old &lt;a href=&quot;http://www.llamasoft.co.uk/lc-8bit.php&quot;&gt;Commodore Vic-20&lt;/a&gt; and continuing right up to the current &lt;a href=&quot;http://www.llamasoft.co.uk/neon-screenshots.php&quot;&gt;Xbox 360&lt;/a&gt;.  The hallmark of all his games has been extremely trippy visuals, moreso over time&amp;#8230;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now, one of his latest works, gridrunner++, has been &lt;a href=&quot;http://www.cheeky.gr/?page_id=18&quot;&gt;ported to J2ME&lt;/a&gt;, which means that you (yes, &lt;em&gt;you&lt;/em&gt;!) can run it on your cellphone!  OK, not just &lt;strong&gt;any&lt;/strong&gt; cellphone, but most of the middling-or-better European-market phones from the past couple years (and probably some of their American counterparts).  I bought a copy &lt;a href=&quot;http://www.gamemobile.co.uk/free-mobile-game.php?affiliate=2903&quot;&gt;here&lt;/a&gt;, and you should do the same.  Even on the tiny screen, this thing is a dazzling display of exploding, twisting, pixel-shattery goodness.  You owe it to yourself, I&amp;#8217;m sure.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Worst Object-Oriented Language</title>
   <link href="http://localhost:4000/blog/2006/03/07/the-worst-object-oriented-language/"/>
   <updated>2006-03-07T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2006/03/07/the-worst-object-oriented-language</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I&amp;#8217;ve been doing object-oriented programming and design since 1994.  Most of that work has been centered on Objective-C, with a bit of dabbling in Smalltalk quite some time ago, occasional forays into Java, and increasingly more Python during the past few years.  During the past year, I&amp;#8217;ve finally had a reason to get deep into a project with C++, and now I know what I&amp;#8217;ve been missing:  A heap of nasty syntax and inflexibility, that&amp;#8217;s what!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Don&amp;#8217;t get me wrong, C++ is definitely a lot more powerful than just plain old C, and you can do some clever things with its templates and some other language features (with the caveat that in doing these clever things, you are relying heavily on the compiler doing lots of things that are far from explicit in the code, which is quite different from standard C).  My main gripe with C++ is that the object-oriented constructs it provides are really very not suited to the practice of object-oriented programming as it stands today (which may be a subject of future postings here).&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
On a whim, I recently googled &lt;a href=&quot;http://www.google.com/search?q=%22worst+object+oriented+language%22&quot;&gt;&amp;quot;worst object oriented language&amp;quot;&lt;/a&gt;, and got some interesting results.  This query produced 103 results, which Google whittled down to just 12 after removing what it thinks are probably duplicates.  Four of those were essentially the same quote from one article, pasted into different contexts, while the other eight seemed to be unique utterances.  In &lt;b&gt;all&lt;/b&gt; of these cases, the language being described was &lt;i&gt;(drumroll, please&amp;#8230;)&lt;/i&gt; yes, C++.  At least I&amp;#8217;m not alone in feeling this way.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>pandora</title>
   <link href="http://localhost:4000/blog/2006/02/17/pandora/"/>
   <updated>2006-02-17T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2006/02/17/pandora</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;My pal &amp;lt;a target=&amp;#8220;_blank&amp;#8221; href =&amp;#8220;http://peoplesflag.blogspot.com/&amp;#8221;&amp;gt;James&lt;/a&gt; tipped me off to the existence of &amp;lt;a target=&amp;#8220;_blank&amp;#8221; href =&amp;#8220;http://www.pandora.com&amp;#8221;&amp;gt;pandora&lt;/a&gt;, which lets you create your own streaming virtual radio station, continually feeding your head with music you like, often things you had never heard of and wouldn&amp;#8217;t have guessed you would like!  The way it works is that you tell pandora the names of some bands you like, and it uses that as a basis to begin choosing songs that it thinks you will like.  The &amp;#8220;editors&amp;#8221; at pandora have listened to thousands of albums, categorized their content by assigning attributes based on the sounds, and put it all in a database.  So, if you start off by entering &lt;a target=&quot;_blank&quot; href=&quot;http://www.tinytim.org&quot;&gt;Tiny Tim&lt;/a&gt; as your favorite artist, presumably you&amp;#8217;d get a stream full of artists who sing falsetto, or play ukelele, or both. &lt;tt&gt;[note to self: create Tiny Tim-based pandora station and see what happens]&lt;/tt&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
To top it off, the virtual stations you create can be shared with others!  I now submit for your listening pleasure my first pandora-station: &amp;lt;a target=&amp;#8220;_blank&amp;#8221; href =&amp;#8220;http://www.pandora.com/?sc=sh12811124&amp;#8221;&amp;gt;rock bastard&lt;/a&gt;.  It gave &amp;lt;a target=&amp;#8220;_blank&amp;#8221; href =&amp;#8220;http://peoplesflag.blogspot.com/&amp;#8221;&amp;gt;James&lt;/a&gt; a headache;  hopefully you&amp;#8217;re made of harder stuff.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>scratch</title>
   <link href="http://localhost:4000/blog/2006/02/10/scratch/"/>
   <updated>2006-02-10T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2006/02/10/scratch</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;A few weeks ago, I became the proud owner of an &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=rebisoft-20&amp;camp=1789&amp;creative=9325&amp;path=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fproduct%2FB0007Y79AI%2Fsr%3D8-2%2Fqid%3D1139561396%2Fref%3Dpd_bbs_2%3F%255Fencoding%3DUTF8&quot;&gt;iPod Nano&lt;/a&gt;.  It now accompanies me everywhere.  Whether I&amp;#8217;m commuting, coding, or cooking, chances are I&amp;#8217;ve got my preciousss in a pocket or otherwise on my person.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The only downside is that the shiny black surface gets scratched insanely easily!  When &lt;a href=&quot;http://www.theregister.co.uk/2005/09/23/ipod_nano_scratching/&quot;&gt;reports&lt;/a&gt; first came out about this last fall, I figured it was the whining of some perfectionists.  But now that I&amp;#8217;ve got one myself, I&amp;#8217;ve seen the light (and the scratches).  I&amp;#8217;ve carried cellphones around for years without this kind of scuffing.  I used one phone from June 2003 to December 2005, and that phone looks better than my iPod did after just a week of use!  During that week, I either carried it in a soft jacket pocket containing nothing else than the iPod and the headphones, but the surface looks like I&amp;#8217;ve been dragging it behind a car.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Fortunately, I&amp;#8217;m a pragmatic person, and I don&amp;#8217; t much care how my devices &lt;b&gt;look&lt;/b&gt;, as long as they do what they&amp;#8217;re supposed to.  Unfortunately the scratching was beginning to mar the display as well, so I decided to buy some protection in the form of an &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;tag=rebisoft-20&amp;camp=1789&amp;creative=9325&amp;path=http%3A%2F%2Fwww.amazon.com%2Fgp%2Fproduct%2FB000BWI6AS%2Fsr%3D1-12%2Fqid%3D1139566530%2Fref%3Dsr_1_12%3F%255Fencoding%3DUTF8&quot;&gt;iSkin Duo&lt;/a&gt;.  This is a dual-layer silicone &amp;#8220;condom&amp;#8221; for the iPod.  It comes in a range of color combinations, most of them brutally ugly.  I chose the brown/orange combo, which I would classify as only &amp;#8220;moderately ugly&amp;#8221;.  A hard transparent plastic bit covers the screen, while the click-wheel is covered by a single layer of silicone and an optional thin plastic bit to make the wheel a little smoother.  All in all, I&amp;#8217;m really happy with this:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;I can toss my iPod into a pocket without worrrying that it&amp;#8217;s scratching up even more.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The silicone skin makes it a little less slippery, therefore easier to grab and more difficult to drop.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The ugliness may prevent would-be thieves from even recognizing the iPod for what it is.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Universal Christmas Poo</title>
   <link href="http://localhost:4000/blog/2006/01/17/universal-christmas-poo/"/>
   <updated>2006-01-17T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2006/01/17/universal-christmas-poo</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Did I release the very first third-party screensaver for Intel Macs?  It seems like it!  I released the latest version of the &lt;a href=&quot;http://www.rebisoft.com/software/mister_hankey.html&quot;&gt;Mister Hankey Screensaver&lt;/a&gt; way back in November, compiled as a Universal Binary so that it would work on Intel Macs.  I didn&amp;#8217;t have access to a developer Intel Mac, so I had a friend try it briefly and verify that it worked.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now that Intel Macs are actually available, I checked versiontracker&amp;#8217;s &lt;a href=&quot;http://www.versiontracker.com/macintel/&quot;&gt;Mac Intel page&lt;/a&gt; to see what else was out there.  Imagine my surprise when I found only five other Mac Intel screensavers there, all of them released in the past couple weeks!  Google can&amp;#8217;t seem to find anything else, either.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
So, as far as I can tell, &lt;a href=&quot;http://www.rebisoft.com/software/mister_hankey.html&quot;&gt;Mister Hankey&lt;/a&gt; is the first screensaver ever released for Intel Macs by a third party.  Hooray!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Chomsky on the lack of a war on terror</title>
   <link href="http://localhost:4000/blog/2006/01/16/chomsky-on-the-lack-of-a-war-on-terror/"/>
   <updated>2006-01-16T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2006/01/16/chomsky-on-the-lack-of-a-war-on-terror</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Just read a &lt;a href=&quot;&quot;&gt;mercifully short interview&lt;/a&gt; with Noam Chomsky.  I say &amp;#8220;mercifully short&amp;#8221; because, as much as I admire the old guy, lots of his writings tend to be long and dense.  Good to see a bite-sized piece for a change. &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Some salient bits:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
A large majority of the population is in favor of a national health care system of some kind. [&amp;#8230;] But whenever that comes up [&amp;#8230;] it&amp;#8217;s called politically impossible, or &amp;#8220;lacking political support,&amp;#8221; which is a way of saying that the insurance industry doesn&amp;#8217;t want it, the pharmaceutical corporations don&amp;#8217;t want it, and so on.&lt;/blockquote&gt;&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
[&amp;#8230;] we are under a rigid doctrine in the West, a religious fanaticism, that says we must believe that the United States would have invaded Iraq even if its main product was lettuce and pickles, and the oil resources of the world were in Central Africa. Anyone who doesn&amp;#8217;t believe that is condemned as a conspiracy theorist, a Marxist, a madman, or something.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;What gives me hope actually is public opinion. Public opinion in the United States is very well studied, we know a lot about it. It&amp;#8217;s rarely reported, but we know about it. And it turns out that, you know, I&amp;#8217;m pretty much in the mainstream of public opinion on most issues.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p /&gt;
&lt;p&gt;Pass it along to your conservative friends!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>cypher &rarr; arrr arrr arrr</title>
   <link href="http://localhost:4000/blog/2005/12/21/cypher-rarr-arrr-arrr-arrr/"/>
   <updated>2005-12-21T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/12/21/cypher--rarr--arrr-arrr-arrr</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Often, non-Swedish movies are given new Swedish titles for the Swedish market, e.g.  &lt;i&gt;The Hulk&lt;/i&gt; becomes &lt;i&gt;Hulken&lt;/i&gt;.  This choice is made by whoever acquires the rights for distributing the film in Sweden.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Sometimes, however, movies are given new titles that are, at best, inexplicable, and, at worst, unintentionally hilarious.  Some of the worst of these occur when a movie with an English title gets a new title which is&amp;mdash;get this&amp;mdash;&lt;b&gt;another English title&lt;/b&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Case in point:  A week or two ago, I noticed a movie in the Swedish TV schedule that looked interesting.  Its original title is &lt;a href=&quot;http://www.imdb.com/title/tt0284978/?fr=c2l0ZT1kZnx0dD0xfGZiPXV8cG49MHxrdz0xfHE9Y3lwaGVyfGZ0PTF8bXg9MjB8bG09NTAwfGNvPTF8aHRtbD0xfG5tPTE_;fc=1;ft=21;fm=1&quot;&gt;&lt;i&gt;Cypher&lt;/i&gt;&lt;/a&gt;, which is of course just an odd misspelling of the word &amp;#8220;cipher&amp;#8221;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now, Swedish has a perfectly good word for &amp;#8220;cipher&amp;#8221;, that could be used to translate this film title for Swedes who may not know the word &amp;#8220;cipher&amp;#8221;:  The word is &amp;#8220;chiffer&amp;#8221;.  The distributer could have chosen to call the movie &lt;i&gt;Chiffer&lt;/i&gt; or some artificial misspelling like &lt;i&gt;Skiffer&lt;/i&gt; or &lt;i&gt;Chyffer&lt;/i&gt;, whatever, to emulate the original.  But they made a different choice.  They chose to call the movie &lt;i&gt;Brainstorm&lt;/i&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Don&amp;#8217;t get me wrong, &amp;#8220;Brainstorm&amp;#8221; is a perfectly good name for a movie.  I quite liked the &lt;a href=&quot;http://www.imdb.com/title/tt0085271/?fr=c2l0ZT1kZnx0dD0xfGZiPXV8cG49MHxrdz0xfHE9YnJhaW5zdG9ybXxmdD0xfG14PTIwfGxtPTUwMHxjbz0xfGh0bWw9MXxubT0x;fc=2;ft=20;fm=1&quot;&gt;1983 movie with that name&lt;/a&gt;, starring Christopher Walken, when I was a kid.  But that&amp;#8217;s just it;  If you&amp;#8217;re going to rename a movie to suit the local language, why choose a new name that &lt;b&gt;(A)&lt;/b&gt; is not in the local language, &lt;b&gt;(B)&lt;/b&gt; has already been used by no less than two other feature films, and &lt;b&gt;&amp;#169;&lt;/b&gt; bears no relation to the original title!  Why, oh silly film distributor, &lt;b&gt;why&lt;/b&gt;???!?!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>presenting Torched Turf</title>
   <link href="http://localhost:4000/blog/2005/11/28/presenting-torched-turf/"/>
   <updated>2005-11-28T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/11/28/presenting-torched-turf</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;&lt;img src=&quot;http://pygame.org/thumb/db9d871fb44ee1259bee943eb294856a.png&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;Ladies and Gentlemen,&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Please welcome &lt;a href=&quot;http://www.jasonmhirst.co.uk/?page_id=163&quot;&gt;Torched Turf&lt;/a&gt; to the world.  Torched Turf is based on the standard old &amp;#8220;artillery&amp;#8221; style of computer game, but with a few new elements that make it stand out on its own.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Torched Turf was created for the &lt;a href=&quot;http://www.idevgames.com/contest/downloads/details.php?file=9&quot; title=&quot;iDevGames - Contest - Downloads - Viewing Torched Turf&quot;&gt;iDevGames Original Mac Game Cup&lt;/a&gt; contest.  The terms of the contest call for a game with one complete, playable level, and currently that&amp;#8217;s what we&amp;#8217;ve got.  In other words, despite its 1.0 status, Torched Turf is still a work in progress, and will be enhanced further in the future.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
In the meantime, download the &lt;a href=&quot;http://metaplay.dyndns.org:8081/~turf/torched_turf-1.0.dmg&quot; title=&quot;http://metaplay.dyndns.org:8081/~turf/torched_turf-1.0.dmg&quot;&gt;Mac version&lt;/a&gt; or the &lt;a href=&quot;http://metaplay.dyndns.org:8081/~turf/torched_turf-1.0-win32.zip&quot; title=&quot;http://metaplay.dyndns.org:8081/~turf/torched_turf-1.0-win32.zip&quot;&gt;Windows version&lt;/a&gt; and give it a try!  Later, sometime between Dec 1 2005 and Dec 15 2005, be sure to go &lt;a href=&quot;http://www.idevgames.com/contest/voting/&quot; title=&quot;http://www.idevgames.com/contest/voting/&quot;&gt;vote&lt;/a&gt; for this or any other game you feel is a worthy winner.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
I am proud to consider myself a member of this world-spanning team of like-minded would-be game-builders, and hope that the release of Torched Turf paves the way for yet more games featuring exploding sheep.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>election theft</title>
   <link href="http://localhost:4000/blog/2005/11/21/election-theft/"/>
   <updated>2005-11-21T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/11/21/election-theft</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;The notion that &lt;i&gt;electronic voting machines without paper trails are dangerous to democracy&lt;/i&gt; is something that&amp;#8217;s been &lt;a href=&quot;http://www.schneier.com/blog/archives/2004/11/the_problem_wit.html&quot;&gt;talked&lt;/a&gt; &lt;a href=&quot;http://www.blackboxvoting.org/&quot;&gt;about&lt;/a&gt; &lt;a href=&quot;http://www.verifiedvoting.org/&quot;&gt;before&lt;/a&gt;.  Now, a &lt;a href=&quot;http://www.gao.gov/new.items/d05956.pdf&quot;&gt;General Accountability Office report&lt;/a&gt; shows pretty clearly that there were lots of irregularities in the 2004 U.S. elections, connected to the use of electronic voting machines.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Regardless of your political affiliations, regardless of whether you believe that Bush &amp;amp; co stole the elections, it&amp;#8217;s important to understand that &lt;b&gt;electronic voting machines without paper trails produce unverifiable results&lt;/b&gt;.  The simple fact is the &lt;i&gt;actual&lt;/i&gt; results of last year&amp;#8217;s elections are, inherently, &lt;b&gt;&lt;span class=&quot;caps&quot;&gt;UNKNOWABLE&lt;/span&gt;&lt;/b&gt;.  There is simply no way to know how many people voted, or for which candidates they voted.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
This goes beyond the issues of &lt;a href=&quot;http://www.cs.uiowa.edu/~jones/cards/chad.html&quot;&gt;&amp;quot;hanging chads&amp;quot;&lt;/a&gt; that vexed us after the 2000 elections;  Then, you could at least theorize the existence of a person or device that could divine the intent of the voter with a high degree of precision.  With unverifiable electronic voting machines, it&amp;#8217;s just a total crapshoot.  The &lt;span class=&quot;caps&quot;&gt;GAO&lt;/span&gt; report cites several known cases where large numbers of votes went to the wrong candidates, which were supposedly &amp;#8220;fixed&amp;#8221; afterwards.  The problem is, how many &lt;b&gt;un&lt;/b&gt;known, similar cases are there?  We&amp;#8217;ll just never know.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Again, this is an issue for &lt;span class=&quot;caps&quot;&gt;EVERYONE&lt;/span&gt; concerned with the preservation of American democracy, regardless of party ties.  This time it may have been criminal, unethical Republican asshats who used some wide-open holes the security of these machines to secure elections for their candidates;  Next time it could be criminal, unethical Democratic asshats doing the same!  For that matter, it may be that &lt;span class=&quot;caps&quot;&gt;BOTH&lt;/span&gt; parties had people trying to fake out the voting machines in 2004, and that the Republicans just did a better job at it.  Who knows?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>spinvaders 1.0.0</title>
   <link href="http://localhost:4000/blog/2005/11/14/spinvaders-1-0-0/"/>
   <updated>2005-11-14T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/11/14/spinvaders-1-0-0</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I&amp;#8217;m pleased to announce the release of spinvaders 1.0.0!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The main change in this release is the introduction of fantastic music and sound effects courtesy of &lt;a href=&quot;http://www.davidtweet.com&quot;&gt;David Tweet&lt;/a&gt;.  Collaborating with David on this release has produced fantastic results.  It&amp;#8217;s almost like a whole new game!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Also new for this release is that spinvaders is now open source, with its own &lt;a href=&quot;http://sourceforge.net/projects/spinvaders&quot;&gt;project hosted at sourceforge&lt;/a&gt;.  This means that not only can Mac and Windows users download a precompiled package, now users of &lt;span class=&quot;caps&quot;&gt;BSD&lt;/span&gt;, Linux, or other unixy platforms can download the source and all its dependencies (which aren&amp;#8217;t too terribly many) and run it on their platforms as well.&lt;br /&gt;
&lt;img src=&quot;http://www.nuthole.com/spinvaders/spinvaders_0_0_4.png&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;p /&gt;Here&amp;#8217;s where to get it:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://prdownloads.sourceforge.net/spinvaders/spinvaders_1.0.0_macppc.dmg?download&quot;&gt;spinvaders&lt;/a&gt; for Macintosh (made for Mac OS X 10.4, but may work on 10.3 as well)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://prdownloads.sourceforge.net/spinvaders/spinvaders_1.0.0_win32.zip?download&quot;&gt;spinvaders&lt;/a&gt; for Windows 95/98/ME/2K/XP&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://prdownloads.sourceforge.net/spinvaders/spinvaders_1.0.0_src.tar.gz?download&quot;&gt;spinvaders source&lt;/a&gt; for other platforms&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Installation is the same as before:  The Mac version is in a disk image; you can copy the enclosed application and run it from wherever you like.  The Windows version is a zip file containing a directory; unpack the directory wherever you like, and run it by starting &amp;#8220;spinvaders.exe&amp;#8221; from within the directory.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>software design sketching</title>
   <link href="http://localhost:4000/blog/2005/10/31/software-design-sketching/"/>
   <updated>2005-10-31T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/10/31/software-design-sketching</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Peter Lindberg &lt;a href=&quot;http://tesugen.com/archives/05/10/modeling-as-sketching&quot;&gt;posted some thoughts&lt;/a&gt; about the lack of &amp;quot;sketching&amp;quot; in software development, which got me thinking a bit.  The following was my emailed response to Peter:&lt;br /&gt;
&lt;hr /&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Personally, I do a fair amount of software &amp;#8220;modeling&amp;#8221;, in the form of prototypes.  If an application calls for a new &lt;span class=&quot;caps&quot;&gt;GUI&lt;/span&gt; component, for instance,  I&amp;#8217;ll set up an empty application/shell/playground with some &amp;#8220;scaffolding&amp;#8221; to provide the component with its inputs, then start &amp;#8220;playing&amp;#8221; with it until I find something that feels right.  Sometimes it will be a continual evolution of the design in the code, but sometimes I&amp;#8217;ll duplicate classes, and rename them with some sort of version ID in the class names, so that I can view several stages of the evolution at once.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The same applies to games I&amp;#8217;m designing, or ideas I have for new applications, or, for that matter, changes I&amp;#8217;m considering in the &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; code for a website.  Seldom do I start off by mapping out &amp;#8220;here&amp;#8217;s exactly what I want to implement&amp;#8221; in my own projects;  Almost always, in work that I&amp;#8217;m doing for myself, I start off with an exploratory phase just to see what comes out of my fingers, and after a few iterations of coding, and trying out what I&amp;#8217;ve done, and sometimes putting the project away for a few days or weeks, eventually things tend to settle into a zone that feels right.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
In a group effort, this doesn&amp;#8217;t always work that well.  When several people are involved from the beginning of a project, if everyone just spins off into an exploration of their own ideas, it can be harder to gather everyone back to some common point to get everything working together.  Maybe that&amp;#8217;s why software design tends, as you say, to be focused on &amp;#8220;producing construction plans&amp;#8221; and defining APIs for how modules will work together.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>NEWS FLASH: Republican Corruption!</title>
   <link href="http://localhost:4000/blog/2005/10/04/news-flash-republican-corruption/"/>
   <updated>2005-10-04T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/10/04/news-flash--republican-corruption-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;OK, I can&amp;#8217;t say I&amp;#8217;m surprised by corruption in the current U.S. administration that is being revealed more and more these days.  Between  &lt;a href=&quot;http://seattletimes.nwsource.com/html/politics/2002538130_delay04.html&quot;&gt;Tom DeLay&amp;#8217;s money laundering&lt;/a&gt;, &lt;a href=&quot;http://www.rutherford.org/articles_db/commentary.asp?record_id=362&quot;&gt;Bill Frist&amp;#8217;s stock dumping&lt;/a&gt;, and &lt;a href=&quot;http://msnbc.msn.com/id/9503017/&quot;&gt;FEMA&amp;#8217;s no-bid contracts&lt;/a&gt; for Katrina cleanup, well, it&amp;#8217;s all pretty clear evidence of the philosophical bankruptcy of the republican party, and the &lt;a href=&quot;http://www.truthout.org/docs_2005/100205F.shtml&quot;&gt;end of the &amp;quot;Republican Revolution&amp;quot;&lt;/a&gt;.  In other words, no big surprise.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
However, even &lt;strong&gt;I&lt;/strong&gt; was surprised to read &lt;a href=&quot;http://msnbc.msn.com/id/9503017/&quot;&gt;this seemingly clear-cut case&lt;/a&gt; of republican operatives&amp;#8217; mob connections (including hitmen!):&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The fraud allegedly committed by Abramoff and his business partner Adam Kidan involved a phony wire transfer they used to purchase a controlling interest in SunCruz from the company&amp;#8217;s founder, Konstantinos &amp;#8220;Gus&amp;#8221; Boulis, in 2001.&lt;br /&gt;
&lt;p /&gt;Abramoff and Kidan later fell out with Boulis in a bitter business dispute that turned violent. In February 2001, gunmen ambushed Boulis on a Fort Lauderdale, Fla., highway and shot him repeatedly. On Tuesday, Florida authorities arrested three New York men with mob connections for the Boulis killing. Two of the men &amp;#8211; Anthony Moscatiello and Tony Ferrari &amp;#8211; had received payments totaling more than $240,000 from Kidan and Abramoff. Moscatiello, a longtime associate of the Gambino Mafia family, and Ferrari were supposedly providing food and consulting services to SunCruz &amp;#8211; or so Kidan claimed when questioned by prosecutors. There is no evidence, however, that Moscatiello and Ferrari provided any services to the company.&lt;br /&gt;
&lt;p /&gt;Connecting the dots isn&amp;#8217;t difficult here: Kidan and Abramoff want to get rid of Boulis, who won&amp;#8217;t go away. Kidan and Abramoff hire Moscatiello and Ferrari with SunCruz money. Moscatiello and Ferrari allegedly whack Boulis, without any motive of their own. If the Broward County state&amp;#8217;s attorney has sufficient evidence to win convictions for a capital crime, some people will probably be talking soon in hope of avoiding the hot shot.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p /&gt;
&lt;p&gt;Just to reiterate, let&amp;#8217;s repeat some of that last paragraph in big, bold bullets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Kidan and Abramoff want to get rid of Boulis.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Kidan and Abramoff hire Moscatiello and Ferrari.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Moscatiello and Ferrari allegedly whack Boulis, without any motive of their own.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p /&gt;
&lt;p&gt;Damn. I mean, damn!  It&amp;#8217;s been clear for a while that Abramoff is a &lt;a href=&quot;http://en.wikipedia.org/wiki/Jack_Abramoff&quot;&gt;real piece of work&lt;/a&gt;, but this is just over the top.  These are the kinds of murderous bastards that our man &lt;a href=&quot;http://www.whitehouse.org/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;GWB&lt;/span&gt;&lt;/a&gt; is fronting for.  Hooray for us, for putting this kind of thuggery in the White House, time and again.  To quote &lt;a href=&quot;http://www.wandasykes.com &quot;&gt;Wanda Sykes&lt;/a&gt;, &amp;quot;You can&amp;apos;t blame the blind man for wrecking your car when you&amp;apos;re the one who gave him the keys.&amp;quot;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The Red Box: how to out-Windows Windows</title>
   <link href="http://localhost:4000/blog/2005/09/21/the-red-box-how-to-out-windows-windows/"/>
   <updated>2005-09-21T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/09/21/the-red-box--how-to-out-windows-windows</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;The past few months have spurred lots of discussion and opinions about Mac on Intel.  One thing that&amp;#8217;s been neglected in most commentary I&amp;#8217;ve seen is mention of Apple&amp;#8217;s old &lt;a href=&quot;http://www.lowendmac.com/musings/boxes.shtml&quot;&gt;&amp;#8220;Box&amp;#8221;&lt;/a&gt; model.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Back in the late 90s, Mac OS X wasn&amp;#8217;t called &amp;#8220;Mac OS X&amp;#8221;, it was called &amp;#8220;Rhapsody&amp;#8221;.  The developer previews ran on both &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; Macs and normal Intel PCs.  Apple spoke of different application environments that would be enabled in Rhapsody: &lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt; The Yellow Box was the OpenStep application framework collection, which is now called Cocoa;  &lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The Blue Box was the legacy Mac OS 9 compatibility environment, now called Classic;  &lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The Red Box was the rumored (never confirmed by Apple) Windows compatibility environment that would allow Rhapsody for Intel to run Windows applications in a native environment, similar to VirtualPC, but running full-bore at native speed since no &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; emulation would be necessary.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p /&gt;
&lt;p&gt;Well, Rhapsody begat Mac OS X, and Mac OS X wasn&amp;#8217;t going to be available for Intel.  Apple stopped talking about their &amp;#8220;boxes&amp;#8221;, VirtualPC worked pretty well, and the world moved on.  Now, the Mac is veering back toward Intel, and before we know it we&amp;#8217;ll be running with Intel, and Microsoft will surely sell native-speed VirtualPC for running Windows&amp;#8230;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
But, what if there&amp;#8217;s another way?  What if we could run Windows apps on Mac OS X/Intel that were freed from the VirtualPC OS-in-a-window appearance?  What if we could run Windows apps with something that strives toward a Mac OS X look?  What I&amp;#8217;m thinking about are the &lt;a href=&quot;http://www.winehq.com/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt;&lt;/a&gt; project and its offshoot, &lt;a href=&quot;http://darwine.opendarwin.org/&quot;&gt;Darwine&lt;/a&gt;.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
For those who don&amp;#8217;t know, &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; (which stands for &amp;#8220;&lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; Is Not an Emulator) is an independent implementation of a subset the win32 APIs, which most existing Windows applications are built on top of.  The main purpose of &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; is to be able to run Windows software on Linux (the Darwine offshoot targets running Windows software on Mac OS X).  Both projects sport &amp;#8221;http://www.winehq.com/site?ss=1&amp;quot;&amp;gt;screenshots&lt;/a&gt; showing a variety of applications running.  WINE&amp;#8217;s subset of the win32 APIs seems to be quite a large subset indeed.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
WINE&amp;#8217;s main advantages over VirtualPC are twofold:  First, it doesn&amp;#8217;t require Windows in order to run (VirtualPC actually has a Windows installation) since it&amp;#8217;s a reimplementation of some APIs rather than a full OS.  Second, Windows created by &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; can be mixed on the screen with standard Mac windows, instead of being trapped inside another window.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Before &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; is fully ready to provide a proper Mac experience however, there are (at least) three main hurdles to overcome:&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;Incomplete APIs.  &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; can run lots and lots of applications, but to be on a par with VirtualPC, it really needs to run nearly everything.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;X-Windows.  The current implementation of Darwine using X-Windows for drawing.  This is an obvious stepping-stone for the developers, but in the long term it needs to use standard Quartz windows.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Windows look&amp;#8217;n&amp;#8217;feel.  Windows applications running in &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; look like, well, Windows applications.  Ideally we&amp;#8217;d want them to look more like Mac applications.  I&amp;#8217;m not sure if there&amp;#8217;s any simple workaround for this;  My (perhaps mistaken) understanding is that win32 is usually used in a fairly low-level way, and that Windows apps (or the libraries they&amp;#8217;re built with) actually draw most of their components themselves, including &amp;#8220;standard&amp;#8221; buttons, etc, so it would be difficult to give them Aqua-styled buttons, scrollbars, bevels, etc.  But it seems like some things could be done to make the experience more Mac-like, perhaps by forcing menu bars to draw at the top of the screen or something.&lt;/li&gt;&lt;/p&gt;
&lt;/ol&gt;
&lt;p /&gt;
&lt;p&gt;Now, I&amp;#8217;m sure that the &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; and Darwine teams have limited resources like most open-source projects do.  But, hey, Apple has some cash in the bank, and a great team of engineers.  What if they set a team to work on taking the existing &lt;span class=&quot;caps&quot;&gt;WINE&lt;/span&gt; codebase, completing more APIs and adding some polish, to provide a smooth Windows-on-Mac experience for Mac OS X 10.5 on Intel?  And then submitting most of their enhancements back to the original project?  They&amp;#8217;ve pulled similar stealth stunts before, both with building Safari from &lt;span class=&quot;caps&quot;&gt;KDE&lt;/span&gt; code, and building the core Darwin OS with parts of various &lt;span class=&quot;caps&quot;&gt;BSD&lt;/span&gt; UNIXes.  If anyone can do it, Apple can.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
What we&amp;#8217;d end up with is a more flexible Mac OS X that would, in addition to the current APIs from Cocoa, Carbon, &lt;span class=&quot;caps&quot;&gt;POSIX&lt;/span&gt;, and Java, support Win32 as well.  This would even further ease things for potential switchers, since even though we assume that there are equal or better Mac apps for most uses, it would be even easier for people to switch if they knew they could bring their favorite text editor or graphics package with them.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
I have absolutely no inside knowledge of what&amp;#8217;s going on inside Apple, and no idea if this concept has even been considered, let along worked on, but it seems to me like lots of people would appreciate this.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Let the chest-thumping begin</title>
   <link href="http://localhost:4000/blog/2005/08/16/let-the-chest-thumping-begin/"/>
   <updated>2005-08-16T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/08/16/let-the-chest-thumping-begin</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Just read a pretty &lt;a href=&quot;http://www.bloggernews.net/showstory.asp?page=blognews/stories/UP0000466.txt&quot;&gt;convincing article&lt;/a&gt; arguing that the reason that people like dubya win elections is largely through assuming an &amp;#8220;alpha male&amp;#8221; pose;  that above anything else, people will vote for the guy who&amp;#8217;s best at hollering, pounding his chest, and behaving like the top gorilla.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>gotchur web teevee on d'innurnet</title>
   <link href="http://localhost:4000/blog/2005/08/12/gotchur-web-teevee-on-d-innurnet/"/>
   <updated>2005-08-12T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/08/12/gotchur-web-teevee-on-d-innurnet</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Stumbled across the &lt;a href=&quot;http://participatoryculture.org/download.php&quot;&gt;&lt;span class=&quot;caps&quot;&gt;DTV&lt;/span&gt; project&lt;/a&gt;, which promises to provide independent internet TV.  Pay attention to two key features:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Anyone can publish video content with the &lt;a href=&quot;http://participatoryculture.org/bm/&quot;&gt;Broadcast Machine&lt;/a&gt; &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; script.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The published file apparently doesn&amp;#8217;t have to be hosted on a webserver, you can share it as a bittorrent from your desktop machine.  The &lt;span class=&quot;caps&quot;&gt;DTV&lt;/span&gt; client software implements the bittorrent protocol for downloading content, and presumably sharing content as well, so as soon as your video is &amp;#8220;out in the wild&amp;#8221;, the clients that have downloaded it will help keep your own bandwidth usage down&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Currently only for Mac, but a Windows client is apparently on the way.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>25 years too late:  the Microsoft Shell</title>
   <link href="http://localhost:4000/blog/2005/08/10/25-years-too-late-the-microsoft-shell/"/>
   <updated>2005-08-10T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/08/10/25-years-too-late---the-microsoft-shell</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;One bit of technology that Microsoft has recently started talking to developers about is the Microsoft Shell.  This is something that &lt;a href=&quot;http://www.vnunet.com/vnunet/news/2140861/microsoft-slams-f-secure&quot;&gt;may or may not&lt;/a&gt; be a part of the upcoming Microsoft &lt;a href=&quot;http://www.macosx.com/forums/showthread.php?p=1147056#post1147056&quot;&gt;&lt;span class=&quot;caps&quot;&gt;VISTA&lt;/span&gt;&lt;/a&gt; OS.  Basically, someone at Microsoft finally decided that &lt;span class=&quot;caps&quot;&gt;DOS&lt;/span&gt;/Windows&amp;#8217; horrid built-in scripting language, as exemplified in millions of nasty &lt;span class=&quot;caps&quot;&gt;BAT&lt;/span&gt; files around the world, needed to be more like a &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; command-line.&lt;br /&gt;
&lt;p /&gt;Kind of ironic, since that old &lt;span class=&quot;caps&quot;&gt;DOS&lt;/span&gt; pidgin scripting language was never anything more than a really feature-poor, painfully bad imitation of 1979-era &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt;.&lt;br /&gt;
&lt;p /&gt;This is where Microsoft Shell steps in, bringing things such as reasonable syntax and (hopefully) complete command i/o redirection and piping, just like &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; has had since the dawn of time.&lt;br /&gt;
&lt;p /&gt;&lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; advocates have long &lt;a href=&quot;http://www.cryptonomicon.com/beginning.html&quot;&gt;argued the advantages&lt;/a&gt; of a command-line interface, mainly that it enables us to use our innate language abilities to interface with a machine, instead of just dragging a mouse around (which evolution hasn&amp;#8217;t really built us for).  So it&amp;#8217;s great that Windows is finally stepping forward towards &lt;span class=&quot;caps&quot;&gt;UNIX&lt;/span&gt; in this regard.  Welcome to the 80&amp;#8217;s, Microsoft!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>spammer death</title>
   <link href="http://localhost:4000/blog/2005/07/27/spammer-death/"/>
   <updated>2005-07-27T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/07/27/spammer-death</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Famed Russian spammer Vardan Kushnir was &lt;a href=&quot;http://www.theinquirer.net/?article=24890&quot;&gt;found murdered&lt;/a&gt; in his home in Moscow yesterday.  Kushnir was apparently famous for saying &amp;quot;spam was what e-mails were for&amp;quot;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
It&amp;#8217;s unknown whether he was killed by a group of angry spam recipients, but that&amp;#8217;s where I&amp;#8217;d put my money if I were a betting man.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>spinvaders 0.0.4</title>
   <link href="http://localhost:4000/blog/2005/07/22/spinvaders-0-0-4/"/>
   <updated>2005-07-22T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/07/22/spinvaders-0-0-4</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;New version of spinvaders is out.  This is primarily a bug-fix release;  the main bug was that 0.0.3 and earlier could not run on Mac OS X 10.4;  Now, spinvaders is much more future-proof and should continue to run &amp;#8220;forever&amp;#8221;.&lt;br /&gt;
&lt;img src=&quot;http://www.nuthole.com/spinvaders/spinvaders_0_0_4.png&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Changes in this version:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;This version now works correctly on the latest version of Mac OS X (10.4, &amp;#8220;Tiger&amp;#8221;)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Cleaned up some sprites&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Player weapon now turns partly green when it is in &amp;#8220;supergun&amp;#8221; mode&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;And here&amp;#8217;s where to get it:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;/spinvaders/spinvaders_0_0_4.dmg&quot;&gt;spinvaders&lt;/a&gt; for Macintosh (made for Mac OS X 10.4, but probably works on 10.3 as well)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;No windows build of spinvaders 0.0.4 is available at this time&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Installation is the same as before:  The Mac version is in a disk image; you can copy the enclosed application and run it from wherever you like.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Wil Shipley, my hero</title>
   <link href="http://localhost:4000/blog/2005/07/20/wil-shipley-my-hero/"/>
   <updated>2005-07-20T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/07/20/wil-shipley--my-hero</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Back in the mid-90&amp;#8217;s, when I was a NeXTStep consultant, getting a job at &lt;a href=&quot;http://www.omnigroup.com&quot;&gt;OmniGroup&lt;/a&gt; was a sort of recurring daydream to me.  Like &lt;a href=&quot;http://web.archive.org/web/19970203173913/http://www.is.com/&quot;&gt;Integrity Solutions&lt;/a&gt; where I worked, OmniGroup did NeXTStep consulting, but also commercial application development.  Started by Wil Shipley and Ken Case and surely some other dudes whose names escape me at the moment, Omni seemed like Shangri-La compared to my job.  &lt;a href=&quot;http://web.archive.org/web/19970413044010/omnigroup.com/Info/Jobs.html&quot;&gt;Browsing their website&lt;/a&gt;, you&amp;#8217;d see descriptions of their work environment, which I&amp;#8217;d contrast with mine:&lt;br /&gt;
&lt;center&gt;&lt;br /&gt;
&lt;table cellpadding=&quot;10&quot; border=&quot;2&quot;&gt;&lt;br /&gt;
&lt;tr&gt;&lt;br /&gt;
&lt;th class=&quot;internal&quot; width=&quot;50%&quot;&gt;at Omni&lt;/th&gt;&lt;br /&gt;
&lt;th class=&quot;internal&quot;&gt;at Integrity Solutions&lt;/th&gt;&lt;/p&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;internal&quot;&gt;&lt;br /&gt;
all employees worked at omni&amp;#8217;s office in a casual, fun atmosphere&lt;/td&gt;
&lt;td class=&quot;internal&quot;&gt;many employees worked in windowless rooms at customer sites, crammed to the point of literally bumping elbows with one another&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;internal&quot;&gt;&lt;br /&gt;
employees working at the office enjoyed no-cost lunches prepared by on-site chef&lt;/td&gt;
&lt;td class=&quot;internal&quot;&gt;
&lt;p&gt;employees working at the office were supposed to pay a quarter for lousy office coffee&lt;/p&gt;
&lt;p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;
&lt;tr&gt;&lt;td class=&quot;internal&quot;&gt;&lt;br /&gt;
once a month, a professional masseuse came around to rub everyone&amp;#8217;s shoulders&lt;/p&gt;
&lt;/td&gt;
&lt;td class=&quot;internal&quot;&gt;
&lt;p&gt;once a month, the &lt;span class=&quot;caps&quot;&gt;CEO&lt;/span&gt; would give away a set of hand-crafted juggling bags that he made from old swimsuit fabric&lt;/p&gt;
&lt;p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;
&lt;tr&gt;&lt;td class=&quot;internal&quot;&gt;&lt;br /&gt;
had some sort of gaming room with (then-)state-of-the-art consoles, etc&lt;/p&gt;
&lt;/td&gt;
&lt;td class=&quot;internal&quot;&gt;
&lt;p&gt;juggling was encouraged&lt;/p&gt;
&lt;p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;br /&gt;
&lt;tr&gt;&lt;td class=&quot;internal&quot;&gt;&lt;br /&gt;
the drudgery of the mind-numbing consulting work was balanced out by being able to design and implement interesting commercial applications&lt;/p&gt;
&lt;/td&gt;
&lt;td class=&quot;internal&quot;&gt;
&lt;p&gt;the drudgery of the mind-numbing consulting work was balanced out by dreaming of going to work for a better company&lt;/p&gt;
&lt;p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/p&gt;
&lt;/table&gt;
&lt;/center&gt;
&lt;p&gt;&lt;p /&gt;As much as I thought about it, for some reason I never tried to get a job there.  Probably partly because I didn&amp;#8217;t want to move, and partly because I was at a stage in my life where, for reasons I don&amp;#8217;t quite grasp now, &lt;b&gt;complaining&lt;/b&gt; about shit seemed like a more useful proposition than trying to actually &lt;b&gt;do&lt;/b&gt; something about shit. &lt;br /&gt;
&lt;p /&gt;Anyway.&lt;br /&gt;
&lt;p /&gt;At some point (I haven&amp;#8217;t followed the twists and turns that well), Wil left the company he founded, and started &lt;a href=&quot;http://www.delicious-monster.com/&quot;&gt;Delicious Monster&lt;/a&gt;, which has had a &amp;#8220;monster hit&amp;#8221; (yuk yuk) with &lt;a href=&quot;http://www.delicious-monster.com/&quot;&gt;Delicious Library&lt;/a&gt;, an application that, to me, seems like cool technology that I would never have guessed would find an audience.  Fortunately for Wil and the gang, it has found a huge audience, earning them &lt;a href=&quot;http://www.wired.com/news/mac/0,2125,66276,00.html&quot;&gt;$250,000 in its first month&lt;/a&gt;, receiving awards, etc.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
To top it off, Wil has started &lt;a href=&quot;http://www.wilshipley.com/blog/&quot;&gt;blogging&lt;/a&gt;, which has been fun.  One of the more interesting posts lately is about his &lt;a href=&quot;http://wilshipley.com/blog/2005/06/student-talk-from-wwdc-2005.html&quot; title=&quot;Call Me Fishmeal.: Student Talk from WWDC 2005.&quot;&gt;Student Talk from &lt;span class=&quot;caps&quot;&gt;WWDC&lt;/span&gt; 2005&lt;/a&gt;, in which Wil gives newbies some advice on starting their own company.  Like Wil, I once started &lt;a href=&quot;http://www.rebisoft.com&quot;&gt;my own company&lt;/a&gt;;  Unlike Wil, I didn&amp;#8217;t really consider doing commercial app development (if you think the Mac market for commercial software in 2005 is small, try to imagine the miniscule size of the NeXTStep market in 1997!), but focused on consulting, and then let it sort of flounder after I couldn&amp;#8217;t, on my own, find enough interesting work to do that way.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Three cheers for &lt;a href=&quot;http://www.wilshipley.com/blog/&quot;&gt;Wil&lt;/a&gt;, the man who proves that nerdery + chutzpah == success.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Pay no attention to the processor in the box</title>
   <link href="http://localhost:4000/blog/2005/06/17/pay-no-attention-to-the-processor-in-the-box/"/>
   <updated>2005-06-17T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/06/17/pay-no-attention-to-the-processor-in-the-box</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Last week, Apple made waves when it announced that future Macintosh models, beginning next year, will contain Intel processors just like other PCs.  Some people have asked me what I think about this, so here goes:&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;b&gt;&lt;i&gt;The transition to Intel is going to be a great thing.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now, before I continue:  I really don&amp;#8217;t much care for the Intel architecture.  I am a True Believer in the &lt;span class=&quot;caps&quot;&gt;RISC&lt;/span&gt; approach embodied in the PowerPC architecture.  However, for reasons that should become clear as I continue, for most intents and purposes, &lt;i&gt;the processor doesn&amp;#8217;t matter&lt;/i&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;center&gt;&lt;h3&gt;the &amp;#8220;new&amp;#8221; technology&lt;/h3&gt;&lt;/center&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
I started off working life as a NeXTStep developer.  For those who don&amp;#8217;t know, NeXTStep was a product of Steve Jobs&amp;#8217; &lt;i&gt;other&lt;/i&gt; computer company, &lt;b&gt;NeXT&lt;/b&gt;, the one he created during the &amp;#8220;dark years&amp;#8221; (ca 1985-1997) that he wasn&amp;#8217;t with Apple.  NeXT was a financial failure, but they created some great technology, both hardware and software.  The software, in the form of the NeXTStep operating system and development environment, makes up the underpinnings of Mac OS X.  I have always held the opinion that Mac OS X could more accurately be called &amp;#8220;NeXTStep 5.0&amp;#8221;.&lt;br /&gt;
&lt;p /&gt;Anyway, back in the early 90&amp;#8217;s, NeXTStep ran only on NeXT&amp;#8217;s own hardware, great beastly black boxes with Motorola 680&amp;#215;0 processors.  The hardware was technologically similar to top-of-the-line Macs of that era, but typically with much larger screens, larger hard disks, more &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt;, and a much higher price tag.  In 1993, NeXT announced that they were getting out of the hardware business entirely, and were going to focus on the NeXTStep operating system, which they had secretly ported to&amp;#8230; Intel!  Does this sound familiar to anyone?&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
So what was a developer to do?  Well, in most cases, they could simply compile their software for Intel by clicking a single checkbox in the NeXTStep &lt;span class=&quot;caps&quot;&gt;IDE&lt;/span&gt;.  The compiler would then compile the code for both platforms, and bundle them together into what could have been called a &amp;#8220;universal binary&amp;#8221;&lt;sup&gt;&lt;a name=&quot;unibinstar&quot; href=&quot;#unibinfoot&quot;&gt;&lt;strong&gt;&lt;/a&gt;&lt;/sup&gt; (again, does this sound familiar?).  This would then run on both Motorola-based NeXT machines and Intel-based PCs.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Not content to stop there, NeXT also ported their operation system to run on Sun &lt;span class=&quot;caps&quot;&gt;SPARC&lt;/span&gt; workstations and HP HP-&lt;span class=&quot;caps&quot;&gt;RISC&lt;/span&gt; workstations.  And as a developer, all you had to do was click on the checkboxes to enable those platforms, and off you went!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
But could it really be that easy?  Well, in a word: &lt;b&gt;&lt;span class=&quot;caps&quot;&gt;YES&lt;/span&gt;&lt;/b&gt;.  If you didn&amp;#8217;t do much low-level bit-flipping, it really was pretty much that easy.  So much so that freeware developers routinely released &amp;#8220;quad-fat applications&amp;#8221; that ran on all four platforms, &lt;i&gt;even if they never had access to one or more of the target platforms for testing&lt;/i&gt;.  They&amp;#8217;d just put it out there, say &amp;#8220;email me if it doesn&amp;#8217;t work right on your machine&amp;#8221;, and call it a day.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Of course, there are applications that require low-level bit-flipping, but that can usually be done with per-platform compiler macros and what have you, so you can abstract that away and off you go.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
So, we jump forward twelve years in time and arrive at last week.  Apple announces technology that old NeXT nerds like me have always known they&amp;#8217;ve had, and that we know works.  Hell, even people who&amp;#8217;ve been Apple nerds since 1997 or 1998 or so should remember that the early, pre-release &amp;#8220;Rhapsody&amp;#8221; versions of Mac OS X ran both on old Apple G3s and Intel PCs.  So really, the technology is not new and has been obviously under the covers ever since Apple acquired NeXT, who &lt;b&gt;nailed this a decade ago&lt;/b&gt;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;i&gt;&lt;a name=&quot;unibinfoot&quot; href=&quot;#unibinstar&quot;&gt;[&lt;/strong&gt;&lt;/a&gt; But of course, it wasn&amp;#8217;t called that.  It was called a &amp;#8220;fat binary&amp;#8221;.  No one ever accused NeXT of being especially good at marketing.&lt;/i&gt;&lt;br /&gt;
&lt;center&gt;&lt;h3&gt;hardware orphans&lt;/h3&gt;&lt;/center&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
One concern I&amp;#8217;ve heard thrown about is that &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; hardware will be &amp;#8220;orphaned&amp;#8221;.  Although this will surely happen at some point, it&amp;#8217;s still &lt;b&gt;years&lt;/b&gt; away;  everyone using current hardware will be able to use it several years into the future.  Look at it this way:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Currently, Mac OS X can run on every Mac released since 1998, from the very first bondi blue iMac all the way up the chain.  This is &lt;b&gt;millions&lt;/b&gt; of machines.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The Intel version won&amp;#8217;t be readily available until mid-2006 (Apple&amp;#8217;s estimate) at the earliest.  Many developers won&amp;#8217;t bother shipping universal binaries until then.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Intel won&amp;#8217;t take over the whole line until at least late 2007 (Apple&amp;#8217;s estimate) or, more likely, 2008.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Therefore, Apple won&amp;#8217;t be shipping all-Intel Macs until perhaps &lt;b&gt;nearly three years from now&lt;/b&gt;.  No developer in their right mind would ditch &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; support any time before that.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Even when Macs are all-Intel, there will remain a huge &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; user community.  Unless Mac sales go up dramatically after the Intel release (we can hope), it will take several years before the numbers of Intel Macs equal the number of &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; Macs.  My guess, we&amp;#8217;re talking at least 2010.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Until the numbers of Intel Macs seriously overtake the number of &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; Macs, smart developers will support both platforms.  So maybe 5 years from now we&amp;#8217;ll start to see significant amounts of Intel-only software, but many developers will probably continue to ship universal binaries much longer than that, since they will keep access to the &lt;span class=&quot;caps&quot;&gt;PPC&lt;/span&gt; users &amp;#8220;for free&amp;#8221;.&lt;/li&gt;&lt;/p&gt;
&lt;p&gt;&lt;/ul&gt;&lt;p /&gt;&lt;br /&gt;
I believe that 5 years is a pretty good amount of time for people to think about buying some new hardware, so I really don&amp;#8217;t think this is going to be too painful.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The only real scenarios I can see being problematic are where people are running specific &lt;span class=&quot;caps&quot;&gt;PCI&lt;/span&gt; hardware such as for high-end audio/video applications;  If your manufacturer can&amp;#8217;t or won&amp;#8217;t create new drivers for MacIntel (if they&amp;#8217;ve stopped caring about their Mac products, or have gone out of business, or whatever), you&amp;#8217;ll probably have to buy new extra hardware for your special needs when you switch to MacIntel.  But in five years time, you&amp;#8217;d probably want to replace it anyway, since considering the march of progress, today&amp;#8217;s &amp;#8220;top-of-the-line&amp;#8221; audio gear is tomorrow&amp;#8217;s &amp;#8220;free-with-your-subscription-to-PC-user-magazine&amp;#8221; throwaway kit, so hey.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>acko acko</title>
   <link href="http://localhost:4000/blog/2005/06/14/acko-acko/"/>
   <updated>2005-06-14T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/06/14/acko-acko</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;&lt;i&gt;(I never thought it would come to this, but here I am: blogging about Michael Jackson.  Hopefully this is the only time.)&lt;/i&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
So, the big &amp;#8220;not guilty&amp;#8221; judgement came down the pike yesterday.  I&amp;#8217;m not plugged-in to the 24/7 American disinfo feed (&lt;span class=&quot;caps&quot;&gt;FAUX&lt;/span&gt; News, &lt;span class=&quot;caps&quot;&gt;CNN&lt;/span&gt;, etc) so I didn&amp;#8217;t hear this important news until this morning when I awoke to hear the TV saying &amp;#8220;Michael Jackson blah blah king of pop blah blah&amp;#8221; followed by my wife calling out &amp;#8220;Michael Jackson&amp;#8217;s &lt;b&gt;&lt;span class=&quot;caps&quot;&gt;DEAD&lt;/span&gt;&lt;/b&gt;!!!&amp;#8221;  That kidder.  As if.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Anyway.  I caught a clip of some jurors talking about the reasons for their decision, and one of the explanations was that no sound parent would let their child attend sleepovers at Michael Jackson&amp;#8217;s house.  Let&amp;#8217;s lay this out:&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;Michael Jackson is a known freak.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;That mom let her son stay at Michael Jackson&amp;#8217;s house.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;No good mom would allow that.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Therefore, that&amp;#8217;s a bad mom.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Therefore, Michael Jackson is innocent.&lt;/li&gt;&lt;/p&gt;
&lt;/ol&gt;
&lt;p /&gt;
&lt;p&gt;Now, I know a little bit about logic, and I think that the jump from step 4 to step 5 there is a little wide.  But then I&amp;#8217;m no legal expert, and the &lt;b&gt;law&lt;/b&gt; surely can&amp;#8217;t be held back by something like logic.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
This reminds me of the &lt;a href=&quot;http://en.wikipedia.org/wiki/Chewbacca_Defense&quot;&gt;Chewbacca defense&lt;/a&gt;, a Johnny Cochran parody defense in South Park, which (in extremely shortened form) goes something like this:&lt;br /&gt;
&lt;ol&gt;&lt;br /&gt;
&lt;li&gt;Look at this picture of Chewbacca.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Chewbacca is a Wookie.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;That makes no sense.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Therefore, my client is innocent!  You must acquit!&lt;/li&gt;&lt;/p&gt;
&lt;/ol&gt;</content>
 </entry>
 
 <entry>
   <title>In *my* day, phishing was done properly</title>
   <link href="http://localhost:4000/blog/2005/06/07/in-my-day-phishing-was-done-properly/"/>
   <updated>2005-06-07T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/06/07/in--my--day--phishing-was-done-properly</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;I tell you what, phishing attacks ain&amp;#8217;t what they used to be.  It used to be that internet hucksters really tried their best to make their pitches seems realistic, but I feel like the scam artists are just getting plain old sloppy.  Take a look at the latest in my inbox.  I&amp;#8217;ve taken the liberty of marking obvious spelling errors in red:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
	From: 	  paypal@mail.paypal.com&lt;br /&gt;
&lt;br /&gt;	Subject: 	Security Center Advisory&lt;br /&gt;
&lt;br /&gt;	Date: 	June 6, 2005 8:02:55 AM &lt;span class=&quot;caps&quot;&gt;CEST&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;	To: 	  Jack&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
We Recently noticed one or more attempts to log in to your PayPal account from foreign IP adress and we have reasons to believe that your account was hijacked by a third party without your authorization&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
If you recently noticed one or more attempts your account while traveling, the unusual log in attempts may have been initiated by you. However, if your are rightful holder of the account, click on the link below to log into your account and &lt;font color=&quot;red&quot;&gt;fallow&lt;/font&gt; the &lt;font color=&quot;red&quot;&gt;intrusctions&lt;/font&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;u&gt;&lt;font color=&quot;blue&quot;&gt;https://www.paypal.com/cgi-bin/webscr?cmd=login-run&lt;/font&gt;&lt;/u&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
If you choose to ignore our request, you leave us no &lt;font color=&quot;red&quot;&gt;choise&lt;/font&gt; but &lt;font color=&quot;red&quot;&gt;not tempor  aly&lt;/font&gt; suspend account.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
We ask that you &lt;font color=&quot;red&quot;&gt;fallow&lt;/font&gt; at least 72 hours for the case to be investigated and we strongly &lt;font color=&quot;red&quot;&gt;recomanded&lt;/font&gt; to verify your account in that time.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
If you &lt;font color=&quot;red&quot;&gt;recived&lt;/font&gt; this notice and you are not the authorized account holder, please be aware that it is in violation of PayPal policy to represent oneself as another PayPal user.Such action may also be in violation of local, national, and/or international law. Paypal is misappropriate at the request of law enforment agencies to ensure that perpetrators are prosecuted to the fullest extent of the law.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Thanks for your &lt;font color=&quot;red&quot;&gt;patiance&lt;/font&gt; as we work &lt;font color=&quot;red&quot;&gt;togheter&lt;/font&gt; to protect your account.&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
Sincerly,&lt;br /&gt;
PayPal Account Review Department&lt;br /&gt;
PayPal, an ebay Company&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Please do not respond to this e-mail adress as your reply will not be &lt;font color=&quot;red&quot;&gt;recived&lt;/font&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Don&amp;#8217;t even get me started on the grammar; the bad spelling just screams out &amp;#8220;bullshit!&amp;#8221;  Not that I&amp;#8217;m super-uptight about spelling or anything, but the super-scary warning supposedly from paypal lost its effect when they &amp;#8220;recomanded&amp;#8221; me to &amp;#8220;fallow the intrusctions&amp;#8221;.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
For some reason I feel a little sorry for these jackasses, so I offer up some tips in the interests of helping my fellow men (even when they are maggots):&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Use a spell-checker before sending out your text.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Have a native English speaker proofread your text.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Don&amp;#8217;t include ludicrous warnings like &amp;#8220;don&amp;#8217;t reply to this email, we won&amp;#8217;t get it&amp;#8221;.  What kind of company sends warnings by email but can&amp;#8217;t receive email in return?  Think, dumbass!&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;If you must include a paragraph warning people not to break they law (working under the assumption that people will automatically believe anyone who quotes laws at them), at least try to make some sense.  &amp;#8220;Paypal is misappropriate at the request of law enforment&amp;#8230;&amp;#8221; ???  That dog won&amp;#8217;t hunt, slim.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Above all, try to think up a plausible story as to why the mark should click your link and give up their password.  I mean, what&amp;#8217;s with this warning about a &amp;#8220;foreign IP address&amp;#8221;?  Foreign compared to what?  You mean it&amp;#8217;s not an address in the US?  Or what?  And how the hell would you know?  And do you know what country the mark is in?  This kind of bullshit just shows that the person who wrote it not only can&amp;#8217;t write clearly, they can&amp;#8217;t even &lt;b&gt;think&lt;/b&gt; clearly.&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;p /&gt;Hopefully these tips will help improve the quality of the phishing attempts I get in my email.  If not, I&amp;#8217;m going to have to give you all a big fat &lt;b&gt;F&lt;/b&gt; pretty soon.&lt;/li&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>Ten Most Harmful Books of the 19th and 20th Centuries</title>
   <link href="http://localhost:4000/blog/2005/06/05/ten-most-harmful-books-of-the-19th-and-20th-centuries/"/>
   <updated>2005-06-05T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/06/05/ten-most-harmful-books-of-the-19th-and-20th-centuries</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;This link was passed to me by &lt;a href=&quot;http://peoplesflag.blogspot.com/&quot;&gt;James&lt;/a&gt;:&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.humaneventsonline.com/article.php?id=7591&quot;&gt;http://www.humaneventsonline.com/article.php?id=7591&lt;/a&gt;&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
This is a &amp;#8220;top ten&amp;#8221; (plus lots of &amp;#8220;honorable mentions&amp;#8221;) compiled by a bunch of conservervate, errr, &amp;#8220;thinkers&amp;#8221;.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
The list includes some obvious punching bags for the right (The Communist Manifesto), at least one obvious punching bag for most everyone (Mein Kampf), but a bunch of titles that I&amp;#8217;m frankly surprised that any group of intelligent people, including plenty of college professors, can consider to be &amp;#8220;harmful&amp;#8221;.  For example:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=rebisoft-20&amp;amp;creative=9325&amp;amp;path=ASIN/0253334128/qid=1117803059/sr=2-1/ref=pd_bbs_b_2_1&quot;&gt;The Kinsey Report&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;br /&gt;
John Dewey&amp;#8217;s &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=rebisoft-20&amp;amp;creative=9325&amp;amp;path=ASIN/0684836319/qid=1117802823/sr=2-1/ref=pd_bbs_b_2_1&quot;&gt;Democracy and Education&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;br /&gt;
John Stuart Mills&amp;#8217; &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=rebisoft-20&amp;amp;creative=9325&amp;amp;path=ASIN/0140432078/qid=1117802884/sr=2-1/ref=pd_bbs_b_2_1&quot;&gt;On Liberty&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;br /&gt;
Ralph Nader&amp;#8217;s &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?link_code=ur2&amp;amp;camp=1789&amp;amp;tag=rebisoft-20&amp;amp;creative=9325&amp;amp;path=ASIN/1583220577/qid=1117803102/sr=2-1/ref=pd_bbs_b_2_1&quot;&gt;Unsafe at Any Speed&lt;/a&gt;&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p /&gt;
&lt;p&gt;Sure, if I were a conservative I would probably consider most of these works uncomfortable, or unpleasant, but &lt;span style=&quot;font-style: italic&quot;&gt;harmful&lt;/span&gt;?  How detached from reality does one need to be, to consider &amp;#8220;Unsafe at Any Speed&amp;#8221; &lt;span style=&quot;font-style: italic&quot;&gt;harmful&lt;/span&gt;?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Bill Moyers</title>
   <link href="http://localhost:4000/blog/2005/05/17/bill-moyers/"/>
   <updated>2005-05-17T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/05/17/bill-moyers</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;I just read this &lt;a href=&quot;http://www.democracynow.org/article.pl?sid=05/05/16/1329245#transcript&quot; title=&quot;http://www.democracynow.org/article.pl?sid=05/05/16/1329245#transcript&quot;&gt;transcript&lt;/a&gt; of Bill Moyers talking about the &lt;a href=&quot;http://www.pbs.org/now/&quot; title=&quot;NOW | PBS&quot;&gt;&lt;span class=&quot;caps&quot;&gt;NOW&lt;/span&gt;&lt;/a&gt; show he used to host on &lt;span class=&quot;caps&quot;&gt;PBS&lt;/span&gt; before retiring.  Living in Sweden as I do, I&amp;#8217;ve never seen the show (except for short clips here and there), but I have read transcripts now and then, and have great respect for Bill Moyers as a journalist.&lt;br /&gt;
&lt;p /&gt;So I was curious what the deal was when I read that &lt;span class=&quot;caps&quot;&gt;PBS&lt;/span&gt; leadership had been pressed by right wingers in the administration into trying to make &lt;span class=&quot;caps&quot;&gt;PBS&lt;/span&gt; more &amp;#8220;balanced&amp;#8221; (i.e. make them tow the party line).  Fortunately Bill Moyers has come forward to talk about these events and share some opinions.  Here are some good bits.&lt;br /&gt;
&lt;p /&gt;On his detractors:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
Who are they? I mean the people obsessed with control using the government to threaten and intimidate; I mean the people who are hollowing out middle class security even as they enlist the sons and daughters of the working class to make sure Ahmad Chalabi winds up controlling Iraq&amp;#8217;s oil; I mean the people who turn faith-based initiatives into Karl Rove&amp;#8217;s slush fund; who encourage the pious to look heavenward and pray so as not to see the long arm of privilege and power picking their pockets; I mean the people who squelch free speech in an effort to obliterate dissent and consolidate their orthodoxy into the official view of reality from which any deviation becomes unpatriotic heresy. That&amp;#8217;s who I mean. And if that&amp;#8217;s editorializing, so be it. A free press is one where it&amp;#8217;s okay to state the conclusion you&amp;#8217;re led to by the evidence.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;p /&gt;And here&amp;#8217;s a good bit:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
Hear me: an unconscious people, an indoctrinated people, a people fed only partisan information and opinion that confirm their own bias, a people made morbidly obese in mind and spirit by the junk food of propaganda is less inclined to put up a fight, ask questions and be skeptical. And just as a democracy can die of too many lies, that kind of orthodoxy can kill us, too.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;p /&gt;You the man, Bill.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tiger Bush Panic</title>
   <link href="http://localhost:4000/blog/2005/04/29/tiger-bush-panic/"/>
   <updated>2005-04-29T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2005/04/29/tiger-bush-panic</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;I&amp;#8217;ve just released BushPanic 1.0.1.  This is a bugfix release, so far built only for Mac.  The bugs fixed are:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;The last level was inherently unwinnable.  You couldn&amp;#8217;t even really get a fair start.  This is fixed.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The 1.0.0 release turned out to not work on Mac OS X 10.4 (&amp;#8220;Tiger&amp;#8221;).  This is now fixed.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Go to the &lt;a href=&quot;http://www.nuthole.com/software_bushpanic.php&quot;&gt;BushPanic page&lt;/a&gt; to download the latest badness.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>hooray internet</title>
   <link href="http://localhost:4000/blog/2005/02/10/hooray-internet/"/>
   <updated>2005-02-10T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/02/10/hooray-internet</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Comments are back online.  I&amp;#8217;ve fixed things so that the spamming won&amp;#8217;t occur again, hopefully.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>stupid internet</title>
   <link href="http://localhost:4000/blog/2005/01/04/stupid-internet/"/>
   <updated>2005-01-04T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2005/01/04/stupid-internet</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Some damned punk spammed the comments.  I&amp;#8217;ve cleaned it up, but posting new comments is disabled until further notice&amp;#8230;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I am .mpg</title>
   <link href="http://localhost:4000/blog/2004/11/11/i-am-mpg/"/>
   <updated>2004-11-11T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/11/11/i-am--mpg</id>
   <content type="html">&lt;p&gt;&lt;p/&gt;According to this &lt;a href=&quot;http://www.bbspot.com/News/2004/10/extension_quiz.php&quot;&gt;quiz&lt;/a&gt;:&lt;br /&gt;
&lt;p/&gt;&lt;center&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.bbspot.com/News/2004/10/extension_quiz.php&quot;&gt;&lt;img
src=&quot;http://www.bbspot.com/Images/News_Features/2004/10/file_extensions/mpg.jpg&quot; width=&quot;300&quot; height=&quot;90&quot;
border=&quot;0&quot; alt=&quot;You are .mpg You live life like it was a movie.  Constantly in motion, you bring pleasure to many, but are often hidden away.&quot; /&gt;&lt;br /&gt;&lt;font size=&quot;-1&quot;&gt;Which File Extension are You?&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/center&gt;
&lt;p&gt;&lt;p /&gt;Well, that certainly beats being a .inf or a .bak, that&amp;#8217;s for sure.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Now We Are Really Fucked</title>
   <link href="http://localhost:4000/blog/2004/11/03/now-we-are-really-fucked/"/>
   <updated>2004-11-03T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/11/03/now-we-are-really-fucked</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;&lt;a href=&quot;http://tbogg.blogspot.com&quot;&gt;TBogg&lt;/a&gt; nails it:&lt;br /&gt;
&lt;blockquote&gt;&lt;p&gt;Four more years of American soldiers being used as cannon fodder.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;Four more years of scientific decisions being made by people who believe in a ghost in the clouds.&lt;/p&gt;
&lt;p&gt;Four more years of debt that our children and grandchildren will have to pay off.&lt;/p&gt;
&lt;p&gt;Four more years of racists and lunatics for judicial appointments&lt;/p&gt;
&lt;p&gt;Four more years of looting the treasury and squandering it on corporate cronies.&lt;/p&gt;
&lt;p&gt;Four more years of making enemies faster than we can kill them.&lt;/p&gt;
&lt;p&gt;Four more years of fear and darkness and racism and hatred and stupidity and guns and bad country music.&lt;/p&gt;
&lt;p&gt;I look at the big map and all of the red in flyover country and I feel like I&amp;#8217;ve been locked in a room with the slow learners. We have become the country that pulls a dry cleaning bag over its head to play astronaut.&lt;/p&gt;&lt;/blockquote&gt;</content>
 </entry>
 
 <entry>
   <title>BushPanic 1.0.0</title>
   <link href="http://localhost:4000/blog/2004/10/29/bushpanic-1-0-0/"/>
   <updated>2004-10-29T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/10/29/bushpanic-1-0-0</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Now available for both Mac and Windows, it&amp;#8217;s about time for some &lt;b&gt;BushPanic&lt;/b&gt;.&lt;br /&gt;
&lt;a href=&quot;http://www.nuthole.com/bp_data/BushPanic.png&quot;&gt;&lt;img src=&quot;http://www.nuthole.com/bp_data/BushPanic.png&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; width=&quot;320&quot; height=&quot;240&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;p /&gt;Click &lt;a href=&quot;http://www.nuthole.com/software_bushpanic.php&quot;&gt;here&lt;/a&gt; for details on this crazy new shoot&amp;#8217;em&amp;#8217;up.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>spinvaders 0.0.3</title>
   <link href="http://localhost:4000/blog/2004/09/18/spinvaders-0-0-3/"/>
   <updated>2004-09-18T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/09/18/spinvaders-0-0-3</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Another two months, another handful of new changes.&lt;br /&gt;
&lt;p /&gt;(It&amp;#8217;s amazing how little spare time one can find to work on hobby projects during vacation and parental leave)&lt;br /&gt;
&lt;img src=&quot;http://www.nuthole.com/spinvaders/spinvaders_0_0_3.png&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Cleaned up event handling code;  this should fix some bizarre hanging problems.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Smoothed out the falling monster trail.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Enhanced alien explosion clouds.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Levels are now differentiated further.  Earlier levels have fewer enemies.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;After every five levels you are given a level skip code.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;There are now &amp;#8220;super aliens&amp;#8221; which require two hits with the normal weapon (or one with the super gun) to kill them.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;High-score table!&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;And here&amp;#8217;s where to get it:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;/spinvaders/spinvaders_0_0_3.dmg&quot;&gt;spinvaders&lt;/a&gt; for Macintosh (OS X 10.3 or later)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;No windows build of spinvaders 0.0.3 is available at this time&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Installation is the same as before:  The Mac version is in a disk image; you can copy the enclosed application and run it from wherever you like.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>What you readin' for?</title>
   <link href="http://localhost:4000/blog/2004/09/02/what-you-readin-for/"/>
   <updated>2004-09-02T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/09/02/what-you-readin--for-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;At the risk of turning this blog into an endless list of political essays you should read elsewhere, here are a couple more: &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.smirkingchimp.com/print.php?sid=17656&quot; title=&quot;High plains grifter: The life and crimes of George W. Bush&quot;&gt;High plains grifter: The life and crimes of George W. Bush&lt;/a&gt; is sort of a Cliff&amp;#8217;s notes version of Molly Ivins&amp;#8217; excellent &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;path=tg/detail/-/0375757147/qid%3D1094133926/sr%3D1-1&quot;&gt;Shrub&lt;/a&gt; for people who don&amp;#8217;t have time to read that.  Incidentally, everyone who didn&amp;#8217;t already read &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;path=tg/detail/-/0375757147/qid%3D1094133926/sr%3D1-1&quot;&gt;Shrub&lt;/a&gt; years ago should really do so.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.retrovsmetro.org/book/&quot;&gt;The Great Divide&lt;/a&gt; offers a new approach to dividing the American nation into two:  Instead of republican vs. democrat, it&amp;#8217;s &amp;#8220;metro vs. retro&amp;#8221;.  I haven&amp;#8217;t read this yet, but it seems interesting, not least because in addition to being able to &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;path=tg/detail/-/0976062100/qid%3D1094134289/sr%3D1-1&quot;&gt;buy it from Amazon&lt;/a&gt;, you can also &lt;a href=&quot;http://www.retrovsmetro.org/book/&quot;&gt;download the whole thing for free&lt;/a&gt;, which I heartily applaud.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>McCain shows his true colors</title>
   <link href="http://localhost:4000/blog/2004/08/31/mccain-shows-his-true-colors/"/>
   <updated>2004-08-31T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/08/31/mccain-shows-his-true-colors</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;In democratic circles, John McCain is often considered to be fairly tolerable (for a republican), and is sometimes thought to be somewhat &amp;#8220;like us&amp;#8221;, since he has had some public disagreements with Bush&amp;#8217;s policies.&lt;br /&gt;
&lt;p /&gt;At the &lt;span class=&quot;caps&quot;&gt;RNC&lt;/span&gt; yesterday, however, most of this went out the window, at least as far as I&amp;#8217;m concerned.  McCain made a clear jab at Michael Moore (which Moore seemed to take pretty well) in the midst of his praise of the Bush regime&amp;#8217;s foreign policy mess:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&amp;#8220;Our choice wasn&amp;#8217;t between a benign status quo and the bloodshed of war. It was between war and a graver threat.  Don&amp;#8217;t let anyone tell you otherwise &amp;#8212; not our political opponents, and certainly not a disingenuous filmmaker [&amp;#8230;]  who would have us believe that Saddam&amp;#8217;s Iraq was an oasis of peace when, in fact, it was a place of indescribable cruelty, torture chambers, mass graves, and prisons that destroyed the lives of the small children held inside their walls.&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Frankly, I&amp;#8217;m beginning to get pretty tired of this sort of straw-man argument where the liars of the right claim that anyone who questions Bush&amp;#8217;s policies is actually a big Saddam supporter.  When has Moore, or any liberal for that matter, ever claimed that &amp;#8220;Saddam&amp;#8217;s Iraq was an oasis of peace&amp;#8221; or anything similar?  On the contrary, well-informed liberals have been critical of Saddam since the 70&amp;#8217;s and 80&amp;#8217;s, since even before the time when &lt;a href=&quot;http://www.gwu.edu/~nsarchiv/NSAEBB/NSAEBB82/&quot;&gt;the Gipper sent Rummy to shake the old bastard&amp;#8217;s hand&lt;/a&gt; and sell him some weapons.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Not in Lake Wobegon Anymore</title>
   <link href="http://localhost:4000/blog/2004/08/30/not-in-lake-wobegon-anymore/"/>
   <updated>2004-08-30T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/08/30/not-in-lake-wobegon-anymore</id>
   <content type="html">&lt;p&gt;Garrison Keiller wrote a nice essay with the incredibly long title &amp;quot;&lt;a href=&quot;http://www.inthesetimes.com/site/main/article_rss/were_not_in_lake_wobegon_anymore/&quot; title=&quot;We're Not in Lake Wobegon Anymore: How did the Party of Lincoln and Liberty transmogrify into the party of Newt Gingrich's evil spawn and their Etch-A-Sketch president, a dull and rigid man, whose philosophy is a jumble of badly sutured body parts trying to walk? -- In These Times&quot;&gt;We&amp;#8217;re Not in Lake Wobegon Anymore: How did the Party of Lincoln and Liberty transmogrify into the party of Newt Gingrich&amp;#8217;s evil spawn and their Etch-A-Sketch president, a dull and rigid man, whose philosophy is a jumble of badly sutured body parts trying to walk? &amp;#8212; In These Times&lt;/a&gt;&amp;quot; which everybody should read.  A choice quote:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
[&amp;#8230;] angry white men who rose to power on pure punk politics. &amp;quot;Bipartisanship is another term of date rape,&amp;quot; says Grover Norquist, the Sid Vicious of the &lt;span class=&quot;caps&quot;&gt;GOP&lt;/span&gt;. &amp;quot;I don&amp;#8217;t want to abolish government. I simply want to reduce it to the size where I can drag it into the bathroom and drown it in the bathtub.&amp;quot; The boy has Oedipal problems and government is his daddy.&lt;/p&gt;
&lt;/blockquote&gt;</content>
 </entry>
 
 <entry>
   <title>Conservatism</title>
   <link href="http://localhost:4000/blog/2004/08/19/conservatism/"/>
   <updated>2004-08-19T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/08/19/conservatism</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;An interesting but &lt;b&gt;huge&lt;/b&gt; article explains what conservatism really boils down to (maintaining a ruling aristocracy) and the tricks used to keep this antiquated world-view in power.  &lt;a href=&quot;http://polaris.gseis.ucla.edu/pagre/conservatism.html&quot;&gt;Check it out&lt;/a&gt; if you&amp;#8217;ve got a half-hour to burn.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>You have become a monster, George</title>
   <link href="http://localhost:4000/blog/2004/08/18/you-have-become-a-monster-george/"/>
   <updated>2004-08-18T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/08/18/you-have-become-a-monster--george</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Check out William Rivers Pitt&amp;#8217;s excellent &lt;a href=&quot;http://www.truthout.org/docs_04/081704A.shtml&quot;&gt;open letter to George W. Bush&lt;/a&gt;.  Good stuff from &lt;a href=&quot;http://www.truthout.org&quot;&gt;truthout&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>sleepiness</title>
   <link href="http://localhost:4000/blog/2004/08/13/sleepiness/"/>
   <updated>2004-08-13T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/08/13/sleepiness</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;OK, things have been pretty quiet around here.  I&amp;#8217;ve been busy with traveling and ongoing parental leave, but at some point soon I&amp;#8217;ll get back on track with the nuthole, and hopefully post a new version of &lt;a href=&quot;/compute/programming/spinvaders&quot;&gt;spinvaders&lt;/a&gt; soon.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>spinvaders 0.0.2</title>
   <link href="http://localhost:4000/blog/2004/06/08/spinvaders-0-0-2/"/>
   <updated>2004-06-08T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/06/08/spinvaders-0-0-2</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;A few small steps forward in the life of &lt;b&gt;spinvaders&lt;/b&gt;:&lt;br /&gt;
&lt;img src=&quot;http://www.nuthole.com/spinvaders/spinvaders_0_0_2.png&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;ul&gt;&lt;br /&gt;
&lt;li&gt; Monsters killed with the &amp;#8220;super gun&amp;#8221; now fall burning from the sky!  Prepare to be terrified.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; New sound effects, in stereo!  Crank it up!&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; Changed player death behavior:  If monsters reach bottom, restart level.  If player is hit by a bullet, just lose a life and continue the level in progress.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; Gameplay and speeds tweaked to maximize your Fahrvergn&amp;uuml;gen.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; While the game is paused or switching screen modes, audio output is paused.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; Mac version now has a reasonable (but somewhat incomplete) menu thanks to PyObjC and a proper nib file.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; Windows version now has an icon.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; Internal code reorganisation to make my life easier.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt; Added &lt;span class=&quot;caps&quot;&gt;CHANGES&lt;/span&gt;.txt and &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt;.txt to distribution.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;And here&amp;#8217;s where to get it:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;/spinvaders/spinvaders_0_0_2.dmg&quot;&gt;spinvaders&lt;/a&gt; for Macintosh (OS X 10.3 or later)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;/spinvaders/spinvaders_0_0_2.zip&quot;&gt;spinvaders&lt;/a&gt; for Windows (95/98/ME/W2K/XP)&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Installation is the same as before:  The Mac version is in a disk image; you can copy the enclosed application and run it from wherever you like.  The Windows version is a zip file containing a directory; unpack the directory wherever you like, and run it by starting &amp;#8220;spinvaders.exe&amp;#8221; from within the directory.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Go nuts.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Support our troops?</title>
   <link href="http://localhost:4000/blog/2004/04/26/support-our-troops/"/>
   <updated>2004-04-26T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/04/26/support-our-troops-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Hmmm.  For a long time, I&amp;#8217;ve consistently held the opinion that even though the U.S invasion of Iraq is wrong-headed, that the troops who are stuck in the mess over there are worthy of support, since none of them created this war and are presumably trying to make the best of a tough situation.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
But then again, there are things like this&lt;br /&gt;
&lt;a href=&quot;http://home.swiftdsl.com.au/~glide/files/DontLoot.wmv&quot;&gt;Don&amp;#8217;t Loot&lt;/a&gt;&lt;br /&gt;
video that are just scary as all get-out.  For those who haven&amp;#8217;t/can&amp;#8217;t/won&amp;#8217;t view that clip, here&amp;#8217;s an executive summary of this brief clip from &lt;a href=&quot;http://www.pbs.org/wgbh/pages/frontline/shows/truth/view/&quot;&gt;frontline&lt;/a&gt;:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;Somewhere in Iraq, looting is occurring.  Reporters arrive on the scene.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;U.S. soldiers are there, and have arrested some men for looting.  The men have apparently taken a couple armloads of lumber and stacked it on top of their car.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;One soldier explains for the camera that &amp;#8220;We tried to stop them from looting, they don&amp;#8217;t understand, so we&amp;#8217;ll take their car and we&amp;#8217;ll crush it.&amp;#8221;&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;A couple of soldiers shoot at the car with pistols a bit.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;The soldiers crush the car by driving a tank over it.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p /&gt;
&lt;p&gt;I think that the mental exercise of reversing roles can be a useful thing to do here.  What if my country was on the verge of civil war after an invading army had removed a brutal dictator but simultaneously destroyed much of my country&amp;#8217;s infrastructure?  Perhaps lumber would be hard to come by.  Perhaps I might take advantage of available resources, particularly if it seemed like they were going unused.  I sure don&amp;#8217;t that that punishing me for this &amp;#8220;crime&amp;#8221; by crushing my only means of transportation would be a noble endeavor on the invading army&amp;#8217;s part.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>spinvaders 0.0.1</title>
   <link href="http://localhost:4000/blog/2004/04/20/spinvaders-0-0-1/"/>
   <updated>2004-04-20T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/04/20/spinvaders-0-0-1</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;In my copious amounts of spare time (ha), I&amp;#8217;ve recently been teaching myself both &lt;a href=&quot;http://www.python.org&quot;&gt;python&lt;/a&gt; and game programming using a fine cross-platform library called &lt;a href=&quot;http://www.pygame.org&quot;&gt;pygame&lt;/a&gt;.  I have some results!&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
&lt;img src=&quot;http://www.nuthole.com/spinvaders_0_0_1.jpg&quot; alt=&quot;screenshot&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;b&gt;spinvaders&lt;/b&gt; is a direct descendant of the old &amp;#8220;Space Invaders&amp;#8221; type of game.  This first public test release, version 0.0.1, is fully playable and may even be fun!  The controls for the game are described at the startup screen, everything should be pretty obvious.  One undocumented feature of this test version is that pressing &amp;#8220;J&amp;#8221; will let you jump to any level.&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;/spinvaders_0_0_1.dmg&quot;&gt;spinvaders&lt;/a&gt; for Macintosh (OS X 10.3 or later)&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;/spinvaders_0_0_1.zip&quot;&gt;spinvaders&lt;/a&gt; for Windows (95/98/ME/W2K/XP)&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;The Mac version is in a disk image; you can copy the enclosed application and run it from wherever you like.  The Windows version is a zip file containing a directory; unpack the directory wherever you like, and run it by starting &amp;#8220;spinvaders.exe&amp;#8221; from within the directory.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Please try it out and let me know what you think by adding a comment below.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>slutspurt</title>
   <link href="http://localhost:4000/blog/2004/04/14/slutspurt/"/>
   <updated>2004-04-14T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/04/14/slutspurt</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/slutspurt-01.jpg&quot; alt=&quot;slutspurt&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;br /&gt;
In Swedish, &lt;em&gt;slutspurt&lt;/em&gt; means roughly &amp;#8220;final push&amp;#8221;  and can be applied to almost anything:  the conclusion of a sporting event, the final stages of a project, etc.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
In English, Slutspurt just sounds like the name of a porn flick.  Perhaps even a whole series!&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>the revolution will not be televised</title>
   <link href="http://localhost:4000/blog/2004/04/05/the-revolution-will-not-be-televised/"/>
   <updated>2004-04-05T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/04/05/the-revolution-will-not-be-televised</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;So the glorious &lt;a href=&quot;http://www.airamericaradio.com&quot; &gt;Air America&lt;/a&gt; is off to a nice start.  I managed to listen to the first few minutes of &lt;a href=&quot;http://www.airamericaradio.com/www/pub/prg3about.htm&quot; &gt;Al Franken&lt;/a&gt;&amp;#8216;s first broadcast before Real Player crapped out (I guess the servers weren&amp;#8217;t quite up for the initial rush), and have so far only heard bits of various shows.  For some reason it seems like I mostly hear &lt;a href=&quot;http://www.airamericaradio.com/pub/prg4about.htm&quot;&gt;Randi Rhodes&lt;/a&gt; whenever I tune in, and usually she&amp;#8217;s griping about the same stuff over and over again.  I mean, she&amp;#8217;s a really good griper and all, but I&amp;#8217;d like to hear a little more variation in the griping.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
I&amp;#8217;m not that happy with the schedule since I&amp;#8217;m 6 hours ahead of New York which means that &lt;a href=&quot;http://www.airamericaradio.com/www/pub/prg3about.htm&quot; &gt;The O&amp;#8217;Franken Factor&lt;/a&gt; is splattered right across my early evening, the time of day when I&amp;#8217;m busy with giving children dinner and baths and putting them to bed, but what the heck.  I&amp;#8217;m just totally jazzed to hear talk radio that is actually critical of the Bush-Cheney Axis of Fascism for a change.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>radio free america</title>
   <link href="http://localhost:4000/blog/2004/03/31/radio-free-america/"/>
   <updated>2004-03-31T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2004/03/31/radio-free-america</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Today is the first broadcast day for &lt;a href=&quot;http://www.airamericaradio.com&quot;&gt;Air America&lt;/a&gt;, a new radio network with a radical concept:  Instead of loudmouth right-wingers commanding the airwaves, let&amp;#8217;s showcase some loudmouth leftists!  I can only welcome this.  They only have a few broadcast stations now, but there will be a live internet feed as well, which means even us overseas people will be able to listen to the likes of &lt;a href=&quot;http://www.airamericaradio.com/www/pub/prg3about.htm&quot;&gt;Al Franken&lt;/a&gt; and &lt;a href=&quot;http://www.airamericaradio.com/www/pub/prg6about.htm&quot;&gt;Janeane Garafalo&lt;/a&gt; skewering the Bush administration, etc.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Hooray!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Verified Voting</title>
   <link href="http://localhost:4000/blog/2004/03/18/verified-voting/"/>
   <updated>2004-03-18T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/18/verified-voting</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;It looks like some congressmen are taking seriously the threat to American democracy that is posed by non-voter-verifiable electronic voting machines!  The &lt;a href=&quot;http://www.verifiedvoting.org/resolution.asp&quot;&gt;Verified Voting&lt;/a&gt; campaign backs a bill, soon coming up before congress, that will require electronic voting machines to be retrofitted with a voter-verifiable paper system by November of this year!  Now might be a good time to &lt;a href=&quot;http://www.verifiedvoting.org/resolution.asp&quot;&gt;go there&lt;/a&gt;, and write or call your congressman to promote this important legislation!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>slut</title>
   <link href="http://localhost:4000/blog/2004/03/18/slut/"/>
   <updated>2004-03-18T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/18/slut</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;The Swedish word &lt;em&gt;slut&lt;/em&gt; simply means &amp;#8220;end&amp;#8221; in English.  This means that you see this word everywhere:  Ends of movies, ends of stories, etc.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>bad speling</title>
   <link href="http://localhost:4000/blog/2004/03/18/bad-speling/"/>
   <updated>2004-03-18T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/18/bad-speling</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;My fortune on &lt;a href=&quot;http://www.orkut.com&quot;&gt;orkut&lt;/a&gt; today:&lt;br /&gt;
&lt;blockquote&gt;You have an unusal equipment for success, use it propery.&lt;/blockquote&gt;&lt;br /&gt;
I wouldn&amp;#8217;t mention this if not for the fact that the short sentence contains two misspellings.  Perhaps the ability to correctly spell words is my &amp;#8220;unusal&amp;#8221; equipment.  I just hope I&amp;#8217;m using it &amp;#8220;propery&amp;#8221; now!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Diebold: Helping you pull the wool over your own eyes since 1859</title>
   <link href="http://localhost:4000/blog/2004/03/15/diebold-helping-you-pull-the-wool-over-your-own-eyes-since-1859/"/>
   <updated>2004-03-15T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/15/diebold--helping-you-pull-the-wool-over-your-own-eyes-since-1859</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I wrote &lt;a href=&quot;http://www.nuthole.com/politics/jack.joy_of_voting.html&quot;&gt;a while ago&lt;/a&gt; about the problems inherent in the various electronic voting systems being implemented throughout America.  One of the main problems is the lack of a printed record, which would allow people to see and verifty that their vote was counted correctly, as well as allow for recounts in case of close results.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Manufacturers like Diebold have been strangely reluctant to include vote-printing options in their machines.  At first they claimed technical incompetence (apparently, attaching a printer to a computer is a daunting task for Diebold), and then when they finally conceded that this technical miracle was possible, they put exorbitant prices on the printer add-ons.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Now comes the big surprise:  As &lt;a href=&quot;http://www.pbs.org/cringely/pulpit/pulpit20040311.html&quot;&gt;Robert X. Cringely&lt;/a&gt; describes in his column, the Diebold machines already have printers!  The internal printers are required by law for end-of-day vote tallies at least.  Modifying the systems to create user-verifiable printed records would require simple changes to the software, and minor enhancements to the computers&amp;#8217; casings to allow the printed receipts to be seen.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Fortunately for Diebold, the major media are still ignoring this story.  Blah.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>pukeberg</title>
   <link href="http://localhost:4000/blog/2004/03/12/pukeberg/"/>
   <updated>2004-03-12T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/12/pukeberg</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;This is perhaps not a &amp;#8220;word&amp;#8221; in some sense, but rather a proper name of a &lt;a href=&quot;http://www.pukeberg.se/en/pukesthlm.html&quot;&gt;store&lt;/a&gt; I&amp;#8217;ve seen in Stockholm and an associated brand.  I propose that the word &amp;#8220;pukeberg&amp;#8221; in English should be used to described the splatters of frozen vomit that can often be found on sidewalks near nightclub entrances in cold climates (e.g. Sweden).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>farthinder</title>
   <link href="http://localhost:4000/blog/2004/03/10/farthinder/"/>
   <updated>2004-03-10T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/10/farthinder</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;&lt;img src=&quot;http://www.nuthole.com/farthinder.jpg&quot; alt=&quot;farthinder&quot; align=&quot;right&quot; hspace=&quot;3&quot; vspace=&quot;3&quot; /&gt;&lt;br /&gt;
Although it seems like the name of a device to help prevent you from passing gas, a &lt;em&gt;farthinder&lt;/em&gt; is actually what we call a speed bump in English.&lt;br /&gt;
&lt;br clear=&quot;all&quot; /&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mega-dildos, Rush!</title>
   <link href="http://localhost:4000/blog/2004/03/09/mega-dildos-rush/"/>
   <updated>2004-03-09T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/09/mega-dildos--rush-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Not particularly new, but this &lt;a href=&quot;http://bootnewt.tripod.com/imanazi.htm&quot;&gt;hilarious audio cut-up&lt;/a&gt; of America&amp;#8217;s greatest gas-bag has him hurling his venom at himself for a change.  Incredibly funny for Limbaugh haters and lovers alike.  I bet Rush would even like it himself, especially when he&amp;#8217;s all &lt;a href=&quot;http://www.rushlimbaughonline.com/&quot;&gt;hopped-up on goofballs&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>fart</title>
   <link href="http://localhost:4000/blog/2004/03/09/fart/"/>
   <updated>2004-03-09T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/09/fart</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Today&amp;#8217;s funny Swedish word is &lt;em&gt;fart&lt;/em&gt;.  This means &amp;#8220;movement&amp;#8221; or &amp;#8220;speed&amp;#8221;.  Fortunately for English-based humorists, this is used to build lots and lots of compound words seen in road signs, shop windows, etc.  Stay tuned.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>nuthole slumber</title>
   <link href="http://localhost:4000/blog/2004/03/03/nuthole-slumber/"/>
   <updated>2004-03-03T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/03/nuthole-slumber</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Holy smokes, it&amp;#8217;s been almost a month since I last posted!  Well, hey, I&amp;#8217;ve been busy, traveling, sick, etc.  And I missed the bus.  And my dog ate my homework.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>fukt</title>
   <link href="http://localhost:4000/blog/2004/03/03/fukt/"/>
   <updated>2004-03-03T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/03/03/fukt</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Today&amp;#8217;s funny Swedish word is &lt;em&gt;fukt&lt;/em&gt;.  This means &amp;#8220;moisture&amp;#8221;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Musings on An Interview with Alex Stepanov</title>
   <link href="http://localhost:4000/blog/2004/02/05/musings-on-an-interview-with-alex-stepanov/"/>
   <updated>2004-02-05T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/02/05/musings-on-an-interview-with-alex-stepanov</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I stumbled across this interesting &lt;a href=&quot;http://www.stlport.org/resources/StepanovUSA.html&quot;&gt;interview&lt;/a&gt; with one of the creators of the &lt;span class=&quot;caps&quot;&gt;STL&lt;/span&gt; for C++.  Now, I haven&amp;#8217;t used &lt;span class=&quot;caps&quot;&gt;STL&lt;/span&gt; extensively, in fact mostly I&amp;#8217;ve just seen it as a headache when porting other people&amp;#8217;s software onto barely-supported platforms.  And I am no big fan of C++ in general.  But, there is some interesting stuff here.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Stepanov seems fairly skeptical of OO, and is mainly a proponent of C++.  He created the &lt;span class=&quot;caps&quot;&gt;STL&lt;/span&gt; as a tool for doing what he calls &lt;a href=&quot;http://www.cs.rpi.edu/~musser/gp/&quot;&gt;Generic Programming&lt;/a&gt;; As an example, he offers the example of implementing a simple &lt;tt&gt;max&lt;/tt&gt; function in C++ using Generic Programming, and claims this can&amp;#8217;t be done in Java:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
My approach works, theirs does not work. Try to implement&lt;br /&gt;
a simple thing in the object oriented way, say, &lt;tt&gt;max&lt;/tt&gt;. I do not&lt;br /&gt;
know how it can be done. Using generic programming I can write:&lt;/p&gt;
&lt;pre&gt;&amp;lt;tt&amp;gt;template &amp;amp;lt;class StrictWeakOrdered&amp;amp;gt;
inline StrictWeakOrdered&amp;amp;amp; max(StrictWeakOrdered&amp;amp;amp; x,
StrictWeakOrdered&amp;amp;amp; y) {
return x &amp;amp;lt; y ? y : x;
}

and
template &amp;amp;lt;class StrictWeakOrdered&amp;amp;gt;
inline const StrictWeakOrdered&amp;amp;amp; max(const StrictWeakOrdered&amp;amp;amp; x,
const StrictWeakOrdered&amp;amp;amp; y) {
return x &amp;amp;lt; y ? y : x;
}&amp;lt;/tt&amp;gt;
&lt;/pre&gt;
&lt;p&gt;(you do need both &amp;amp; and const &amp;amp;). And then I define what strict&lt;br /&gt;
weak ordered means. Try doing it in Java. You can&amp;#8217;t write a generic &lt;tt&gt;max()&lt;/tt&gt;&lt;br /&gt;
in Java that takes two arguments of some type and has a return value of&lt;br /&gt;
that same type. Inheritance and interfaces don&amp;#8217;t help.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;p /&gt;This is the sort of thing that I&amp;#8217;ve always disliked about Java.  Interestingly enough, this is pretty easily implemented in Objective-C.  I also love his answer to the question, &amp;#8220;What do you think of Java?&amp;#8221;:&lt;br /&gt;
&lt;blockquote&gt;&lt;/p&gt;
I spent several months programming in Java. Contrary to its authors prediction, it did not grow on me. I did not find any new insights &amp;#8211; for the first time in my life programming in a new language did not bring me new insights. It keeps all the stuff that I never use in C++ &amp;#8211; inheritance, virtuals &amp;#8211; OO gook &amp;#8211; and removes the stuff that I find useful. It might be successful &amp;#8211; after all, MS &lt;span class=&quot;caps&quot;&gt;DOS&lt;/span&gt; was &amp;#8211; and it might be a profitable thing for all your readers to learn Java, but it has no intellectual value whatsoever. Look at their implementation of hash tables. Look at the sorting routines that come with their &amp;#8220;cool&amp;#8221; sorting applet. Try to use &lt;span class=&quot;caps&quot;&gt;AWT&lt;/span&gt;. The best way to judge a language is to look at the code written by its proponents. &amp;#8220;Radix enim omnium malorum est cupiditas&amp;#8221; &amp;#8211; and Java is clearly an example of a money oriented programming (&lt;span class=&quot;caps&quot;&gt;MOP&lt;/span&gt;). As the chief proponent of Java at &lt;span class=&quot;caps&quot;&gt;SGI&lt;/span&gt; told me: &amp;#8220;Alex, you have to go where the money is.&amp;#8221; But I do not particularly want to go where the money is &amp;#8211; it usually does not smell nice there.
&lt;/blockquote&gt;
&lt;p /&gt;
&lt;p&gt;He also has some choice words about OO in general:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;span class=&quot;caps&quot;&gt;STL&lt;/span&gt; is not object oriented. I think that object orientedness is almost as much of a hoax as Artificial Intelligence. I have yet to see an interesting piece of code that comes from these OO people. In a sense, I am unfair to AI: I learned a lot of stuff from the &lt;span class=&quot;caps&quot;&gt;MIT&lt;/span&gt; AI Lab crowd, they have done some really fundamental work: Bill Gosper&amp;#8217;s Hakmem is one of the best things for a programmer to read. AI might not have had a serious foundation, but it produced Gosper and Stallman (Emacs), Moses (Macsyma) and Sussman (Scheme, together with Guy Steele). I find &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras &amp;#8211; families of interfaces that span multiple types. I find &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting &amp;#8211; saying that everything is an object is saying nothing at all. I find &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms &amp;#8211; you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p /&gt;
&lt;p&gt;The thing that strikes me reading this is that in spite of Stepanov&amp;#8217;s hostility toward OO, I think that his concepts are really orthogonal to OO concepts, and that perhaps these ideas could be combined.  In fact, I think that the problems he has with OO are based on a mixture of misunderstanding its uses, and exposure to inadequate OO languages.  Let&amp;#8217;s take those one at a time:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
I find &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras &amp;#8211; families of interfaces that span multiple types.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;p /&gt;Well, that&amp;#8217;s not so hard to handle.  Regular polymorphism as seen in all the various OO languages gets you part of the way;  If you&amp;#8217;re using Objective-C, the use of protocols gets you all the way!  I don&amp;#8217;t remember off the top of my head, but I believe this is handled quite well in Smalltalk and somewhat in Java as well.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
I find &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting &amp;#8211; saying that everything is an object is saying nothing at all.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p /&gt;
&lt;p&gt;It seems that exposure to languages that are not &amp;#8220;OO-complete&amp;#8221; has blinded Stepanov to the possibilities of the technology.  OK, turning data structures with associated specialized functions into objects amounts to little more than syntactic sugar.  But the interesting things start to happen when language elements such as method names and implementations, chunks of code, and class definitions themselves are also represented as objects.  C++ and Java offer very little in this way, compared to Smalltalk and Objective-C.&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
I find &lt;span class=&quot;caps&quot;&gt;OOP&lt;/span&gt; methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms &amp;#8211; you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p /&gt;
&lt;p&gt;I think this demonstrates that Stepanov has never had the opportunity to be knee-deep in an OO design project.  &amp;#8220;Starting with classes&amp;#8221; is fundamentally &lt;em&gt;unlike&lt;/em&gt; &amp;#8220;starting with axioms&amp;#8221;.  A different analogy could be that classes correspond to proofs, and axioms correspond to complete applications.  In any case, OO technology is generally used in a top-down approach for building applications that someone might want to use, so in a sense, yes, you are defining an outcome (the &amp;#8220;axiom&amp;#8221; you&amp;#8217;re shooting for) before you work on the pieces (or &amp;#8220;proofs&amp;#8221;).  But then, OO programming isn&amp;#8217;t mathematics, and I think it&amp;#8217;s not very helpful to frame it that way.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
I may be going out on a limb here, but I think that for most OO programmers, the algorithms we were taught in school have little use in real-world applications.  Certainly there are specialized algorithms for all kinds of specific uses (in finance, graphics, encryption, compression, etc), but &lt;span class=&quot;caps&quot;&gt;IMHO&lt;/span&gt; most OO technology these days is used for moving and reorganizing data, and presenting it to the user.  When you do need to massage data with any advanced algorithm, you&amp;#8217;re generally dealing with data that is fairly homogenous (as far as type is concerned) and often packed into a structure you&amp;#8217;ve designed specifically to optimize the algorithm in question;  So what&amp;#8217;s the point of genericizing algorithms?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>the best bible ever</title>
   <link href="http://localhost:4000/blog/2004/02/03/the-best-bible-ever/"/>
   <updated>2004-02-03T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/02/03/the-best-bible-ever</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;One of the funnier uses of Legos I&amp;#8217;ve seen, &lt;a href=&quot;http://www.thebricktestament.com/&quot; &gt;The Brick Testament&lt;/a&gt; depicts loads of famous bible scenes using Lego bricks and minifigs.  In addition to a graphic depiction of &lt;a href=&quot;http://www.thebricktestament.com/genesis/cain_and_abel/gn04_01a.html&quot;&gt;Adam and Eve copulating&lt;/a&gt;, you&amp;#8217;ll also see &lt;a href=&quot;http://www.thebricktestament.com/exodus/the_ark_of_the_covenant/ex25_10-14.html&quot;&gt;Moses building the Ark of the Covenant&lt;/a&gt;, &lt;a href=&quot;http://www.thebricktestament.com/the_gospels/jesus_is_born/lk01_35.html&quot;&gt;Mary&amp;#8217;s encounter with the Holy Spirit&lt;/a&gt;, and of course &lt;a href=&quot;http://www.thebricktestament.com/the_gospels/the_crucifixion/jn19_16_lk23_32.html&quot;&gt;the crucifixion&lt;/a&gt;.  As if that weren&amp;#8217;t enough, you can even get this in &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/1931686459/rebisoft-20&quot;&gt;book form&lt;/a&gt;.  Time to throw out your boring old text bibles!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The evil of iTunes</title>
   <link href="http://localhost:4000/blog/2004/01/23/the-evil-of-itunes/"/>
   <updated>2004-01-23T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/23/the-evil-of-itunes</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;OK, I don&amp;#8217;t really think &lt;a href=&quot;http://www.apple.com/itunes&quot;&gt;iTunes&lt;/a&gt; is evil.  In fact, I think it&amp;#8217;s a pretty darn great application for its original purpose:  Organizing and playing mp3 files. &lt;br /&gt;
&lt;p /&gt;What &lt;a href=&quot;http://www.downhillbattle.org/itunes/index.html&quot;&gt;this site&lt;/a&gt; points out however is that the iTunes Music Store, Apple&amp;#8217;s marvelously successful online music store, unfortunately does little or nothing to improve the situation of the artists who are screwed every which way by the giant record labels (a situation described surprisingly well years ago by &lt;a href=&quot;http://dir.salon.com/tech/feature/2000/06/14/love/index.html&quot;&gt;Courtney Love&lt;/a&gt;).&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>there it is</title>
   <link href="http://localhost:4000/blog/2004/01/21/there-it-is/"/>
   <updated>2004-01-21T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/21/there-it-is</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I finished reading &lt;i&gt;&lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0446532231/rebisoft-20&quot;&gt;Dude, Where&amp;#8217;s My Country&lt;/a&gt;&lt;/i&gt; a couple of days ago.  It&amp;#8217;s a very quick read, and pretty much follows the mold of Michael Moore&amp;#8217;s &lt;a href=&quot;http://www.amazon.com/exec/obidos/external-search?tag=rebisoft-20&amp;keyword=Michael%20Moore&amp;mode=books&quot;&gt;other books&lt;/a&gt;&lt;br /&gt;
, but there&amp;#8217;s some interesting new content in there, including:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;The concept of &lt;a href=&quot;http://www.texassportfishing.com/editorial_5.htm&quot;&gt;Dead Peasants Insurance&lt;/a&gt;.  This was a new one to me, and if you haven&amp;#8217;t heard of this before, prepare to be disgusted:  Large corporations including Disney, Dow Chemical, and Walmart routinely purchase life insurance insurance policies for their employees &amp;#8211; &lt;i&gt;wherein the company is the beneficiary!&lt;/i&gt;  So if you work for one of these companies and have no life insurance of your own, and you have the misfortune of dying, your widow and children will be left penniless while your erstwhile employer rakes in &lt;a href=&quot;http://conscience.notfrisco2.com/archives/003626.html&quot;&gt;hundreds of thousands of dollars&lt;/a&gt;!  I understand that this kind of thing is legal (so far), but man, that is sleazy.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;Moore claims that numerous polls show that Americans are, on average, more progressive on most issues than commonly believed.  My standpoint is to initially assume that he&amp;#8217;s accurately citing poll data (based on the principal of &amp;quot;&lt;a href=&quot;http://www.michaelmoore.com/words/wackoattacko/&quot;&gt;innocent&lt;/a&gt; until &lt;a href=&quot;http://slannder.homestead.com/&quot;&gt;proven guilty&lt;/a&gt;&amp;quot;), so I&amp;#8217;m not going to bother looking up this poll data.  However, I&amp;#8217;m really curious about whether people I know (family, friends, etc) might not also actually be more &amp;#8220;leftist&amp;#8221; than they consider themselves to be!  More on this later.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;</content>
 </entry>
 
 <entry>
   <title>The Political Compass</title>
   <link href="http://localhost:4000/blog/2004/01/21/the-political-compass/"/>
   <updated>2004-01-21T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/21/the-political-compass</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I&amp;#8217;ve been wondering about Michael Moore&amp;#8217;s assertion that Americans tend to be more progressive than is commonly acknowledged.  I figured it could be instructive to find some online tests, the kind of thing where you are asked a bunch of questions and then are shown where on the political spectrum you actually lie.&lt;br /&gt;
&lt;p /&gt;Here are some of the tests I found:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://quizilla.com/users/hazelwudi/quizzes/Where%20do%20you%20fall%20on%20the%20liberal%20-%20conservative%20political%20spectrum%3F%20%20(United%20States)/&quot;&gt;Where do you stand on the liberal-conservative spectrum&lt;/a&gt;:  A quick test that answers the stated question&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://madrabbit.net/webrabbit/quizshow.html&quot;&gt;The Political Quiz Show&lt;/a&gt;:  This test is nearly a decade old, but the questions on it are still pretty useful in today&amp;#8217;s political context.&lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.self-gov.org/quiz.html&quot;&gt;World&amp;#8217;s Smallest Political Quiz&lt;/a&gt;:  This very short test test seems to be hosted by a libertarian organization.  Perhaps its questions and results are skewed to move everyone that direction, who knows?  &lt;/li&gt;&lt;br /&gt;
&lt;li&gt;&lt;a href=&quot;http://www.politicalcompass.org/&quot;&gt;Political Compass&lt;/a&gt;:  This seems to be the most well-thought-out of the bunch.  Rather than smashing everyone onto a one-dimensional left/right line, your answers place you on a square grid, where left and right correspond to the economic ideals of the left and right (controlled economy vs free enterprise), and up and down correspond to authoritarian vs libertartian social policies.  Using this notation, George W. Bush appears in the upper right, Saddam Hussein in the upper left, with Nelson Mandela and the Dalai Lama keeping me company in the lower left.&lt;/li&gt;&lt;/p&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;p /&gt;Take some tests, you may be surprised at the results!  And feel free to post your results in the comments here if you like.  All these tests easily labeled me as the wacko commie liberal I am, so no surprises there.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>call me "crusty"</title>
   <link href="http://localhost:4000/blog/2004/01/21/call-me-crusty/"/>
   <updated>2004-01-21T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/21/call-me--crusty-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;After nearly a year of visiting my doctor to try to find out what mysterious condition was causing bizarre patches of flaky skin on choice locations throughout my body, I was able to finally visit a dermatologist who looked at me for a few seconds and said, &amp;quot;No question, you&amp;#8217;ve got &lt;a href=&quot;http://www.niams.nih.gov/hi/topics/psoriasis/psoriafs.htm&quot;&gt;psoriasis&lt;/a&gt;.&amp;quot;  Bleah.  Well, at least I now have a diagnosis and a treatment plan;  Prior to this, my regular doctor was just making it up as she went along, prescribing a random array of creams and ointments to see if any of them did anything.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Anyway, if you notice my hair is all flaky and it looks like there&amp;#8217;s been an isolated snowstorm on my shoulders, now you know it&amp;#8217;s not just run-of-the-mill dandruff or bad grooming (although that can&amp;#8217;t ever be ruled out either), I&amp;#8217;ve actually got a diagnosed medical condition, bub.  I just hope I can get it under control before I drown in a sea of skin flakes.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>nuthole evolution</title>
   <link href="http://localhost:4000/blog/2004/01/16/nuthole-evolution/"/>
   <updated>2004-01-16T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/16/nuthole-evolution</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Thanks to the plethora of plugins available on the &lt;a href=&quot;http://www.blosxom.com&quot;&gt;blosxom website&lt;/a&gt;, I&amp;#8217;ve added more new features to this site.  The most interesting is the ability for you to add comments!  Now anyone and everyone can comment on the stories posted here.  Feel free to let me know what you think!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>New pictures of Beanie and Squiggly</title>
   <link href="http://localhost:4000/blog/2004/01/16/new-pictures-of-beanie-and-squiggly/"/>
   <updated>2004-01-16T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/16/new-pictures-of-beanie-and-squiggly</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;New pictures of &lt;b&gt;Beanie&lt;/b&gt; and &lt;b&gt;Squiggly&lt;/b&gt; are &lt;a href=&quot;http://homepage.mac.com/jacknutting/PhotoAlbum6.html&quot;&gt;online&lt;/a&gt;!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tarttilicious</title>
   <link href="http://localhost:4000/blog/2004/01/09/tarttilicious/"/>
   <updated>2004-01-09T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/09/tarttilicious</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;I just finished reading &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/1400031699/rebisoft-20&quot;&gt;&lt;i&gt;The Little Friend&lt;/i&gt;&lt;/a&gt; by Donna Tartt.  I really liked her previous book, &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0804111359/rebisoft-20&quot;&gt;&lt;i&gt;The Secret History&lt;/i&gt;&lt;/a&gt; when I read it a decade ago, so I figured I&amp;#8217;d give it a go.  It&amp;#8217;s a good read, with some really gripping moments and highly believable characters.  The only complaint I have with the book is that the ending doesn&amp;#8217;t really tie up all the threads that are laid out during the telling;  I suppose that&amp;#8217;s the whole idea, that the book is primarily a character study, but it&amp;#8217;s a shame that a fine, nicely written story has such a lackluster conclusion.  It almost feels like the first four-fifths of a book rather than a complete work.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Mac OS X tech overview</title>
   <link href="http://localhost:4000/blog/2004/01/08/mac-os-x-tech-overview/"/>
   <updated>2004-01-08T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/08/mac-os-x-tech-overview</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Check out this &lt;a href=&quot;http://www.kernelthread.com/mac/osx/&quot; &gt;technical overview of Mac OS X&lt;/a&gt;.  It&amp;#8217;s written primarily for Linux geeks, and gives a nice wide picture of how the system is laid out, what happens during the boot procedure, etc.  The author sums up with a little &lt;a href=&quot;http://www.kernelthread.com/mac/osx/conclusion.html&quot;&gt;opinion piece&lt;/a&gt; explaining the pros and cons of Mac OS X vis-a-vis Windows and Linux.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Lord of the Nerds: Return of the Nuthole</title>
   <link href="http://localhost:4000/blog/2004/01/07/lord-of-the-nerds-return-of-the-nuthole/"/>
   <updated>2004-01-07T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2004/01/07/lord-of-the-nerds--return-of-the-nuthole</id>
   <content type="html">&lt;p&gt;Finally!&lt;/p&gt;
&lt;p&gt;After nearly two months offline, nuthole.com is now once again available to the teeming masses.  The story of our absence is the all-too-common, sad tale of broadband companies failing to live up to their commitments, which won&amp;#8217;t be retold here.&lt;/p&gt;
&lt;p&gt;Anyway, we&amp;#8217;re now back in business.  Let&amp;#8217;s celebrate with a link to a slightly aged article by Molly Ivins entitled &lt;a href=&quot;http://www.thenation.com/doc.mhtml%3Fi=20031117&amp;s=ivins&quot;&gt;&amp;#8220;Is America Texas?&amp;#8221;&lt;/a&gt; about the impending Texafication of the nation.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>news from the my-dog-ate-my-homework department</title>
   <link href="http://localhost:4000/blog/2003/12/02/news-from-the-my-dog-ate-my-homework-department/"/>
   <updated>2003-12-02T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2003/12/02/news-from-the-my-dog-ate-my-homework-department</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Some of you may have seen (in some obscure media outlet) mention of Neil Bush admitting, in his divorce papers, that he played around with some undisclosed number of prostitutes in Southeast Asia while he was there &amp;#8220;on business&amp;#8221;.  Of course, this son-of-a-Bush can&amp;#8217;t just come clean, no;  he is compelled to wrap this misadventure in a lie:  see, the women simply knocked on his hotel door and then had sex with him;  He didn&amp;#8217;t pay them, and therefore didn&amp;#8217;t know they were callgirls!  Perhaps Neil thought his animal magnetism was so strong that women could &lt;b&gt;smell&lt;/b&gt; him right through the door and out in the street, and simply had to have him.  That he was there as a guest/&amp;#8220;business partner&amp;#8221; of the son of the former president of China doesn&amp;#8217;t seem to come into play there at all.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;So, the obvious questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How would the media handle this if it were Bill Clinton&amp;#8217;s brother?&lt;/li&gt;
&lt;li&gt;How does that compare with the actual media treatment?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;p&gt;Oh, that liberal bias, eh?&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>holding on to one's humanity</title>
   <link href="http://localhost:4000/blog/2003/11/23/holding-on-to-one-s-humanity/"/>
   <updated>2003-11-23T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2003/11/23/holding-on-to-one-s-humanity</id>
   <content type="html">&lt;p&gt; Check out &lt;a href=&quot;http://truthout.org/docs_03/111703D.shtml&quot; &gt;this excellent letter&lt;/a&gt; by a Vietnam veteran concerning our the current US occupation of Iraq.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>babies and slow updates</title>
   <link href="http://localhost:4000/blog/2003/11/17/babies-and-slow-updates/"/>
   <updated>2003-11-17T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2003/11/17/babies-and-slow-updates</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;Well, I don&amp;#8217; t have much to say at the moment, except that I&amp;#8217;ve been tied up for a couple of weeks since the birth of my new baby daughter!  Hopefully I&amp;#8217;ll get back on track soon.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>the joy of voting</title>
   <link href="http://localhost:4000/blog/2003/10/27/the-joy-of-voting/"/>
   <updated>2003-10-27T00:00:00+01:00</updated>
   <id>http://localhost:4000/blog/2003/10/27/the-joy-of-voting</id>
   <content type="html">&lt;p&gt;I found an &lt;a href=&quot;http://truthout.org/docs_03/102003A.shtml&quot;&gt;interesting article&lt;/a&gt; about the problems with the touch-screen voting terminals that are starting to be used all over America.&lt;/p&gt;&lt;p&gt;
&lt;p&gt;Most of the problems boil down to the fact that these are closed systems whose workings are impossible for any outsider to examine or verify.  There&amp;#8217;s literally &lt;em&gt;no way&lt;/em&gt; to know if the machines are recording votes accurately, or whether through error or mischief they are recording and reporting incorrect results.  It seems to me that the easiest, best solution (as proposed in the article) is that after entering everything, the machine should print out a paper ballot for the voter to verify, and those ballots should then be saved in case a recount is required.  Presumably the paper copy and the electronic copy would be tagged identically so that given a paper ballot, you could find the electronic ballot and see if it matches what was printed.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>I am The Doctor</title>
   <link href="http://localhost:4000/blog/2003/10/20/i-am-the-doctor/"/>
   <updated>2003-10-20T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/20/i-am-the-doctor</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;My friend &lt;b&gt;James&lt;/b&gt; clued me in on the existence of a fine TV and radio program from the &lt;span class=&quot;caps&quot;&gt;BBC&lt;/span&gt; called &lt;a href=&quot;http://www.bbc.co.uk/radio4/comedy/deadringers.shtml&quot;&gt;Dead Ringers&lt;/a&gt;.  It&amp;#8217;s a prank call show, but what separates this from the &lt;a href=&quot;http://www.thejerkyboys.com/&quot;&gt;Jerky Boys&lt;/a&gt; or &lt;a href=&quot;http://www.crankyank.com/&quot;&gt;Crank Yankers&lt;/a&gt; is that the pranskters are talented impressionists.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;One of the most heavily-used characters for these prank calls is &amp;#8220;The Doctor&amp;#8221;, an actor who does a mighty fine &lt;a href=&quot;http://www.bbc.co.uk/cult/doctorwho/deadringers/index.shtml&quot;&gt;Dr Who&lt;/a&gt; (as portrayed by Tom Baker) impression, confusing his hapless victims with bewildering talk of Daleks, alternate timestreams, time travel, and past and future selves.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;(For those of you whose Dr Who knowledge stops at the &amp;#8220;you mean the guy with the long scarf and the puffy hair?&amp;#8221; level, it is that very same Doctor [who was played by actor &lt;b&gt;Tom Baker&lt;/b&gt;] who is being sent up in these sketches).&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Anyway, there are a few RealAudio clips from Dead Ringers &lt;a href=&quot;http://www.bbc.co.uk/cult/doctorwho/deadringers/index.shtml&quot;&gt;linked from the offical Dr Who site&lt;/a&gt;, and a few mp3 files of the same available on the p2p networks (a fine use for &lt;a href=&quot;http://poisonedproject.com/&quot; &gt;Poisoned&lt;/a&gt;).  What I haven&amp;#8217;t yet found anywhere are clips from the TV series.  Apparently the aforementioned prankster actually walks about in full TomBakerDrWho regalia, leading to further hilarity.  Hoo!&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>poisoned</title>
   <link href="http://localhost:4000/blog/2003/10/13/poisoned/"/>
   <updated>2003-10-13T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/13/poisoned</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;For the past half-year or so, I&amp;#8217;ve been using Acquisition, a Macintosh client for the gnutella network.  It&amp;#8217;s got some really nice features, integrates well with iTunes, and feels like a proper Mac OS X application.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;But Acquisition has its problems:  For one thing it&amp;#8217;s crippleware, and the accursed warning panel that pops up now and then is bothersome.  Acquisition also makes use of the Limewire engine for connecting to the gnutella network;  While this makes life easier for Acquisition&amp;#8217;s developer, it&amp;#8217;s obnoxious for those of us who want decent performance on our machines;  Limewire is notoriously resource-hungry, and will happily consume all the &lt;span class=&quot;caps&quot;&gt;RAM&lt;/span&gt; and &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; you can throw its way.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So imagine my happiness when I stumbled across &lt;a href=&quot;http://poisonedproject.com/&quot;&gt;Poisoned&lt;/a&gt;, an open-source p2p client that addresses all of the problems I&amp;#8217;ve had with Acquisition, and is nearly as full-featured.  It connects to the gnutella, FastTrack, and OpenFT networks, and it seems like support for the OpenNap network is coming as well.  Instead of the hungry Limewire core, it uses the open source &amp;#8220;giftd&amp;#8221;, which connects to the aforementioned networks through a plugin system.  It is missing some of Acquisition&amp;#8217;s neatest new features like the nice organization of search results, but is roughly equivalent with where Acquisition was 6 months ago in terms of nifty &lt;span class=&quot;caps&quot;&gt;GUI&lt;/span&gt; features.  Definitely one to &lt;a href=&quot;http://poisonedproject.com/&quot; &gt;keep an eye on&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>i am nutholio</title>
   <link href="http://localhost:4000/blog/2003/10/13/i-am-nutholio/"/>
   <updated>2003-10-13T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/13/i-am-nutholio</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;As of today, this blog is now being brought to you through the power of nuthole.com.  Now instead of that crazy-long address you used to have to type in order to reach this fine place, you can just type &amp;#8220;www.nuthole.com&amp;#8221;, or heck, in most modern browsers you can probably just type &amp;#8220;nuthole&amp;#8221; and you&amp;#8217;ll be on your way.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;If you&amp;#8217;re reading this, you&amp;#8217;re certainly already aware of this.  I just thought it might be worth noting for posterity&amp;#8217;s sake.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;The origins of the nuthole.com domain are far too boring to recount here.  At any rate, the actual &lt;strong&gt;meaning&lt;/strong&gt; of the very word &amp;#8220;nuthole&amp;#8221; is currently open to debate and discussion.  While the &lt;a href=&quot;http://www.urbandictionary.com/define.php?term=Nuthole&quot;&gt;Urban Dictionary&lt;/a&gt; defines &lt;em&gt;nuthole&lt;/em&gt; as &amp;#8220;Persons of uncoolness, one who is one can short of a six pack, involoved in rather ridiculous acts&amp;#8221; (which may or may not apply here), another witness noted that nuthole.com sounds like the name of a gay dating service (which this site is not).  Other theories are welcome at &lt;a href=&quot;mailto:nuthole@rebisoft.com&quot;&gt;nuthole@rebisoft.com&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>dyslexicalism</title>
   <link href="http://localhost:4000/blog/2003/10/13/dyslexicalism/"/>
   <updated>2003-10-13T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/13/dyslexicalism</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.nuthole.com/2003/09/30#outrage&quot;&gt;Earlier&lt;/a&gt; I wrote a few words about the &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0393322963/rebisoft-20&quot; &gt;&lt;i&gt;Bush Dyslexicon&lt;/i&gt;&lt;/a&gt; I was reading.  Well, I&amp;#8217;ve now finished it.  Toward the end, things started to get repetitive;  I felt quite certain that the author was re-using some of the Bushisms he was quoting, and overall it just seemed to be getting overly long.  After reading Bush&amp;#8217;s various malapropisms one after another after another, eventually you get the point.  Fortunately, the Afterword wraps things up nicely, tying together all the points made throughout the book.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;So now I&amp;#8217;m on to bigger, fresher fish to fry:  namely, Al Franken&amp;#8217;s wonderful &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0525947647/rebisoft-20&quot;&gt;&lt;i&gt;Lies and the Lying Liars Who Tell Them: A Fair and Balanced Look at the Right&lt;/i&gt;&lt;/a&gt;.  Anyone who&amp;#8217;s been paying any attention to political books these days will already have heard about this book and probably formed an opinion based on which wing of the Plutocratic Party they belong to, but for the undecided amongst you:  &lt;em&gt;You Must Buy This Book&lt;/em&gt;.  Besides exposing the deceitful tactics of the rabid right who (unfortunately) set the tone of discourse in American media, it&amp;#8217;s also pretty damn funny.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Terminated</title>
   <link href="http://localhost:4000/blog/2003/10/08/terminated/"/>
   <updated>2003-10-08T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/08/terminated</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;&amp;lt;insert obligatory Terminator joke here&amp;gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;OK, so Arnold Schwartzenegger is going to be the governor of California.  Here&amp;#8217;s a guy who has no particular experience to make him suitable for the job, and whose ideas regarding public policy don&amp;#8217;t seem very well thought-out.  He doesn&amp;#8217;t appear fully comfortable with the English language, he seems to have some unsavory personality glitches, and doesn&amp;#8217;t want to talk much about his wild partying in the 70&amp;#8217;s.  Hmm, does this remind you of &lt;a href=&quot;http://www.gwbush.com&quot;&gt;anyone else&lt;/a&gt;?&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;Chalk up one more point for Form in the battle between Form and Substance.&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>flashes of inspiration</title>
   <link href="http://localhost:4000/blog/2003/10/02/flashes-of-inspiration/"/>
   <updated>2003-10-02T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/02/flashes-of-inspiration</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;Yesterday I wrote that I figured out how to connect my &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;amp;path=tg/browse/-/917664/xs-tag%3D%5Fx23%5FtPalm/qid%3D1065091925/sr%3D45-1&quot;&gt;Palm&lt;/a&gt; to my phone with Bluetooth and how great and nerdy that is.&lt;br /&gt;
&lt;p /&gt;What I &lt;b&gt;didn&amp;#8217;t&lt;/b&gt; mention was that I had tried to do the same thing a month ago, and was totally and utterly stumped.  Using the same pieces of hardware and software, doing nearly the same steps, I was totally stumped, and came to the mistaken conclusion that the software on the Palm just didn&amp;#8217;t work with my carrier.&lt;br /&gt;
&lt;p /&gt;Maybe the documentation was poor.  Maybe I was just having an off day.  Whatever.  Somehow a few words from a colleague and a little bit of &lt;a href=&quot;http://www.google.com&quot;&gt;googling&lt;/a&gt; yesterday, and suddenly I had solved the problem which I had previously thought to be intractable!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>i love the bluetooth</title>
   <link href="http://localhost:4000/blog/2003/10/01/i-love-the-bluetooth/"/>
   <updated>2003-10-01T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/10/01/i-love-the-bluetooth</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;For a few months, I&amp;#8217;ve been using a phone with built-in Bluetooth, which lets me wirelessly synchronize contacts with my computer.  About a month ago I acquired a &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;path=tg/browse/-/917664/xs-tag%3D%5Fx23%5FtPalm/qid%3D1065091925/sr%3D45-1&quot;&gt;Palm&lt;/a&gt; &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;path=tg/listmania/list-browse/-/50WS58LGP8FY/qid%3D1065092121/sr%3D5-1&quot;&gt;Tungsten T&lt;/a&gt;, which also includes Bluetooth, but I haven&amp;#8217;t used the bluetooth there to any extent until today.  Suddenly, inspired by a coworker&amp;#8217;s easy success connecting to the internet with his new &lt;a href=&quot;http://www.amazon.com/exec/obidos/redirect?tag=rebisoft-20&amp;path=tg/detail/-/B0000AH5N1/qid%3D1065092266/sr%3D-3&quot;&gt;Tungsten T2&lt;/a&gt; and a Bluetooth phone, I figured out how to do this as well.  It rocks!  Anywhere I go, I can have access the internet (albeit slowly) with a proper web browser on the Palm (instead of the lowly &lt;span class=&quot;caps&quot;&gt;WAP&lt;/span&gt; browser on my phone.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
It&amp;#8217;s nerdalicious!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>dude, where's my country?</title>
   <link href="http://localhost:4000/blog/2003/09/30/dude-where-s-my-country/"/>
   <updated>2003-09-30T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/09/30/dude--where-s-my-country-</id>
   <content type="html">&lt;p /&gt;
&lt;p&gt;Lately I&amp;#8217;ve been bingeing on left-wing books complaining about our selected president and his corrupt cronies.  I started off with &lt;a href=&quot;http://www.michaelmoore.com&quot;&gt;Michael Moore&lt;/a&gt;&amp;#8216;s &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0060392452/rebisoft-20&quot;&gt;&lt;i&gt;Stupid White Men&lt;/i&gt;&lt;/a&gt;, continued with the excellent &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0452283914/rebisoft-20&quot;&gt;&lt;i&gt;The Best Democracy Money Can Buy&lt;/i&gt;&lt;/a&gt; by Greg Palast, and am now following up with Mark Crispin Miller&amp;#8217;s (at this point somewhat outdated) &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0393322963/rebisoft-20&quot;&gt;&lt;i&gt;Bush Dyslexicon&lt;/i&gt;&lt;/a&gt;.  The latter book is the one that&amp;#8217;s got me in a posting mood at the moment.  &lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
Written in those halcyon days before 9/11, &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0393322963/rebisoft-20&quot;&gt;&lt;i&gt;Dyslexicon&lt;/i&gt;&lt;/a&gt; deals mostly with Bush&amp;#8217;s conduct before becoming president.  Miller is able to deftly define what I&amp;#8217;ve had a hard time putting into words:  Bush is unfit to be president not because he&amp;#8217;s unintelligent (he isn&amp;#8217;t), but rather because he embodies the worst of what is wrong with the decadent upper crust of our society.  Bush attended the finest schools our country has to offer, but failed to master basic English language syntax or understanding of how our country&amp;#8217;s government works;  His string of failed business ventures in the 1970s and 80s, which would have sent most people into the poorhouse, were instead perpetually financed and bailed out by his father&amp;#8217;s associates;  In spite of a self-professed lack of interest in issues of governance, he has used wealthy patrons to finance election campaigns (and, at least in the Texas gubernatorial case, occasionally win).  Born into wealth and privilege, Dubya expects to have the world served to him on a silver platter, and remarkably, he has so far gotten what he&amp;#8217;s expected.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>The joys of broadband</title>
   <link href="http://localhost:4000/blog/2003/09/29/the-joys-of-broadband/"/>
   <updated>2003-09-29T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/09/29/the-joys-of-broadband</id>
   <content type="html">&lt;p&gt;&lt;p /&gt;I&amp;#8217;ve recently gotten broadband service at home.  When it works, it works &lt;b&gt;great&lt;/b&gt;, but unfortunately our provider has decided to use some new bleeding-edge equipment that doesn&amp;#8217;t play well with the houses on our street.  The network uses the same co-ax as our cable TV, and if our TV &amp;#8220;accidentally&amp;#8221; sends voltage out the cable (which apparently some TVs do) it fries some critical piece of network equipment.&lt;br /&gt;
&lt;p /&gt;&lt;br /&gt;
So, it can work great for weeks at a time, then be out for days and days.  So I had no network access at home from noonish last Friday until today.  And just when I had started messing with this blog!  Crikey.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>the first entry</title>
   <link href="http://localhost:4000/blog/2003/09/25/the-first-entry/"/>
   <updated>2003-09-25T00:00:00+02:00</updated>
   <id>http://localhost:4000/blog/2003/09/25/the-first-entry</id>
   <content type="html">&lt;p&gt;
&lt;p&gt;blog this, blog that, blog blog blog.  everyone&amp;#8217;s got a blog now, right?&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
i actually started blogging years ago, creating a quickly-abandoned site that is &lt;a href=&quot;http://whydont.itgo.com&quot;&gt;still floating around&lt;/a&gt; on a free webserver somewhere.  In those days, I was relying on the web-based blogging system at blogger.com, which was just too prickly to really want to use on a regular basis.  Now I&amp;#8217;ve stumbled across this new-fangled &lt;a href=&quot;http://www.blosxom.com/&quot;&gt;blosxom&lt;/a&gt; doohickey which looks like it will make my blogging efforts a bit more manageable.  We&amp;#8217;ll see!&lt;/p&gt;
&lt;/p&gt;</content>
 </entry>
 

</feed>
