ucantblamem

Hi, I’m James Angus. I have a greed for learning, an obsession with all things web; I am in love with standards, accessibility, creating things for use by people and yes, this site was designed on a mac. Read on ยป

OpenSUSE

26th Mar 2008

It’s a well known fact that if you want a usable linux distribution, you download Ubuntu. Whether you’re a system admin looking for a server environment that’s effortless to update or an “average joe” looking for a cheap alternative to the commercial operating systems; (cue corny advertising voice) the canonical team have a solution for you!

However, like many IT pro’s, I like to investigate alternatives and try new things. This curiosity led me to download OpenSUSE recently and I was pleasantly surprised by what I swiftly had installed.

The 650MB “live-CD” is based on SUSE Linux Enterprise Desktop (SLED) and is actively developed by Novell, in partnership with an ever-growing community. The contributions of a commercial entity are noticeable, particularly in the User Interface - applications are very easy to find and most of the settings are modified with assistance from an accompanying wizard. In fact, OpenSUSE is the first distribution that I’ve used without having to touch the terminal.

Like any other variation of Linux, OpenSUSE is not without its’ share of “issues”. Because I installed it as a Parallels virtual machine, networking should be seen as a standard ethernet connection - and it is. However, the system does not seem to automatically connect itself like many every other operating system; I am forced to select “Wired Network” from the networking menubar-item, every time I login.

Once I got my head around this small quirk, I opened Firefox and clicked on the “Novell” bookmark - as a test - only to discover that Novell’s own website requires Flash, which is not included in the default install of OpenSUSE. Yes, I understand that as a piece of “Free” software the developers are reluctant to include proprietary plugins anything, but it sure doesn’t look good - from a “user” perspective - if the developers’ own website isn’t compatible with their products.

My final gripe isn’t relegated to OpenSUSE alone - in just about every *nix-based system I have ever tested, font-rendering has been well below the industry standard. As with the flash issue, this has a lot to do with Linux’s aversion to using proprietary fonts and the substitutions simply lack the spit-n-polish that you get from commercial typefaces. But, I believe this is really only a small part of a much deeper issue.

Behind almost every Linux interface is a windowing system known as “X” and my suspicions are that the poor typesetting and anti-aliasing can be directly attributed to this system - and not so much the typefaces themselves.

From a practical stand-point, some might argue that supposed “poor” anti-aliasing is a pithy point and hardly worth the mention. To that my reply would be: “Have you seen OS X or Windows Vista lately?“. The industry is clearly moving towards more eye-pleasing visuals and subtle animation to enhance the experience - so why not Linux???

In OpenSUSE’s defense, I should point out that included, is an animation system, which I assume is enabled on hardware that supports it (not mine however). I also really like the general look and feel of OpenSUSE - the icons, colour-scheme and placement of GUI elements make the entire operating system feel welcoming and finessed. But, on closer inspection (and I mean “face up to the screen” closer) the dithering looks quite chunky and that typesetting issue raises the alarm-bells once again.

Graphics issues aside, I honestly believe that my mother, who is barely computer literate, could install and use this Linux distribution with little trouble. Clearly the community behind this operating system have been working hard to make it inviting and easy to use - and if anyone ever comes up with a better windowing engine than X, I’m sure Linux will be well on its’ way to destroying the evil empires (Microwho???).

Overall, I am very impressed with OpenSUSE and as a result it has climbed its’ way to the top of my “favourite linux distro’s” list. Unfortunately, it hasn’t amassed the strength to reef me from the clutches of cupertino - though vista’s smooth skin and easy smile has stolen my stair once or twice in recent times. Perhaps Ubuntu’s “Hardy Heron” (due out in April) will be not just a credible opponent for the Green Chameleon, but a worthy platform for even this most fussy of power-users - we shall soon see.

Ruby, CGI and the attack of the ignorant

22nd Mar 2008

I have been developing Rails applications for a year or two now and have even deployed a couple on my own Media Temple account (no linkage, sorry), however I’d never attempted to put together a simple ruby script in my cgi-bin.

In the past, I have written python and perl cgi scripts, but never ruby. So, today I started working a little script to help me quickly setup SVN repositories… But, I quickly found that all my knowledge of UNIX, scripting and CGI equated to squat when I was greeted with a starkly contrasted “Internal Application Error” page - otherwise known as an HTTP 500 error.

Debugging the problem, I checked that:

  • My script had 755 permissions
  • The script belonged to the correct group
  • The shebang line was correct: #!/usr/bin/env ruby
  • I ran the script from the command line
  • But, everything seemed fine.

