April 18, 2010

Writing elsewhere

I moved parts of my writing over to Gem Session, which focuses on Ruby development and software testing.

This blog might still receive the occasional post in the future, so keep it in your feed reader if you like.

September 4, 2009

Should I test for translated strings?

Last night I visited the Ruby User Group Berlin where Clemens Kofler and Sven Fuchs were talking about the future of the Rails I18n API. Many friendly and smart people made for a wonderful evening.

After the talk I brought up the question whether tests should call the translation API when checking for the presence of a string.

Take this simple Cucumber story:

When I go to my bookings page
And I press "Delete booking"
Then I should see "Booking deleted"

This story will fail when the locale comes back from an external translator who deemed "Remove" a friendlier label for that button. We discussed some ideas how to make our stories less brittle in the face of translation changes.

One idea was to have the tests look up keys in the translation store:

When I go to my bookings page
And I press the translation of "bookings.index.delete"
Then I should see the translation of "bookings.index.deleted"

This story would survive translation changes, but pollutes your pretty Cucumber stories with implementation details. You also need to extend existing step definitions to look up translation keys.

Nico Hagenburger came up with the idea of using a translation store that just returns the translation key as its translation, so you could just use existing step definitions:

When I go to my bookings page
And I press "bookings.index.delete"
Then I should see "bookings.index.deleted"

Clemens' advice was to ninja around naming actual strings by checking the DOM tree for the presence or absence of elements:

When I go to my bookings page
And I press the delete button
Then I should see a confirmation flash

I like how this tests for the confirmation message. This probably won't work as well for following links and pressing buttons, where you need to distinguish that one link from the 50 other links. Already the step "When I press the delete button" from our example above is tricky to implement well.

A workable compromise might be to only check for text fragments:

When I go to my bookings page
And I press "Delete"
Then I should see "deleted"

While this might break after a translation change, you're cool as long as the new translation contains the word "deleted".

Another interesting idea is to keep around a development locale which never gets shipped to the translator. The development locale would retain all the labels, messages and terminology used during initial development of the application. The translator creates an English locale based on it but never changes the development locale. Your tests would never break from translation changes, at the expense of maintaining one additional locale.

Comments (1)

September 2, 2009

HOWTO: Rock at CSS and keep your sanity

I happen to be good at writing robust CSS. Years of exposure to a world of broken browsers made me develop a couple of practices that make my styles break less. All these practices share a common theme: Make it easy for the browser to understand you. If you express your styles clearly, any browser will be happy to render your pages as intended.

I will dispense this advice now.

Tag anorexia is a false idol

I often see people striving for layouts using as few div and span tags as possible. Get over it. Minimalistic tag usage is a false idol with zero ROI and requires unmaintainable style acrobatics to make it work. Be generous with divs and spans and your styles will be much cleaner and easier to reuse.

Don't accept stacking margins

It is not acceptable when the margins and paddings of adjacent elements randomly stack or merge with each other, scattering gaps small and large all over your page. It shows that you have trouble making styles work together, which is more important for the overall impression of your page than the look of individual elements.

As a general rule, the paddings of adjacent elements never merge with each other. Adjacent elements try to merge their margins but it doesn't work reliably in all situations and browsers. Especially the merging of margins at the top or bottom of containers, and across different depths of the element tree is hard to manage consistently.

Strongly consider applying margins and paddings only to the right and bottom edge of elements, while resetting margin and padding at the top and left to zero. This prevents the stacking of margins in most situations and puts you back in control.

Sense ambiguities and avoid them

Develop an eye for possible ambiguities in your styles. Take this example:

<p>A paragraph</p>
<strong>Some inline text</strong>

Which block element interacts with the boundary of that <p>? An imaginary <div> wrapped around that <strong>? It would be clearer to not mix block elements and inline elements within the same parent element. Cultivate a sense for such vagueness and avoid it. Even if you often get away with unclear instructions it's not worth the world of pain when the next browser update starts to guess wrong.

Prevent float trouble early

Always clear your floats or your layout will break as real user content replaces your conveniently sized lorem ipsums in production. Whenever you float something, your next concern should be clearing the float further down. Use a zero-height <div class="clear"> if there is no other element to do the job.

