Toxic Elephant

Don't bury it in your back yard!


Posted by matijs 27/06/2007 at 21h12

So, I’m reading Steve Yegge’s latest, and he drops some not so suble hints to the reader that they should apply at Google. I talk about that to my wife, how working at Google would definitely be nice, but that it would mean moving from Amsterdam (the Netherlands) to Zurich (Switzerland), because that’s where Google is in Europe. And then she says:

Zurich has the best zoo in Europe.

Tags 1 comment no trackbacks

People Ready

Posted by matijs 25/06/2007 at 20h27

First, what the hell does Microsoft’s slogan people ready even mean? The campaign’s site seems to think it means you need people to run a business. Well, I don’t see any businesses around run by small rodents, so I guess they’re right. That’s some vision

So, what’s this about? Some bloggers got paid for writing about people ready, and people got upset.
Now, some defend themselves saying they didn’t endorse anything, and some defend themselves saying of course it’s an ad box (whatever an ad box is).

Well, I don’t think this looks like an ad, and it may not be an endorsement of a Microsoft product, but it is an endorsement of a Microsoft campaign. Oh, and look at the right of the page. It says “Click here to submit your own People Ready Business story”. So, that pretty much suggests that the content on the left was also submitted the same way. But of course, it wasn’t.

Luckily, at least one of the entries seems to have been written while drunk.

People readiness is something only people that are ready for people to be ready can be ready for.

All this via Mark’s translation.

Finally, back to the meaning: “people ready” means ready for people, right? Just like HD ready means ready for HD. Well, sort of anyway. But no, it means the people are ready. See?

Campaign lame.

Tags , no comments no trackbacks

A song

Posted by matijs 21/06/2007 at 23h38

Today, at seven months and nineteen days of age, Sophia spontaneously performed her first song. It went like this:

Ba ba baa ba baa, ba ba baa ba baa.

(The bas are short, the baas are long). The piece was performed at a constant pitch. I’m still working on the correct rhythmic notation; it’s pretty complex.

Years from now, we will say: We were there at her first performance.

Tags no comments no trackbacks

How to compile TV output into the latest ati drivers on Ubuntu

Posted by matijs 21/06/2007 at 12h58

The Problem

You have built a home server slash PVR that you want to hook up to your twenty-year-old television. You have gone to several shops to buy a graphics card that actually has open-source drivers for its TV output functionality (i.e., the ATI Radeon A9250). You have dodged salesmen trying to sell you something else (“No, but here is its successor the NVidia so-and-so.” “Uhm, no thanks.”). You finally succeeded by ordering it over the Interweb (and probably should have done that in the first place). Now you want to patch the driver shipped by Ubuntu to actually get TV output working.

Tags , 11 comments no trackbacks

Subversion and tagging

Posted by matijs 18/06/2007 at 14h50

I’ve been using svk for a while now, but I keep bumping into problems with the whole concept of tags being just copies.

The problem is this: In my mind, a tag should be a symbolic name for a particular revision on a particular branch. In subversion (and hence, svk), it’s not. To use a tag in place of a revision, you first have to do svn info to find the corresponding revision number, and then use that in your svn diff or svn merge or whatever.

Subversion should have had a smarter client from the start, one that emulates tags and branches and hides the implementation detail that they are ‘really the same thing’ from the user.

As it stands, subversion has no tagging.

It’s all very annoying.

Tags 1 comment 1 trackback


Posted by matijs 18/06/2007 at 13h13

Last week, I did some work on my website, upgrading to the latest Typo trunk and Rails 1.2, and changing from mod_fcgid to a Mongrel cluster.

Last Friday or so, I rebooted my server. Unfortunately, I had neglected to make the Mongrel cluster start at boot. So for the past weekend, all you have seen here is a Service Temporarily Unavailable message.


Tags no comments no trackbacks

A DSL for making SQL-like DSLs

Posted by matijs 14/04/2007 at 14h42

Setting the stage

Some time ago, I came across SQLDSL, a DSL for building SQL queries. The benefit of using a DSL over plain old string concatenation is that syntax is checked before the database server is hit. Unfortunately, SQLDSL does not deliver. It will happily accept

q = Insert.into[“frot”][“zop”][“blob”].values(“kng”).values[“kgn”]

resulting in

  1. => “insert into ‘frot’ (zop) (blob) values (‘kng’) values () (kgn)”

which is hardly acceptable SQL.

A metasolution

The problem is that each chained call operates on the same class, so the calls can be repeated, even when that’s not appropriate. Instead, each step in the building of the query should return an object of a different class, having only methods appropriate at that stage. Something like this:

class Insert
  1. […]
    def [](*fields)
    return, fields)
class InsertIntoFields
  1. […]
    def values, @fields)
  1. etc.

Of course, this quickly becomes tedious, with all the initialize methods having to be made, etc. Boring, boring. Let’s do some metaprogramming.

First, I need a quick way to create a class with a certain number of instance variables, that are set in the call to new(). That sounds like Struct, but the classes that creates have too many methods that would conflict with a DSL for SQL (like values()). So instead, I took a small, simplified part of Mauricio Fernandez alternative: SuperClass (specifically, I didn’t want any accessors for the fields, or named parameters):

