September 26, 2008

Closures in PHP 5.3

If early releases are any indication, PHP is scheduled to receive some pretty significant updates in version 5.3. In addition to namespaces, I'm particularly interested in the addition of closures.

According to object-oriented programming expert Martin Fowler, closures are defined as a block of code that can be passed to a function. However, delegates (C#), anonymous classes (Java) and function pointers (C) don't quite qualify because the following also needs to be true:
  1. Closures need to be able to refer to variables already present in scope at the time they're defined.

  2. Closures shouldn't require complex syntax (I personally think this point is a tad subjective).
As you can imagine this capability might be helpful when writing a function that repeatedly executes a block of code specific to the function. It wouldn't make sense to refactor this block of code to the class level if it doesn't get used anywhere outside the function. With closures, the block of code distinct to the function may be defined and repeatedly called upon without having to bloat your classes.

PHP's upcoming syntax for closures is shaping up to be comparable to the C# 2.0 implementation. In the .NET world closures first arrived as anonymous methods in C# 2.0 (these were later simplified into lambda expressions in C# 3.0).

For comparison's sake C# anonymous methods look something like this:
/* Returns true if tOne and tTwo are  both evenly 
divisible by the denominator (denom) */
public bool EvenlyDivisible(int denom, int tOne, int tTwo)
{
//Define the closure
Predicate evenlyDivisible = delegate(int testNum)
{
//Note that denom is defined outside closure scope
if ((testNum % denom) == 0)
{
return true;
}
else
{
return false;
}
};

//Use the closure as necessary
if (evenlyDivisible(tOne) && (evenlyDivisible(tTwo)))
{
return true;
}
else
{
return false;
}
}
When released, a comparable implementation in PHP 5.3 will probably look something like the following:
/* Returns true if $tOne and $tTwo are  both evenly 
divisible by the denominator ($denom) */
function EvenlyDivisible($denom, $tOne, $tTwo)
{
$evenlyDivisible = function ($testNum) use ($denom) {
//Note that $denom is defined outside closure scope
if (($testNum % $denom) == 0)
{
return true;
}
else
{
return false;
}
};

//Use the closure as necessary
if ($evenlyDivisible($tOne) && ($evenlyDivisible($tTwo)))
{
return true;
}
else
{
return false;
}
}
For additional information please check out the closure proposal on php.net.

August 22, 2008

The ref and out Keywords in C#

In C# all value type parameters (objects that inherit from System.ValueType) are allocated to the stack and passed by value. This means that a copy of these variables is created and passed into the method being called. Since the parameter is a local copy its scope is limited to that method. See the following example below:
protected void Sample()
{
int x = 5;
//Writes 5 to the console
Console.WriteLine(x.ToString());
//Send a copy of x
Increment(x);
//Writes 5 to the console
Console.WriteLine(x.ToString());
}

protected void Increment(int incoming)
{
incoming++;
}
Note that the variable x is not changed by the Increment method. In most cases this behavior is desired. However, there are occasions when we may want to persist changes to a value type parameter beyond the scope of the method. This is where the ref and out keywords come into play. Here's our sample again but with the ref keyword used in the Increment method:
protected void Sample()
{
int x = 5;
//Writes 5 to the console
Console.WriteLine(x.ToString());
//Send a reference of x
Increment(ref x);
//Writes 6 to the console
Console.WriteLine(x.ToString());
}

protected void Increment(ref int incoming)
{
incoming++;
}
Note that this time around x is 6 after the Increment method is executed.

The ref and out keywords operate identically except that ref parameters must be initialized before being passed into the method while out parameters must be initialized by the time the method returns.

August 09, 2008

SQL Server 2005 Finicky with Nested Comments

I found out the hard way that MS SQL Server 2005 is sometimes finicky about nested comments leading up to CREATE PROCEDURE or ALTER PROCEDURE lines. Here's a simple illustration of this phenomenon:

/*
/*Bad comment line*/2
*/
CREATE PROCEDURE [dbo].[GetProduct]
AS

SELECT * FROM Product
This code executes without error...but everything grinds to a halt when you try to modify or script it. Management Studio reports a Syntax error in TextHeader.

I ran into this behavior after working an hour on a fairly complex sproc. I didn't back up my work before I ran it, assuming I could always pull it out of the database to make tweaks if necessary. Needless to say I was miffed to find that I couldn't open the stored procedure and effectively lost my work.

Thankfully, it's possible to retrieve code that's lost in this manner:

SELECT
ROUTINE_DEFINITION
FROM INFORMATION_SCHEMA.Routines
WHERE
ROUTINE_Name = 'GetProduct'

May 19, 2008

Browsershots Browser Compatibility Tool

For many projects I end up developing and testing my web applications on Internet Explorer, Firefox and Safari. This strategy, though sufficient for testing common scenarios, does not take into account multiple operating systems, browser versions or additional browser vendors. Any of these factors might introduce compatibility issues. It would be very costly, boring and ultimately unrealistic to manually test against all of these possible variations.

This is where Browsershots enters the picture. This open source service (created by Johann C. Rocholl) generates screen shots of your web application running under your choice of over 40 web browsers that span 4 platforms.

I'm very pleased to have such a tool available for automating the leg work that goes into browser testing, especially for the less likely scenarios.

March 31, 2008

Design Pattern Reference

If you're interested in learning more about design patterns, or if you'd simply like to have a reference handy when sizing up your next project, I wholeheartedly recommend the following:

The Net Objectives Pattern Repository

Net Objectives has put together some well articulated verbiage detailing the nuances of over half a dozen design patterns. For myself, the inclusion of procedural analogs and non-software analogs (metaphors for each pattern in the real world) are especially helpful. Sample implementations, motivations for use, testing issues and consequences of use are also explored for each pattern.