Confessions of a Converted PHP Developer: Namespace Superhero!

Tweet

The moment you start writing code that grows beyond a few classes, you start to realise that you need a way to group files and logic. While this is easy to do, it can become quite difficult to ensure that you have class names that are unique and don’t end up accidentally clashing with other classes in your own code, or classes in other people’s code that you are using.

Namespaces! That’s What You Want.

Namespaces are a way of encapsulating code to a specific library or area. This is most easily viewed as a way to create classes that are unlikely to conflict with other classes. If you had a class called foo, and then started using a library of classes which also included a class called foo, then you’re in trouble, as you’ve now got two classes with the same name. In PHP you’d end up with an ugly error – which is actually quite good, as you’re able to track it down. In Ruby you’d just end up with a frankenstein of the two classes in one — which is definitely not good.

To get around this issue, programming languages need a way to group together like items into their own encapsulated area so that one domain of your code can have the same classes as another domain of your code. The term for one of these groups is namespace.

Namespacing has been a core part of Ruby since it’s inception — just not officially under that name — whereas in PHP it’s a relatively new addition. As a result of this there’s a semi defacto naming convention in many of the PHP libraries that maps classes to folders as a form of namespacing. While this works to create unique classes, it also makes the code somewhat verbose and unsightly.

PHP’s lack of namespacing

PHP only introduced proper namespacing in version 5.3, released at the end of June 2009 to much furore and, from my experience, has been very slow in uptake. I’d attribute this to one main fact, and that’s backwards compatibility. Unfortunately the hosting community’s uptake of new versions of PHP is very slow, and as such the availability of PHP 5.3 to a large proportion of the user base is not there. PHP 5.3 accounts for under 9% of websites known to be using PHP. For a developer to use namespaces in their library they’re effectively cutting off a large user base, and while that’s no excuse to stifle a feature’s use — you can understand why some developers are loathe to do it.

PHP’s Psuedo Namespacing

Before official namespace support was available in PHP, it was common to define your classes with a sort of psuedo-namespace based on the folder structure of your classes, adding underscores to distinguish new folders or files.

An example of a library that uses this method is the library Facade.

Facade File Listing

Facade’s file structure

We can see there is a Request.php file in the Facade/S3 folder. Following the psuedo namespacing we end up with a class named Facade_S3_Request. This also makes it easy for auto loaders to find a file to load. If you ask for Facade_S3_Request it’s easy to look for Facade/S3/Request.php.

This works well, except you’re stuck having to use the verbose class names in both the libraries’ code and the code that has to use it. This can get a little ugly when you start using large codebases — here’s a class name in a library I use: HTMLPurifier_AttrDef_URI_Email_SimpleCheck.

PHP’s Official Namespacing

Namespaces are defined by using the namespace keyword right at the top of your PHP file (it has to be there), like so:

<?PHP
namespace Foo;

// or alternatively

namespace Foo{
# code here
}

All code after the namespace Foo; command will be in the Foo namespace.

You can also assign sub namespaces by separating them with a backslash character.

<?PHP
namespace FooBar;

class MyClass
{
	public function hello()
	{
		return "Hello World";
	}
}

Now you could use this code in one of two ways, firstly:

<?PHP
include 'my_class.php'; // Let's assume our previous code is in this file
echo FooBarMyClass::hello();

This uses the fully qualified namespace to reference the class, or secondly:

<?PHP
use FooBar;
include 'my_class.php'; // Remember our assumption from before...

echo BarMyClass::hello();

We tell PHP that we want to use the FooBar namespace, and then we call BarMyClass. You might have thought we’d just be able to call MyClass without the Bar part, and while that makes sense — it’s just not the case.

It only really makes sense if you look into the way PHP namespaces are aliased. use FooBar is the same as saying use FooBar as Bar — which means that Bar is aliased to FooBar. You could say use FooBar as Potato and then call echo PotatoMyClass::Hello(). Confusing? Yes. Useful? To a degree.

There’s a bunch of rules to do with precedence and a few more features but I’ve rabbited on about PHP for enough. You’re here for Ruby, so let’s look at how Ruby implements namespaces. You can read more about PHP’s namespaces in this series of SitePoint articles.

Ruby modules, er… namespaces!

We’ve already seen Ruby modules in action while talking about mixins, but they’re also Ruby’s built in way of creating namespaces.

A basic namespace

