If software engineers were composers…

I’ve been thinking a lot recently about the widely divergent approaches to software engineering I’ve experienced during my 15+ years in the field. It’s occurred to me that these approaches can be loosely compared to the way different famous composers worked. For example, some engineers are Beethovens. Driven perfectionists, constantly refining and revising their code, never content for it to be just “good enough”. Beethovens are utterly fearless about using “revolutionary” new approaches and techniques. They aren’t motivated by what’s fashionable or lucrative; their only concern is to blaze new trails and create radically innovative solutions that nobody has ever seen before.

Other engineers are Mozarts. Great software just seems to “pour” out of them, as effortlessly as breathing. They’re not so concerned with breaking new ground, but their code “just works” and is elegant and easy to understand and maintain. They are masters of the tools of the trade. They’re not always reliable though, preferring to avoid work, and don’t like producing on a deadline.

Then there are the Haydns. Steady, dependable, consistently cranking out one app after another like a machine. While the Beethovens and Mozarts work best on their own, Haydns are great delegators and collaborators. Their code isn’t likely to change the world, but neither is it likely to crash or contain bugs, and you can count on them to deliver on time and under budget.

It’s too bad Music History isn’t taught in schools any more, because this would be a great software engineer interview question: “If you were a composer, which one would you be?”. I wonder how many recent computer science students could provide an intelligent answer?

Country pick lists and American jingoism

I’m adding a new feature to an iphone app I’m working on that requires a country pick list to select an emergency call number for the country they are currently in.

I’m wondering whether to just sort the list of countries alphabetically, or put “US” and other English-speaking countries on top. I’m not going to be supporting languages other than English (yet), but I don’t want to be accused of “jingoism”. Then again, I wouldn’t want Sarah Palin and her ilk to boycott my app!

Any thoughts about this from my developer/designer friends?

getting your IDE to recognize javascript in .phtml files

Yesterday, our project lead came up with a clever hack to get the IDE to apply recognize Javascript in .phtml files.

Our project uses a lot of .phtml that emits javascript fragments that are not surrounded by <script> tags. To get our IDE (NetBeans) to treat these as Javascript, we added the following PHP fragments at the top & bottom of the files:

<? if (false) { ?><script language='javascript'> <? } ?>

... CODE HERE...
<? if (false) { ?></script><? } ?>

Of course this is kind of a hack, but it’s pretty useful!

php implementation of Java HashSet

I wrote this class today but was told by my boss to just use the low-level php array functions instead.

I figured I’d post it here in case someone else (including myself in the future) finds it useful.

/**
 * PHP implementation of Java HashSet
 *
 * @author mpelzsherman
 */

class HashSet {

    private $_objects = array();

	/**
	 * @param  $o Object to be added to this set
	 * Returns: true if the set did not already contain the specified element.
	 */
	public function add($o) {
		foreach($this->_objects as $obj) {
			if ($obj == $o) {
				return false;
			}
		}
		$this->_objects[] = $o;
		return true;
	}

	/**
	 * @param  $o Object to be removed from this set
	 * Returns: true if the set contained the specified element.
	 */
	public function remove($o) {
		foreach($this->_objects as $obj) {
			if ($obj == $o) {
				array_splice($this->_objects, $obj);
				return true;
			}
		}
		return false;
	}

	/**
	 * @param  $o
	 * Returns true if this set contains the specified element.
	 */
	public function contains($o) {
		foreach($this->_objects as $obj) {
			if ($obj == $o) {
				return true;
			}
		}
		return false;
	}

	public function size() {
		return count($this->_objects);
	}

	public function objects() {
		return $this->_objects;
	}

	/**
	 * Removes all of the elements from this set.
	 */
	public function clear() {
		$this->_objects = array();
	}
}

There’s more than one way to do it… but only one works!

I just found a perfect example of something that really annoys me about software frameworks, API’s, toolkits, and programming languages in general.

I call it “There’s more than one way to do it… but only one works!”

Today’s example is from ExtJS – an extremely powerful framework for building applications in Javascript. I had an instance of Ext.Panel with borders on it and wanted to turn them off.

So in the documentation I found the following three methods:

1. border : Boolean

True to display the borders of the panel’s body element, false to hide them (defaults to true). By default, the border is a 2px wide inset border, but this can be further altered by setting bodyBorder to false.

2. bodyBorder : Boolean