Finally, I turned on error logging from the Media Temple (Plesk) control panel and refreshed the page again. On inspecting the error log, I noticed the line “Premature end of script headers” - What the heck is that???

After quite a bit of Googling to find the actual meaning of this error, it hit home that unlike PHP, general-purpose scripting language - such as ruby - don’t send a default set of HTTP headers to the browser and hence Apache wasn’t sure what to do with the results from the CGI.

Adding the following line fixed my troubles and allowed me to start building out my little utility:

print "Content-type: text/html\\n\\n"

For anyone who wants a very quick “base” script to check your servers’ setup and start building your own ruby-cgi script, try throwing this into a *.cgi file in your cgi-bin:

#!/usr/bin/env ruby
print "Content-type: text/html\\n\\n"
print "Hello world"

PHP: Casting Objects

20th Mar 2008

Working in an MVC environment, one of the things that we do quite often is take a record from a database and send it to the view for display in some form or another. In a strict MVC paradigm the view really shouldn’t know the names of the fields in the database, yet all too often you will find that the code behind most applications is simply loading a row from the database as an object and sending that object - through the controller - to the view and echo-ing out each property of the object as necessary.

One of the major reasons for doing things this way is that too much effort is required to take one object and make it more meaningful to the view. The problem is compounded when you are taking a series of rows - or an array of objects - and sending that to the view.

Now, in practical terms, it really doesn’t matter; the views ultimately get processed by the application language before they get to the client, so you could hardly say that the controller is exposing your data structure (or any other such nonsense). In any case, this relatively small problem has been on my mind for some time and it wasn’t until recently - while working on an unrelated problem - that I found a solution.

The function that I came up with allows you to “cast” an entire object into another object structure using a given format. Take the following object for instance:

$obj = new stdClass;
$obj->name = 'Jeff';
$obj->id = 39;

A very simple object with two properties - name and ID. Now, if we wanted to make this an option in a select-list for example, ideally the view would accept three properties: The value (for the “value” attribute of the tag), the text (which would display in the select-list itself) and the title (attribute, because we like semantics right? :P). What we would really like this object to look like is this:

$obj = new stdClass;
$obj->text = 'Jeff';
$obj->title = 'Jeff';
$obj->value = 39;

In pure PHP, we would normally do this like so:

$obj = new stdClass;
$obj->name = 'Jeff';
$obj->id = 39;

$new_obj = new stdClass;
$new_obj->text = $obj->name;
$new_obj->title = $obj->name;
$new_obj->value = $obj->id;

This is a very raw and relatively unmaintainable solution, especially for objects with plenty of properties - like most database records. What we really need is a function that, give an object and some kind of map, can take the properties from the original object and create another object using the map. Here is just such a function:

/**
 * Take one object and cast it to another object structure using a given format
 * The '&' symbol can be used in the rules to copy a property.
 *
 * @access public
 * @param object $obj The original object that will be cast
 * @param array $rules An associative array of key/value pairs. The key is the name of the current object's property and the value is the new key for the "cast" object.
 * @param mixed $blank_value The value given to a property if there is no existing property available in the original object
 * @return object
 * @author James Angus - ucantblamem.com
 * @copyright (c) James Angus 2007. All rights reserved.
 * @license MIT License - http://www.opensource.org/licenses/mit-license.php
 * @version 1.0
 */
function cast_object($obj, $rules = array(), $blank_value = 0)
{
    $obj = (array) $obj;
    $fin = array();

    foreach($rules as $key => $value) {
        if(isset($obj[$key])) {
            $fin[$value] = $obj[$key];
        } elseif (substr($key, 0, 1) == '&') {
            $key = str_replace('&', ", $key);
            if(isset($obj[$key])) {
                $fin[$value] = $obj[$key];
            }  else {
                $fin[$value] = $blank_value;
            }
        } else {
            $fin[$value] = $blank_value;
        }
    }

    return (object) $fin;
} // cast_object()

With this function we can now rewrite our little example like so:

$obj = new stdClass;
$obj->name = 'Jeff';
$obj->id = 39;

$new_obj = cast_object($obj, array('name' => 'text', '&name' => 'title', 'id' => 'value'));

Note that the second key in our array has an ampersand appended. Because array keys must be unique, I built in a mechanism for copying a property more than once. In the above example, the value of the “name” property will be copied to both the “text” and “title” properties of the new object. Also of note is that you can use multiple ampersands to copy a property as many times as you need.

Lastly, I have allowed you to specify a value for properties that could not be found in the original object. This means, that the object returned contains all the properties specified in the rules.