module Good
	class Person
		def self.Welcome
			puts "Well, Hello World!"
		end
	end
end

module Evil
	class Person
		def self.Welcome
			puts "I will kill ye' all."
		end
	end
end

We now have two modules with separate Person classes, each with their own Welcome method. We can access these by using the standard module operator.

Good::Person.Welcome
> "Well, Hello World!"

Evil::Person.Welcome
> "I will kill ye' all."

Alternatively we can include this into another class, and drop the module name.

class HelloWorld
	include Good
	def self.WelcomeMessage
		Person.Welcome
	end
end

HelloWorld.WelcomeMessage
> "Well, Hello World!"

So what we’ve done there, is create a new class which includes the Good module. Inside the WelcomeMessage class method we simply call Person.Welcome and since we’ve included the Good module, Person refers to Good::Person.

Applying multiple ‘namespaces’

This method of namespacing is interesting, as it allows you to apply multiple modules with the include statement, and the methods will simply overwrite each other, but leave methods that aren’t available in a later module alone. We can see this by doing two things. First we’ll add a new class to the Good module, and call that in our WelcomeMessage method inside the HelloWorld class, and secondly we’ll tell the HelloWorld class to include Evil — which will overwrite any classes from Good which are also in Evil.

module Good
	class Animal
		def self.Welcome
			puts "Meow."
		end
	end
end

class HelloWorld
	include Evil
	def self.WelcomeMessage
		Person.Welcome
		Animal.Welcome
	end
end

HelloWorld.WelcomeMessage
> "I will kill ye' all."
> "Meow."

So the output we’re seeing here is a mixture from both Good and Evil. We first included Good, which gave us the Person and Animal classes, but when we included Evil it overwrote the Person class — but not the Animal class, since there wasn’t one defined in Evil. Boom!

Nesting Modules

Modules in Ruby are quite versatile, you can nest them inside each other to build up multiple level namespaces (technically you can nest them in classes too, as Class is a subclass of Module, but baby steps eh?).

module SuperHeroes
	module JusticeLeague
		class Batman
		end
		class Superman
		end
	end
	module Avengers
		class IronMan
		end
		class CaptainAmerica
		end
	end
end

Here we’ve created a module SuperHeroes as a super namespace, then created two sub modules JusticeLeague and Avengers as sub namespaces. Each of these sub namespaces have a couple of super heroes defined as classes in them.

We can now include either one of those sub namespaces in another class, for example:

class MyHeroes
	include SuperHeroes::Avengers
end

MyHeroes.constants
> [:IronMan, :CaptainAmerica]

I’ve included the Avengers into my MyHeroes class, and then listed the available constants (In this case, the classes that were included). It gives us IronMan and CaptainAmerica.

Module / Class Short Cuts

You can shortcut your module or class naming, if you know that the module has already been created. If we continue on from before, we can create a new module with this shorthand.

module SuperHeroes::SHIELD
	class NickFury
	end
end

And that works fine, but only because we have already defined the SuperHeroes module. If I try and do this without a predefined module, I’ll get an error.

module IHave::NoFriends
end

> NameError: uninitialized constant Object::IHave

That’s all folks

Today we’ve had an introduction look at ways to namespace your code in Ruby, and how very, very different it is to PHP. I’ve only really scratched the surface when it comes to Modules in Ruby, they’re a truly versatile and complex beast!

If you’ve got any tips on working with Modules, let us know in the comments!

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://www.itmitica.com/en/ IT Mitică

    Nice article. Very good, explicit and funny examples.

    One thing I feel the need to mention: using include can sometimes require… require. If the module is in a separate file.

  • Cody Christofferson

    The example you gave in the Ruby Namespacing section where the Good namespace overrode the Evil one for Animal because the Evil namespace didn’t have an Animal class is disturbing. That should be considered an error, not something to celebrate with a ‘Boom’. Anytime code acts outside of the expected behavior it is a bug that needs to be fixed.

    Other than that, your examples are very well explained. Thanks for the info!

  • David

    In the first 2 PHP examples, would not require the declaration of the hello method as “static”?

  • http://opensourceame.com opensourceame

    Hmm, does this mean if I have to declare the PHP equivalent of:

    namespace MyCompanyProjectDocumentParser;
    class XML {}

    as:

    module MyCompany
    module Project
    module Document
    module Parser
    class XML

    That seems really cumbersome to me. :-S