True to display an interior border on the body element of the panel, false to hide it (defaults to true). This only applies when border == true. If border == true and bodyBorder == false, the border will display as a 1px wide inset border, giving the entire body element an inset appearance.

3. hideBorders : Boolean

True to hide the borders of each contained component, false to defer to the component’s existing border settings (defaults to false).

In my case, only door #3 worked, but it took me a while to figure that out.

It seems to me that it would be better if the API only offered one way to control borders. If I don’t want borders on my child components, I can turn them off in the child components. I’m willing to live with slightly less power in exchange for clarity. Or, if all of the methods actually worked as expected, I could live with that too.

I could cite countless examples of this issue. This probably isn’t even the best example, since these different methods probably are legitimate for some use case that I haven’t run across yet. I’ve seen many cases where some API methods simply do not work at all, while others do, with no explanation.

This will probably become a chapter in my upcoming book series on software development “gotchas” … stay tuned!

A brief response to Sam Anderson’s “In Defense of Distraction”

This article in New York magazine made for a good morning read to get the juices flowing.

The point the author fails to drive home, however, is that multitasking is quite simply an adaptive response to a dramatic increase in the amount of information available, the increased rate of change on all levels, and, most importantly, latency. All of these phenomena are caused by advances in technology, especially networking but also mobile computing. Multitasking is simply unavoidable in order to remain competitive and operate effectively in the modern world. Making use of time spent sitting on hold, waiting at the doctor’s office, waiting for files to download, software to install, clients and co-workers to respond to emails, etc. is the only way to stay productive in this world.

Case in point – I wrote this post while waiting for a software prototyping tool to download & install. I have to reboot my computer now of course, since this is Windows. Luckily I have my iphone so I can catch up on my email during the reboot. 🙂

Authentication with Zend Framework and Doctrine

At my new job, we’re using some pretty cool cutting edge object-oriented PHP technology: Zend Framework for MVC and Doctrine for ORM. If you don’t know what those acronyms mean, you probably shouldn’t bother reading the rest of this post. 🙂

As an exercise to ramp up on these two technologies, I modified the code from the Zend Framework quick start to authenticate users against a MySQL table using Doctrine.

I found a pretty good tutorial on Zend_Auth authentication adapter. The author of the tutorial says “I’m not going to go into specifics on this, as the documentation covers them, and your needs will vary based on your site.”. Well, the Zend documentation doesn’t cover them all that well, so it took me a while to figure this out. Surprisingly, I was unable to find any examples anywhere. I did find this proposal for an implementation, but it’s not quite complete. I figured I’d save someone else the trouble and post my solution here.

Here’s the adapter:

class MPSAuthAdapter implements Zend_Auth_Adapter_Interface
{
	private $_username;
	private $_password;

    /**
     * Sets username and password for authentication
     *
     * @return void
     */
    public function __construct($username, $password)
    {
        $this->_username = $username;
        $this->_password = $password;
    }

    /**
     * Performs an authentication attempt using Doctrine User class.
     *
     * @throws Zend_Auth_Adapter_Exception If authentication cannot
     *                                     be performed
     * @return Zend_Auth_Result
     */
    public function authenticate()
    {
    	$result = null;

    	try {
			$q = Doctrine_Query::create()
			    ->from('User u')
			    ->where('u.username = ?', $this->_username);

			$user = $q->fetchOne();
			if ($user == NULL) {
				$result = new Zend_Auth_Result(
			            Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND,
			            null,
			            array('sorry, login ' . $this->_username . ' was not found'));
			} else {
				if ($user->getPassword() != $this->_password) {
					$result = new Zend_Auth_Result(
				            Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID,
				            $user,
				            array('sorry, the password you entered was invalid for user ' .
                                                    $this->_username));
				} else {
					$result = new Zend_Auth_Result(
				            Zend_Auth_Result::SUCCESS,
				            $user,
				            array());
				}
			}
			return $result;
    	} catch(Exception $e) {
    		throw new Zend_Auth_Adapter_Exception($e->getMessage());
    	}
    }
}

… and here’s my version of LoginController.php:

// based on Matthew Weier O'Phinney's tutorial
// http://weierophinney.net/matthew/archives/165-Login-and-Authentication-with-Zend-Framework.html
require "MPSAuthAdapter.php";
require "BaseController.php";

class LoginController extends BaseController
{
    public function getForm()
    {
    	// MPS: note I had to change this classname
    	// to work with the Zend autoloader:
        return new Default_Form_Login(array(
            'action' => '/login/process',
            'method' => 'post',
        ));
    }