module SuperClass def*fields, &blk) k = do

defined_instance_variables = fields.clone class << self; attr_reader :defined_instance_variables end define_method(:initialize) do |*a| if fields.size != a.size raise ArgumentError, "wrong number of arguments (#{a.size} for #{fields.size})" else fields.each_with_index {|f,i| instance_variable_set("#{f}", a[i])}
k.instance_eval &blk if blk

(Annoyingly, there’s no way to dynamically create methods with arbitrary arity, without resorting to eval-ing a string.)

The heart of this metaprogramming is this module:

module DSLChain def self.create(*fields, &blk) k =*fields) k.extend(DSLChain::Link) k.instance_eval &blk if blk k end module Link def add_step(func, field=nil)

div = defined_instance_variables
fields = div.clone
fields << field unless field.nil?
n = DSLChain.create(*fields)

define_method func do |a|
vals = []
fields.each do|f|
if div.include?(f)
vals << instance_variable_get(“@#{f}”)
vals << a if a.size > 0

Stepper::Step#add_step(func, field) adds a method called func that creates an object of a new anonymous class, optionally adding a field called field. It returns the new anonymous class, so theses calls can be chained.

This means we can do the following:

  1. Insert …
    Insert = DSLChain.create(:table) do
  2. Insert.into creates an instance of this class.
    def self.into(table)
  1. Insert.into[fields].values[values]
    add_step(:[], :fields).
    add_step(:[], :values).class_eval do
    def to_sql
    cn = table.column_names @fields.each {|f| cn.include?(f) or raise "Invalid field: #{f}"} raise "Incorrect number of values" unless @values.size == @fields.size res = "insert into #{table.to_s.downcase} ("
    res << @fields.join(", ")
    res << “) values (”
    res <<{|v| v.to_sql}.join(", ")
    res << “)”

In the middle there, each call to add_step(func, field) creates a new intermediate anonymous class that results from a call to func on the previous one. The result is that after creating an Insert object with Insert.into, the call sequence is forced to be

Insert.into(SomeTable)[“some”, “column”, “names”]. values[“these”, “are”, “values”].to_sql

Aside One: For this to work, Insert.into takes some object that has a method column_names, like ActiveRecord objects. I’m also assuming appropriate to_sql methods to be defined on String and Numeric)

Aside Two: I changed the syntax a little bit from SQLDSL, since I like it better that way.

The original example then results in:

  1. => undefined method `[]’ for #<#:0×30050220 @fields=[“id”], @table=Frob> (NoMethodError)

More examples

If you want two options, you can do this:

Sample2 = DSLChain.create(:one) do k = self.add_step(:foo, :two) k.add_step(:bar, :three).class_eval do def to_s “A bar: #{@one}, #{@two}, #{@three}” end end k.add_step(:baz, :four).class_eval do def to_s “A baz: #{@one}, #{@two}, #{@four}” end end end“one”).foo(“two”).bar(“three”).to_s
  1. => A bar: one, two, three“one”).foo(“two”).baz(“four”).to_s
  2. => A baz: one, two, four

Where to from here?

This was mainly a proof-of-concept, of course. There is now a DSL to make DSLs. I haven’t even begun to create the DSL for the select statement, and insert is far from complete. Doing the conditions of the where clause is yet another matter, although ez_where could prove useful for that.

On the other hand, I may not get round to adding all those parts. The metaprogramming was the best part, anyway.

On the gripping hand, wouldn’t it be nicer to have a DSL that actually looks like Ruby’s array operations, such as grep and map? That would be so much more beautiful.

Tags no comments no trackbacks

Who told you to come to this book store?

Posted by matijs 10/04/2007 at 22h22

Say you’re an online book store, and you have an affiliate program. Of course, affiliates come and go. So, what do you do when, say, slashdot stops being your affiliate, and someone clicks on an affiliate link left lying around in an old book review? Do you

  1. Show the book anyway, but not pay the affiliate? Or…
  2. Tell a potential customer to go elsewhere?


Tags 1 comment no trackbacks

Strike, Stones

Posted by matijs 30/03/2007 at 11h44

For work, I’m in Chennai in India. Up to today, I have seen the apartment where we are staying, the office, restaurants, and the streets in between. That is actually already a lot to see: There’s always a lot going on on the streets.

For tomorrow, a trip was planned to Mahabalipuram, but now there’s a big strike planned, and the trip was canceled. The reason is not that there won’t be transport, but that people will be allowed to throw stones at cars without fear of punishment.

Tags 1 comment no trackbacks

Resistance to Posting

Posted by matijs 25/03/2007 at 13h05

Daring Fireball talks about about an interesting post by Tantek Cilek about Human Interface Design. It’s true that there is some cognitive load in posting a blog entry as opposed to just answering What are you doing?

Partially, that resistance is good. Like forums, or blog comments, the Twitter entries are mostly like noise. A soothing background hum that lets you know other people are alive and going about their business. Unfortunately, that business is often uninteresting in the long run. So how long are we willing to store it, even for ourselves?

On the other hand, it is annoying that I have to come up with a title that covers this little post that wanders all over the place. Or that so many thoughts end up as half-finished posts in my drafts pile.

Tags , no comments no trackbacks