On March 10, 2010
Inspired by the "Benificially Relating Elements" phrase of Kent Beck, I started
out creating a builtin weblog for my webshop platform. The nice thing about the
idea is that it helps you find relations between elements that you already have.
I started with the "What is a weblog?" A weblog is a chronological list of
pages. By answering this way, I can reuse two elements that already are
supported in the webshop: collections and pages.
Collections are lists of products and other collections. Nothing more nothing
less. By increasing the scope of collections a little bit, I can also include
pages.
A page is a piece of text that can be shown in the webshop. It has an url. By
making a weblog post to be a page, I can reuse all the infrastructure of pages
for weblog posts. This includes: creating, editing, saving and showing. The only
thing missing from a page is the creation date, which is needed to sort the
weblog posts chronologically.
The other two things that simplified the weblog feature are plug-ins and
routes. Plug-ins are small packages of code that are loaded on start of the
request and connect to rendering and loading and saving code.
Routes are ways to convert urls to controllers. The latest release made it
possible to create routes based on regular expressions and all urls are parsed
using this. This allowed me to use the names of the pages in the urls.
By relating the pieces, I created a new feature, that is useful in itself
without having to write a lot of new code. Now when I add 'comments' as a
feature to the weblog, I will also automatically add comments as a feature to
pages, because they are the same thing.
Two features for the price of one. I like it.
On March 8, 2010
The next feature I will talk about, is the given/when construct. This was
added in perl 5.10. It works like switch/case in other programming
languages, but is much more powerful. The matching is based on smart matching,
which is another feature added in 5.010;
I will start with a simple example to give you an idea of the syntax that is
used.
use 5.010;
my $x = <>;
chomp $x;
given ($x) {
when ([0..99]) {
say "Looking good";
}
when ([100..199]) {
say "That's a bit much";
}
default {
say "This could be a problem";
}
}
This code compare the value of $x with the array's in the when statements.
If $x is between 0 and 99 (inclusive) it will the text Looking good. If it's
between 100 and 199 then it will say That's a bit much. The default block
will be called when the value isn't matched by the when blocks.
Next I will give a more useful example, but not much more.
use 5.010;
my ($x, $y) = (0,0);
LINE: while (<>) {
my @parts = split /\s+/;
for (@parts) {
when (/^x(\d+)/) {
$x = $1;
}
when (/^y(\d+)/) {
$y = $1;
}
when (/^p/) {
say $x + $y;
}
when (/^q/) {
last LINE;
}
}
}
This example reads lists of tokens from STDIN and matches them and executes code
based on the input. In effect it's a small programming language. Notice that
this code doesn't use the given statement. It's not needed here, because the for
already assigns each element of @parts to $_.
It's also possible to use simple expressions like you would use in an if statement.
For example:
use 5.010;
my $age = <>;
chomp $age;
given ($age) {
when (!/^\d+$/) {
say "Not a number";
}
when ($_ > 100) {
say "That's quite old";
}
when (18) {
say "Now your life begins...";
}
when (0) {
say "Just born, and already using the computer.";
}
default {
say "I have nothing useful to say about '$age'";
}
}
As you can see when is quite smart about what to do with different
expressions. The first when clause contains a negated regular expression.
This will be matched using $age !~ m/REGEX/. The second one do what you
expect. The 18 and 0 clauses will match using $age == 18 and $age == 0.
You should watch out with comparing to 0 because this will also match empty
strings or just strings. For example if $age = 'hello', when(0) will match.
Smartmatching is really powerful. With given and when it's easy to use this
power for deciding what to do with the value that you've been given. You
should take a look at the manual for more information about the possible smart
matches and the things you can with given and when.
On March 2, 2010
When I'm programming, I sometimes need to use a problem solving pattern, that
Kent Beck called Parallel.
The pattern tells us that when your making a change you should also leave the
old way of doing things in the program, so you can gradually move to the new
solution. This helps in situations, where you can't just flip a switch to
migrate.
The problem with this however is, that you do have to migrate all the way to
the new solution, because otherwise you will have twice the code and data in
various states.
When I'm using Parallel, I like to keep an eye on the progress and I don't like
to go back to the old way. To help me with this I created a unit test that monitors
the progress that I make, while changing the program and the data.
It would be nice to have a test module that keeps track of this, but at the moment
I only have a small test program. It does three things:
- Read the previous count (of old way occurences)
- Check if the current count is smaller or equal to the previous count.
- If true, the test succeeds and then writes the count to a file. If false, the test will fail.
This way the tests will only succceed if I make improvements or if the code
stays the same. This way it can only improve the code.
On February 28, 2010