Also don't build pages where everything floats, even if those floats get cleared eventually. It's bad karma.

Default browser styles can be anything

Understand that whenever a given style isn't defined in your stylesheet, the browser can default to any value at all. Some people use reset stylesheets to regain control. At the very least you should be worried about margins and line heights whenever you use a block element.

If your site isn't a near-pixel perfect carbon copy in Firefox and IE you should be worried because it means you're relying on a default style without knowing it. Do demand control over your layout. Don't just blame IE.

Semantic markup is overrated

The selection of "semantic" tags available in HTML is so small and unexpressive it's laughable how much bandwidth was wasted arguing over their proper usage. Stop caring if a given element should be a <p> or a <div> or an <address>. Do use proper headings, but other than that just use whatever is the easiest to style. If your site looks usable when you turn off styles, you're semantic enough.

Some people will argue that semantic markup equals accessibility, which is wrong. Screen readers are better at handling tag soup than you think. They get a bad rap from people who are clueless or want to sell accessibility makeovers. Instead of guessing what a screen reader can or cannot handle, try it out yourself. Also remember that there is more to accessibility than proper markup and styles.

Fake the designer

Most of us don't have a proper design education. I know I don't. You can still produce decent results if you follow two simple rules and leave the fancy stuff to the pros:

  1. Whitespace is important. Don't have different margins and paddings everywhere. Pick a standard margin that separates block elements on your page and stick with it. 15 pixels often work for me.

  2. Colors are important. Never use pure colors like #00f. Tint your colors like #12e and they will look much nicer. Also pick a color palette and stick with it. Creating a good palette is hard, but there are tools to help and sites with great premades.

Don't demand the impossible from your browser

There are times when the browser would have to read your mind in order to render your styles as intended. For instance, you have a container element with some children nested inside. The width of the container is dependent on the width of its children (it floats), but the width of a child is dependent on the width of the container (their width is defined in percent). How should a browser make sense of this undecidable mess?

Try to be as clear as possible when describing your layout. Don't make everything dependent on everything. Always root dependent styles in definite expressions such as "this column is 300 pixels wide" or "this box grabs all available space" and any browser will gladly follow your instructions.

June 22, 2008

Setter methods make kittens cry

Do use setters if being edited is the central purpose of that class. Do not use setter methods to create an object. Setter methods intended for creation will still be accessible during the whole lifetime of the object. Someone might use them and break all your stuff. Basically everything involving caches or hashCode() will die in your arms. Like when changing an attribute will cause some remote piece of code have maps with broken mappings and suddenly sport sets with duplicate elements. Being paranoid makes for good code karma.

Furthermore, do not use setters to wire up required attributes. I often see code like this:

Foo foo = new Foo();
foo.setAttribute1(a1);
foo.setAttribute2(a2);
foo.setAttribute3(a3);

This is bad because until the last line has executed, foo lives in some sort of twilight zone, where it exists but may not be used yet. Your class should not allow to create an object with invalid state. Better use the constructor to wire up attributes:

Foo foo = new Foo(a1, a2, a3);

Some people will argue that this will become hard to read if you have a lot of attributes. In such cases you should use a Builder separate factory class that collects all attributes with setters and can create the object once all required attributes are present (otherwise throw an exception). This shifts the enforcement of valid object creation from compile time to runtime, but still fails fast if necessary.

A related point I would like to make is that immutable objects (objects that cannot change their state after instantiation) also make for good code karma. Mutable objects can be a pain to work with and force their clients to make defensive copies. Immutable objects are also thread-safe by default (you might still screw it up though).

April 12, 2008

You don't know Java: Method type parameters

When someone tells you they know Java, smile and say "no, you don't". Proceed to soften them up with questions about covariance and contravariance and how they relate to parametrized types. When they start crying, go in for the kill.

But let's talk about something nice today: Method type parameters. Few people know that type parameters in Java are not limited to types, but that every method and constructor can declare their own type parameters. And if this alone wasn't cool enough, it can actually be useful!

To illustrate, I need a couple of interfaces from Java kindergarden:

interface CanWalk {
    void walk(int steps);
}

interface CanSwim {
    void swim(int strokes);
}

interface CanSleep {
    void sleep(int minutes);
    boolean isSleeping();
}

