The writings of Peter Stuifzand

Archive for September 2010

After these two changes I got into an object-oriented (with a splash of functional and generic programming) mindset. So I created a table filter in my template code. A filter is a function that transforms a data structure to an HTML string.

This filter transforms a template parameter value from an arrayref to an HTML table. Currently it only supports lists of items, but it could be expanded to single items. I'm not sure how useful that would be, however. The question is: "How can we produce a nice HTML table from an arrayref?" The answer lies in the use of objects.

A few months ago I created a few classes that allow me to easily transform arrayrefs to HTML. I wrote one Model class and one Render class. The Model class models the information in a list. It's not always required, because the Render class also renders simple arrays, without a model.

The Model classes (there are three, at the moment), have at least three methods: update, length, item. The three classes all implement these methods.

The Render class renders these list Models. The important method on this class is the render method. It renders a HTML version of the table. The set_header method accompanies the render method. The set_header method sets the description of the table structure. This description is an arrayref with an item for each column in the table. Each item consists of, at least, a field and a title. It's also possible to add a class or a link.

These two classes are combined in the template code in the template_table function.

sub template_table {
    my ($type, $value) = @_;
    my $table = Render::Table->new();
    $table->set_header(...);
    $table->set_model(Model::Table::List->new($value));
    return $table->render;
}

This function renders the table, but notice that the set_header function lacks an argument. What argument should we use?

In a explicitly typed language we would have known the type of the $value argument. In Perl we only know that it's an arrayref. However, we can ignore the type of the value inside. The render function only needs a description of the table to be able to render the HTML. The best way to do this is, is by calling a method on the $value. In this case that's a call to the first value: $value->[0]->column_descriptions.

This change adds two preconditions to the function. Ignoring these preconditions, introduces an error. This function only works for non-empty arrays, where the first value has a method, that returns a table description.

What should we do? Can we declare these preconditions? How do we cope with these?

The first precondition — handling empty arrays — can be removed when we add code that returns a table when an empty array is passed as an argument. To solve it we return an empty string. To return an empty table based on the structure of the first value element would be really hard.

The second precondition — the value should contain the method — is already handled by Perl itself; it will throw an exception when the method missing. It could be a problem that we have to test the code, to find this error.

It like how this chunk of code enables us to remove the simpler table generating pieces of template code. These guidelines enabled me to write simpler code.

  • Write code for arrays, ignorant of the type inside.
  • Use objects instead of primitive types. Call methods on those objects.
  • Allow the value to tell you what to do with it.
  • Look for preconditions in your code and know how these are handled.
  • Make your code more general by moving specific code to specific classes.

While I was thinking about how to structure some of my access handling code in my web app, I saw that it currently is impossible to return a 403 code when a user reaches a password protected page.

The biggest problem with returning a 403 is the way the browsers show this problem to the user. The user is interrupted with popup asking them for a username and a password.

I want to propose a way to make it possible to return a 403 and allow for people to login without getting in the way.

403 forbidden proposal

In this image you can see that when a user reaches a password protected page, that the browser shows a small bar on top of the page, that looks just like the 'Save password' bar in newer browsers.

This new bar allows users to enter their username and password for a website. It also allows the browser to assist the user by showing just a login button with a username and password already filled in.

With this approach, the web page below this bar can help the user create a new account or retrieve the password.

Please discuss below, and let me know if there are any problems with this approach.

Update 2010-09-14: Of course, the 403 page is shown when you aren't allowed to view a page. The 401 error code is used to show a login popup. Replace all mentions of 403 with 401 in the above example. Thanks, Klaas.

I've been using Plack for a few days now, and I have to say, I really like it. I rewrote the base of my webshop platform to use it. The change wasn't really difficult and the code is a lot cleaner now.

Especially with the Middleware structure I was able to remove a lot of code from the main application. Middleware classes are classes that are called between the webserver and the main application. These classes have the opportunity to rewrite the request and the response classes for each request.

Because I use the same code for each webshop, but different databases for each customer, so I need a way to select the right database for a request. This is a great use for a Middleware class. The software selects and connects to the database based on the hostname in the request. The connection is then added to the environment hash. And the way back the database connection gets closed.

Furthermore there are already a few nice Middleware classes for logging and debugging. That is code you don't have to write. I really like it.

In Hash function performance Dave Winer writes:

It's been a long time since we looked at the object database in Frontier, so today Brent wrote a little app that checks out how the hash function distributes objects across the buckets for each table in the database.

[... result distribution among buckets ...]

This looks pretty random to us.

And he's right. In the sense that it's just a bunch of random numbers. Not something you would want in a hash function.

Meanwhile in the Hacker News page about this people are talking about a few other things, they thought they should read from this article.

  1. Ignorance. I think it's sarcasm actually.
  2. Performance. Performance isn't always about speed.
  3. Hash function (as in cryptography). In cryptography you use functions that won't collide for documents that are possible. In an object database, collisions aren't important, it's assumed.
  4. Using a built-in hash function. If you built your own platform and language, there isn't always a built-in hash function. Sometimes you need to write one yourself.

I'm really not sure what to say about EWD 1036. This is a must read for people who think we can write better software programs.


Programming will be so different in the future, that people will talk about this time, as the great false start or the Dark Ages of programming.

The coming age (I don't think it has started yet), will be based on mathematics. The software we write will have sturdy theoretical underpinnings that will evolve with the software we write. Where formal methods seem unwieldy now, we will see ways to simplify these. We will prove theorems about structures and these structures will be used again and again. We will find structures in our programming languages and programs and simplify and use these structures from one program to the next.

Programming will be easier than it ever was. We will write programs that are bigger and better than a human has ever seen.

View archived entries