On February 24, 2010
Example of how you should send email in 2010 with Perl.
#!/usr/bin/perl -w
use strict;
use Email::Sender::Simple qw(sendmail);
use Email::Simple;
use Email::Simple::Creator;
my $email = Email::Simple->create(
header => [
To => '"Peter Foo" <foo@example.com>',
From => '"Peter Bar" <bar@example.org>',
Subject => "What's up",
],
body => "Hey, how are you doing?",
);
sendmail($email);
You can see that this is simple enough. First you create an
Email::Simple object. This object will format the message that wil be
sent.
After that sendmail will send this message using it's default transport.
The nice thing about using these modules is that you can, while testing,
replace the default transport with testing modules.
use Test::More;
BEGIN { $ENV{EMAIL_SENDER_TRANSPORT} = 'Test' }
use YourModule;
YourModule->run;
my @deliveries = Email::Sender::Simple->default_transport->deliveries;
is(@deliveries, 1);
This way you can check how many emails were send using in the code your
testing. By picking apart @deliviries you can check out the text of the
emails that were send. See Email::Sender::Transport::Test for more
information about this.
On February 17, 2010
I use prove from Test::Harness to test the code of my Perl projects. The
program prove runs tests files and summarizes the output. If tests fail then
it shows the error in its output.
The problem is, my defaults aren't the same as the defaults that prove uses.
I keep my main application files in app/lib and a few vendor libraries in
vendor. The problem with this is that I have type out the options of prove
every time I wanted to test. For the longest time I used a Makefile to solve
this problem.
Then I found out about .proverc. If you put this file in your current
directory of in your home directory, then prove will use each line as an
extra command-line option.
The .proverc in the root dir of my project looks like this:
-Iapp/lib
-Ivendor
-r
It includes two extra directories in the Perl include path; app/lib and
vendor. It also find all test files recursively in the t directory, which
is also not a default setting of prove.
On February 16, 2010
In the same way that Ubuntu has a list of problems that are trivially fixable
Paper cuts, you could also do that for
other programs. Google Buzz is a service that I use
at the moment. I like this program, because it seems to take public standards
into account and it will allow decentralized communication between people. So
today I will spend some time to write down the few problems that I found that
will be trivially fixable.
Ubuntu's definition is this:
a paper cut is a trivially fixable usability bug that the average user would
encounter in default installation of Ubuntu or Kubuntu Desktop Edition*.
Paper cuts
Muting a Buzz is very slow. This seems to be a problem with the fade. The
thing is, it is nice that the Buzz fades away, but I don't need to see it. It
should be fast. It also moves the viewpoint to the top. Please don't move my
screen.
Clicking a Buzz that isn't selected will move the screen to the start of the
Buzz. If you scroll up from the next Buzz to a comment above in the previous
Buzz, and then click on the comments, it will move the viewpoint to the start
of the Buzz.
The @-prefix for responding to people is ugly, when used with the domain
name. There are better ways to do this. A few suggestions: '->', 'r:', '#',
'>', '>>'. And I say screw backward compatibility and expectations.
So if you like the things I said here, please find a way to share it with some
people. There seem to be quite a few places where that's possible today.
On February 13, 2010
Jeff on Coding Horror writes:
Among programmers of any experience, it is generally regarded as A Bad Idea (tm)
to attempt to parse HTML with regular expressions.
You should read the rest of the article. I'm mostly of the same opinion about
this as Jeff. Additionally I think that parsing HTML is a bad idea in the first
place.
One of the examples Jeff gives for parsing HTML is sanitizing user input. The
user input will be used on the website as comments for example. I think allowing
people to write HTML and putting it on a webpage is the wrong way to go.
If you want to include user input in a web page there are only two ways to do it:
Encode all special HTML characters. You can start with <, >, &, "
and '. If you encode these then people can send all the HTML they want, but
it's encoded and will not affect your web page. For Perl I recommend the
HTML::Entities module.
The other way to allow HTML is, on a page, where it is their own. If they
want to break their own web page, they should be allowed to do that. This
doesn't mean profiles on websites, but actual websites that are completly their
own.. So you say it is HTML and then use the input verbatim.
If you want to include some kind of formatting for the input, you can use a
markup language. Use a markup language that allows to specify as much
formatting as you like, this could be a HTML-like language, that only
transforms the tags that you want. Therest of the text should be HTML encoded.
On February 12, 2010
Adam Turoff wrote:
I could have written my taxicab number search in C or Java, but I would have
lost interest somewhere between #include <stdio.h> or public static void
main(String args[]) and firing up the compiler.
It's a shame this happens so often. It should be easier to just write the part
your idea is about and then insert it into some thing, that will make the rest
work.
Before being able to try and research your ideas, you need to have the
basic code working. When people ask: why would you write your own X software?
Where X is one of the pieces of software you have written, that looks like
something that already exists. This would be the answer.
If there is a program or system that works for 95 percent or even 90, that
would take a lot of time write. Then there is almost no incentive to create (or
test) a similar tool. An example of this would be Google. Or a computer game
that uses a 3D engine.
These all take many years to create, and there is not much to gain from the
work that is done to get to the same level. To innovate you need to have a
basis; but you will be bankrupt before you even get near.
On February 5, 2010
A few days ago I started using Wave for some real projects. I found out that
Wave is not really hard to use. The problem is that the network effect is
kicking in, but in the opposite way.
Wave is a communication tool. You can use it to send messages and collaborate
on projects with other people. And I think the problem here, is that the other
people are missing.
I remember the first few years that I had internet. Not many friends were using
email. I had email, but I had no one to send emails to. The same is happening
with Wave now to. What use is it to send an email to someone, if you can't be
sure that that person will read it.
I have a simple solution to this problem: install a Wave
notifier.
At the moment I use a notifier that works as extension in Chrome. It's non
intrusive and shows a little number when I have new unread Waves. No
interruption and I can take a look at the Wave that people sent me.
Wave me at peter.stuifzand@googlewave.com.