interface Animal implements CanSleep { }

interface Cat implements Animal, CanWalk { }

interface Dog implements Animal, CanWalk, CanSwim { }

Say we want to write a method that simply takes an Animal and returns it. This is the way we used to roll:

Animal returnMe(Animal animal) {
    return animal;
}

What's bad about this method is, that it returns its value as Animal, even if we gave it a Cat. So if we wanted our cat back, we need to cast it manually:

Cat cat = (Cat)returnMe(new Cat());

We can improve on this by binding a type variable to the returnMe method like this:

<A extends Animal> A returnMe(A a) {
    return a;
}

This way we don't need the cast:

Cat cat = returnMe(new Cat());

To give an actually useful example, let's write a method getAwake that is given a list of objects implementing CanSleep, and returns those objects that return false from isSleeping():

<A extends CanSleep> List<A> getAwake(List<A> potentialSleepers) {
    return Lists.select(potentialSleepers, new Filter<A>() {
        public boolean passes(A element) {
            return !element.isSleeping();
        }
    });
}

... with Lists.select working like select in Ruby lists, but you cool kids already figured that out by yourself. Again we can give getAwake a list of cats, and get a list of cats back, rather than a list of animals. You can see how method type parameters allow us to be more expressive about our method signatures.

This might be stretching the attention span of the YouTube generation, but here's one more cool thing: Method type parameters with composite upper bounds:

<Duckish extends CanWalk & CanSwim & CanSleep> void rockTheBeach(Duckish duckish) {
    duckish.walk(100); // check out the chicks
    duckish.swim(20);  // cool down in the water
    duckish.sleep(60); // take a nap
}

This is about as much fun as you'll ever be able to have writing Java. Enjoy!

March 21, 2007

Names are important

For a profession that is all about naming things, most programmers are being terribly careless with names. Although you get away with it most of the time, you look so immensely stupid when two pieces of code disagree over the meaning of a name. Names are important.

One of the things I still love about Perl is that, by convention, it is considered rude to invade other people's namespace. So we put all our public methods and constants into the @EXPORT_OK array and let the client decide which part of that he wants to use in their code. I should be able to do the same with code extending existing classes: Let me decide which extensions I want patched in on a per-class basis. I believe extension methods in C# 3.0 work this way. Do copy this.

Another name issue few languages get right are namespaces. Namespaces are important, because sooner or later you will have two different Node classes in your project and you need to tell your code which one to use. Let's look how some popular languages are dealing with this:

PHP

Bashing PHP is a bit like beating up an old man, but here we go anyway: PHP has no notion of namespaces at all. To work around this, people are using Really_Long_Classnames_With_Packagish_Names_Prefixed to lessen the chance of namespace clashes. LOL.

Java

Has a wonderful culture of putting classes in packages named after some domain you own. So my Node class would be packaged as org.netalive.swsu.Node and people could import this name and just write Node. Bad: When you need to use two different Node classes in the same piece of code. As you can only import one Node without name clashes your code will look like Map<Node, incredibly.long.package.name.of.other.Node>. Horrible when it happens, and it happens frequently. For instance, both the most basic GUI widget in Swing and the most basic data structure in Java are called List.

Perl and Ruby

Uses Package::Subpackage::Classname syntax for improved looks, but since you cannot import or alias these long names, this is more about organizing files and not really better than PHP's Package_Subpackage_Classname workaround. At least you can switch into a namespace and add and replace methods without using fully qualified names. It's kind of OK for untyped languages because you only need to reference types when calling a constructor or another static method. Still the possibility of another Tree::Node class in a second library is always there and sometimes urges you to use more unique package names than you would like.

Python

I don't speak Python, but from what I've seen this is a language that got namespaces right. You can import a namespace as in Java, you can selectively import symbols as in Perl, and here's the goodness: You can import reallylongmodulename as shortcut to alias reallylongmodulename into shortcut. Nice.

I think what Python does (importing and importing into aliases) should be the minimum requirement for any language that wants to take names seriously. The package naming convention from Java is cool, because the DNS is the only naming scheme humanity ever reached something like an agreement over, and unique names are good. Imagine blowing up the planet because some piece of code felt ambivalent about the semantics of System.Nuke. We would look all kinds of stupid if this sort of thing ever happened.

