Monday, June 15, 2009

iPhone + Asterisk = free long distance

Like many a small business, MTA uses VoIP for its phone services—after all, our employees are all over the place, and POTS lines just wouldn't do it. Through the clever combination of VoIP and Asterisk, the phone bill for the entire company still comes in at under $50 a month.

Plus, Asterisk gives us a number of advantages when we're on the go. For example, we use a DISA to cause our PBX to bridge a new line into an incoming call, thus allowing us to make long-distance calls from any phone by paying only our incoming and outgoing rates—given that 1-800 service costs us around $0.03 a minute, and outgoing long-distance service costs around $0.02 a minute, $0.05 a minute sounds like a very attractive rate when you're away from home and need to make a call; all you need is a payphone and you're in business.

DISA works well from cell phones, too—but here there are a few pet peeves. A DISA call requires me to make an outgoing call (which is always billable on my cell phone plan) to the office, dial a special code and then dial the phone number I want to reach… and my memory for phone numbers isn't all that good. The fact that I can't seem to dial a number from my address book while I'm on a call really irks me: the data is there, the technology isn't that complicated, and the only reason that I can think of why this wouldn't be allowed is that telephone companies don't want it to… which, to me, sounds like a really good reason why it should.

Asterisk to the rescue
Thus, I have been thinking of coming up with a solution that solves all these problems—with the possible added benefit of sticking it to the phone company*. Yesterday, I finally had a couple of hours to spend on it, and this is what I came up with.

First, I have a small PHP script that runs on one of our servers. The script takes a phone number in input (as well as a shared secret in case someone gets a hold of the address) and then creates a small call file, which is sent to Asterisk. The call file, combined with a specially-built context, instructs Asterisk to:
  1. Set its Caller ID to the outgoing phone number
  2. Call my cell phone
  3. Upon pick up, play a simple voice messsage ("Press 1 to complete your call")
  4. When 1 is pressed, initiate a call to the outgoing phone number
  5. Bridge the two calls
Item #1 on the list is mostly a nice touch—by setting the CID to the number I'm trying to dial, I can still have a meaningful record of the conversation in my iPhone's call log. Items 2 through 4 call me cell phone (incoming calls are free, you see) and then wait for some action on my part; this ensures that, should I fail to pick up or the call go to voicemail, the person I want to call doesn't end up getting into an argument with my recorded messages. Item #5, finally, completes the bridge, thus giving me a completely free call to either an internal MTA extension or an arbitrary external number.

On the iPhone
So, far, there is nothing special about my set up. I can now make phone calls simply by invoking a script through HTTP—something that can easily be done from an iPhone without the need for anything more than stock software: I could just use Safari to call up the script and be done with it.

However, this doesn't directly solve the problem with being unable to dial from my address book. This is where the couple hours of free time last night came into play. Armed with the GM release of the 3.0 SDK, I wrote a little application that allows me to initiate a bridged call either by dialing a number or by calling up my address book, and then selecting a contact and a phone number:





Clearly, this app is not going to make it to the App Store any time soon, but it's a great little thing to have for me and the rest of the staff.


* I don't usually advocate sticking it to anyone—but, unfortunately, for the phone company, I happen to know what their operating costs are, and am fully aware of the fact that they are, indeed, sticking it to me with their $0.30 per minute (plus another $0.20 for long distance) rates. Therefore, it is only fair to return the favour.

Wednesday, June 03, 2009

Introducing: Twitter Dinner with Tabini

As there is clearly big business to be had and I seem to be one of the few in the community who hasn't sold out his life-story rights, I would like to announce the upcoming* Twitter Dinner with Marco Tabini. For a small fee (plus the cost of food), I will show you how to:

  • Create a Twitter account that you most likely won't use
  • Post messages that most likely nobody will ever care about
  • Open up your wallet and give me all your money
  • Sign off on that once-in-a-lifetime Nigerian real-estate deal that you've been deftly avoiding all your life.
Don't wait! Seating at my local McDonald's is limited. Sign up today!

* Dates and times to be determined (a 20-minute seating limit applies before the cops cite us for loitering).

Saturday, May 09, 2009

Dates, Times and Derick

As you may know, php|a just published Derick Rethans' new book, php|architect's Guide to Date and Time Programming. If you allow me a small amount of self-promotion, this is a great book—and not just because my company happens to be the publisher.

Date and time programming is one of those topics that almost everybody tends to think they're doing well and almost nobody does correctly. Thus, the most challenging aspect of selling this book is the fact that almost all those who could benefit from it—and that's just about everybody—will tend to think that they don't need it.

As an aside on why this book is so important, let me tell you this little story. Like most, we paid relatively little attention to our date programming—for the most part, it just worked, but only because all our servers are set to the same timezone, so that date and time values are all automatically synchronized.

When we installed PHP 5.2, however, our machines kept crashing. I have had occasion in the past to mention that out software is written with Nixon-level paranoia in mind, so all warnings and strict notices turned on and anything amiss is cause enough for our software to throw a 500 error and let us deal with the consequences by hand.

It turns out that, starting with 5.2, PHP was much more anal about the way it handles dates, so that it now spits out warnings like these:

Strict Standards: strtotime(): It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/New_York' for 'EDT/-4.0/DST' instead.