    public function getAuthAdapter(array $params)
    {
        return new MPSAuthAdapter($params['username'],$params['password']);
    }

    public function indexAction()
    {
        $this->view->form = $this->getForm();
    }   

    public function processAction()
    {
        $request = $this->getRequest();

        // Check if we have a POST request
        if (!$request->isPost()) {
            return $this->_helper->redirector('index');
        }

        // Get our form and validate it
        $form = $this->getForm();
        if (!$form->isValid($request->getPost())) {
            // Invalid entries
            $this->view->form = $form;
            return $this->render('index'); // re-render the login form
        }

        // Get our authentication adapter and check credentials
        $adapter = $this->getAuthAdapter($form->getValues());
        $auth    = Zend_Auth::getInstance();
        $result  = $auth->authenticate($adapter);
        if (!$result->isValid()) {
            // Invalid credentials
            $form->setDescription(array_shift($result->getMessages()) .
                                                           "
please try again.");
            $this->view->form = $form;
            return $this->render('index'); // re-render the login form
        }

        // We're authenticated! Redirect to the home page
        $this->_helper->redirector('index', 'index');
    }

    public function logoutAction()
    {
        Zend_Auth::getInstance()->clearIdentity();
        $this->_helper->redirector('index'); // back to login page
    }
}

To ensure that all of the pages in the app are authenticated, I created a BaseController class that handles authentication, and derived all of my controller classes from it. Here’s that class:

class BaseController extends Zend_Controller_Action
{
    public function preDispatch()
    {
        if (!Zend_Auth::getInstance()->hasIdentity()) {
            if ('/login' != $this->getRequest()->getPathInfo() &&
                'login' != $this->getRequest()->getControllerName()) {
    			$_redirector = $this->_helper->getHelper('Redirector');
                $_redirector->gotoUrl('/login');
            }
        }
    }	

}

I’m still pretty new to all this, so I’m very interested in any comments.

URL Shortening in Objective-C

Here’s a little class I wrote this weekend to support URL shortening using the is.gd service.

I hope someone finds it useful.

//
//  URLShortener.h
//
//  Created by Michael Pelz-Sherman on 5/15/09.
//

#import 

@interface URLShortener : NSObject {}

+ (NSString *)shortURL:(NSString *)longURL;

@end

=================================
//
//  URLShortener.m
//  Creates a short URL from a long URL using the is.gd API.
//
//  Created by Michael Pelz-Sherman on 5/15/09.
//

#import "URLShortener.h"

@implementation URLShortener	

+ (NSString *)shortURL:(NSString *)longURL {
	NSURL *apiURL = [NSURL URLWithString:[NSString stringWithFormat:@"http://is.gd/api.php?longurl=%@",longURL]];
	NSError *error = nil;
	NSString *result = [NSString stringWithContentsOfURL:apiURL encoding:NSISOLatin2StringEncoding error:&error];
	if (error != nil) {
		NSLog([error description]);
		return nil;
	} else {
		return result;
	}
}	
	

@end

Two new iphone ads NOT from Apple

Last night, during a single episode of “Rescue Me”, I saw the following ads:

To me this demonstrates more clearly than anything else the iphone’s growing dominance of the mobile applications space.

Essential development tools for Windows vs. Mac

Upon starting my new job on Monday, I was provided with a laptop with a fresh install of Windows XP.

Here are the essential software tools I’ve had to install so far in order to be productive with PHP development on Windows:

– Firefox/Firebug
– Eclipse
– TortoiseSVN
– Cygwin
– WAMP
– EditPlus (Text editor)
– 7-Zip (for creating zip archives)
– 5-Clicks (for selective screen capture)
– Pidgin (IM client)
– Adobe Flash Player
– Adobe PDF Reader

Here’s the same list on Mac OS X:

– Firefox/Firebug (may be less critical as more dev features are added to Safari)
– Eclipse
– Adobe Flash Player
– MySQL
– TortoiseSVN OS X comes with command-line svn, which works fine for me
– Cygwin OS X comes with Terminal.app
– MAMP OS X comes with apache & php, MAMP isn’t really needed
– EditPlus OS X comes with TextEdit
– 7-Zip OS X has zip support built in
– 5-ClicksOS X has selective screen capture built in
– Pidgin (IM client) OS X comes with iChat
– Adobe PDF Reader OS X comes with Preview