March 20, 2007

Whoops! Open classes not cool after all!

Ruby, Perl and many other languages let you reopen an existing class or namespace and add additional methods to it, or replace existing methods with new code. Everyone thinks that is "like super-cool" and "really feels the spirit of getting things done", probably accompanied by some generic "LOL Java, agile languages FTW!" rant.

Surprisingly, open classes have one serious problem: People are using them!

Right now the two most popular uses for reopening classes are (1) adding methods to core classes like objects or lists and (2) patching totally not public code with your own funky version. Both are terrifyingly bad ideas which will probably break with the next update of the code you're patching, or as soon as another clever library attempts to do the same. But let's enjoy some examples together:

  1. It is impossible to use prototype.js and json.js at the same time because prototype.js does something nasty to Object.prototype. But never mind since these are only the two most commonly Javascript libraries on the planet.

  2. What Rails is doing to the Ruby core, and what some plugins are doing to Rails, is downright scary in some places. Thankfully Rails is heavily maintained and bugs are patched quickly.

  3. While developing a World of Warcraft addon in Lua, we discovered that the preferred way to intercept chat messages was to replace the existing message handler, intercept the messages you need and hand over the rest to a copy of the old handler. Unfortunately, since our addon name was lexically smaller than the name of another addon that used the same trick, and World of Warcraft loads addons in alphabetical order, our new message handler was replaced by a third addon handler by that other, lesser addon and everything went to hell.

I'm not even sure if the last example is valid in this context, but it's also about bad scope and globals, and I really needed to stress the fact that I'm writing kick-ass World of Warcraft addons this very minute.

Anyway, don't you think it's funny how twenty years after people realized that "globals are teh suck" we're falling into the same bad habits all over again? Yes, open classes are fun toys to play with, but you can also fuck up royally if you don't pay attention. So, please, do think about what happens when other libraries attempt to pull the same hackery as you. Do consider the chance that a second library also wants to decorate the draw method, and do assume it will also save the existing method using alias :original_draw :draw. And OH MY GOD do not patch up private methods that have clearly not been cleared for public consumption by the original author!

Patching private methods. I mean, what the hell. Think of the children!

January 16, 2007

Gapless MP3 loops in Flash

When encoding a sound loop as MP3, the encoder will add ugly gaps of silence at the beginning and end of your track, making the resulting file not very loopable at all. This is due to the way MP3 encoding works.

Although there are some instructions (scroll down to "Part 2") how to remove those gaps from your sound file, the amount of hackery involved is not for the faint of heart. The same guy also wrote a tool to automate the process but it's restricted to a maximum of 8 seconds of sound, and you can totally not buy a full version.

You're lucky if you're working in Flash however. The MP3 encoder inside the Flash IDE knows about the problem and will make sure any MP3 it compresses will loop without gaps. So:

  1. Have an uncompressed sound loop as WAV oder AIFF. If your loop is already an MP3, remove the silent padding at the beginning and end of the track and save it as WAV.
  2. Import the uncompressed sound into the library of your clip.
  3. In the sound properties, set the desired MP3 compression.
  4. Loop away.

December 24, 2006

You don't know jack about thread-safety

All you hotshot programmers need to drop what you're doing and secure a copy of Java Concurrency in Practice. 50 pages into the book my face was frozen in pure horror, as Brian Goetz and his friends happily ran over everything I ever thought I knew about thread-safe programming.

What do you think the following code will print to the console?

public class NoVisibility {

    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while (!ready) Thread.yield();
            System.out.println(number);
        }
    }

    public static void main(String[] args) {
        new ReaderThread().start();
        number = 42;
        ready = true;
    }
}

Unless your answer is "either zero, 42 or nothing at all" you really need to read the book before someone notices.

December 8, 2006

There's nothing wrong with bloggers

<tom> there's nothing wrong with bloggers
<tom> it's just that like
<tom> when they're ALL in ONE ROOM, all SWEATING, all POSTING, 
<tom> all EDITING ONE DOCUMENT COLLABORATIVELY WITH SUBETHAEDIT, 
<tom> it gets a bit much
<liz> do non-bloggers not sweat then?
<tom> they do, but their sweat doesn't have an rss feed

Comments (0)