As you can see, Derick and the rest of the PHP team have gone to great lengths to make sure that date and time manipulation are as accurate as they can be—and, as anyone who has ever tried writing date-management code knows, that's not a simple task.

That's why I think Derick's book should be on every PHP developer's reading list—because you, too, could end up with a line like this in your code:

// Here, Derick--happy?
date_default_timezone_set('America/Toronto');


Monday, May 04, 2009

Use your own brain, please

There has been a surprising—and, at times, outright hilarious—debate under the form of a number of reactions to my last post on self-commenting code (itself a follow-up to a blog post by Brandon Savage). For my part, I will limit myself to wonder, with a slightly curled lip, how, with so many people openly disdaining the mere idea of reducing the number of comments in code, there can be so much horribly commented code lying around, and leave things at that…

…well, not quite—I will say one more thing while I'm at it: please, please stop blindly quoting Martin Fowler and his books. He is not Jesus Christ, and his books are not the Bible. Like every other source of information, Mr. Fowler's books should be assimilated into your own personal base of knowledge and used to formulate your own ideas, not parroted as if they were the word of the Almighty. I bet he would be the first to say so himself.

Let me give you a quick reason why quoting out of context is dangerous:

Never forget that the most sacred of all rights in this world is man's right to the earth which he wishes to cultivate for himself and that the holiest of all sacrifices is that of the blood poured out for it.


What a heartfelt, patriotic and inspiring quote, eh? Too bad you may have a bit of trouble liking it once you find out who the author is.

Thursday, April 30, 2009

The myth of the myth of self-commenting code

On Code Commenting And Technical Debt | BrandonSavage.net

Interesting post by Brandon—I disagree only on one main point:

This myth of self-documenting code needs to be squashed once and for all. Commenting is important, and unless your code does nothing other than display “Hello World!” it’s going to need some explanation.

I find this view of coding a little misguided, to be honest—in fact, I would go as far as saying that code doesn't need any comments.

Wait, did I just say that? Yes, I did, and here's why: code is a discussion between the developer and a machine. Writing code that cannot be comprehended by another human being is a bit like writing a letter to your dear friend in a language you can write but not read—strange, at best.

Good code should be self-documenting insofar as you should be able to understand what the code does without the assistance of any comments—after all, the computer gets it, so why shouldn't you? This can easily be done by the judicious use of clear logic and good programming practices like giving your variables names that are actually related to what they do.

What I suspect Brandon really means is that the comments are there to illustrate the intentions of the author when those intentions are not immediately made obvious by the code itself. This, I daresay, is the crux of Eli's argument that commenting inside the code is the most important contribution that a developer can make towards eliminating technical debt. That's because commenting inside the code helps understand the reasoning behind the choices that were made when writing the code, rather than what the code itself accomplishes.

Let me make an example using an actual piece of code taken from a project I'm working on in an effort to avoid the hello-world syndrome that so often affects this kind of post:


function __construct(array $pathInfo) {
$section = $pathInfo[0];
$file = $pathInfo[1];

// Assume that the location of this file is inside the main trunk, and that pathInfo has already been filtered.

$path = dirname(__FILE__) . '/../../' . $section . '/xml/static/' . $file . '.xml';

if (!file_exists($path)) {
Controller::singleton()->doError(404);
}

parent::__construct('main/xsl/template.xsl', $path);
}


Now, as you can see this code contains only one comment, but I think that any reasonably competent developer would have no problem understanding what it does, because the code itself gives you all the assistance and hints you need. On the other hand, all sorts of big red WARNING flashing lights would be going on in a developer's mind without the comment: why is the code looking for things using relatives paths? And, most disconcertingly, why isn't the $pathInfo array being filtered before usage*?

Thus, the concept of “self-documenting” code is not a myth—code should be written so as to tell a developer what it does without the need for any comments. It is a myth insofar as people use it as an excuse to avoid documenting their intentions, which is really what comments are useful for.


* I cheated a bit here, because in the real codebase the filtering is done system-wide, so part of this comment is really superfluous if you know the codebase's overall design, which, of course, would be documented elsewhere.

Sunday, April 26, 2009

May I suggest a rev=completelyUnrelated attribute?

Brooklyn novelist Peter Brett found his muse and wrote first novel commuting on the F line

That's gotta make for a couple of sore thumbs—but the best part is the ten links in the article, of which one is relevant to the topic at hand. But, hey, at least they didn't link articles and most adverbs.

Saturday, April 25, 2009

The book industry is stupid


If the world were a less stupid place, there really would be no need for bookstores. You'd simply go online, find a book you want and have it printed out remotely at a location that's convenient to you. This way, publishers would save money by not having to print a million copies to sell 100,000, authors would be able to negotiate higher royalties and not have to deal with the problem of accounting for reserves and returns, and the entire accounting process would be simple and automatic. And don't even get me started on the savings for the environment: no more shipping, no more waste of paper (since you only print what you need) and a greater distribution of refuse.

Of course, there would be two huge losers: bookstore chains and distributors, which luckily are already doing an excellent job of destroying the market anyway.

Small bookstores would, on the other hand, thrive, because they would be able to offer a valuable service (printing any book at any time) that is perfect for their small scale.