Tigraine

Daniel Hoelbling-Inzko talks about programming

Mongoid .length on query ignores limit

I just ran into this and wanted to share this quite puzzling behavior:

20.times { Fabricate(:post) }
Post.scoped.limit(10).length.should eq(10)
# => Test failed
#    expected: 12
#         got: 20

Weird right? But once you look at MongoDB's capabilities and the Mongoid implementation you'll quickly discover that this is only kind of a semi-bug :). MongoDB supports an .count() command that takes a filter and returns the number of matches documents. This command is being issued by Mongoid whenever you call .length on a criterion (since it's much cheaper than executing the actual query and counting the returned objects).

So don't write tests like this:

# method under test:
def self.most_played
  self.order_by(:play_count.desc).limit(12)  
end

# test
it 'returns the 12 most played items' do
  Video.most_played.length.should eq(12)
end

This test will fail, even though the method is doing everything perfectly right. I'd even say that in a regular ActiveRecord setting this would be a passing test. But since I am utilizing the delayed execution functionality of Mongoid most_played method is only returning a Criteria object that represents the query and can be composed into a more complicated query.

This causes .length to be executed on Criteria where it causes Mongoid to call the .count() method instead of running .length on Array. Since limit is no query parameter it will not be passed to MongoDB and the returning count will correctly be equal to the total number of Documents in the collection.

The more correct way to write that test is to actually force Mongoid to execute it's query and count the result:

it 'returns the 12 most played items' do
  Video.most_played.to_a.length.should eq(12)
end
Filed under mongoid, rails, ruby

German programming-friendly keyboard layout for Mac OSX

This may sound totally hilarious to people used to the english layout, but german programmers use shortcuts like Shift + 8 to write a [ and ALT-GR + 8 for a {. (Oh and semicolons are only available through shift - yay for C-style languages!) The main reason for this is that we have these useless little umlauts üöä that sit right where the useful keys for a programmer would be, were it not for the german keyboard.

But after years of arm-twisting and cursing you get used to that and develop a reasonable degree of efficiency even with a absolutely unsuitable keyboard layout. Only problem: these shortcuts are radically different on the Mac! (And breaking the built-in keyboard of your Laptop is not really an option as others suggest)

Instead of Shift 8 for a brace it's ALT + 5, and the backslash is skillfully hidden behind ALT+Shift+6 yuck!

So I tried for a few days and then I decided to stop the madness! Instead of learning to use yet another crappy german keyboard layout I started to use the standard english one. And it's awesome, once you get used to it feels absolutely natural, and it also shows that all programming languages have been written to be easy on people with english keyboard layouts.

Only problem: I was severly handicapped when writing german emails to customers or writing german translation texts. I mean, my friends and colleagues can read written out umlauts (ä = au ..) just fine, but it looks totally stupid when writing something official and well phrased and you are misspelling stuff (ß can be sloppily substituted by ss, but there are cases where ss is orthographically wrong and in other cases ß would be wrong and ss right).

So I investigated and found this wonderful Mac program called Ukulele that allows you to write your own keyboard layout files for OSX. I took the standard US layout and altered it to incorporate the german umlaut keys where they are actually printed on the keys, but only if you hit ALT. So ALT + ; turns into a ö etc..

Here a quick overview of the english layout (notice how conveniently located all those symbols are):

alt

And once you hold down ALT:

alt

Since most people I mention this to usually give me a: "wow that's a really good idea" I decided to simply upload the .keylayout file so people don't have to bother with Ukulele themselves.

You can download the keylayout here: US-daniel.keylayout.

Installation:

Download the file and place it in ~/Library/Keyboard Layouts/, logout and log back into the machine. Now open your System preferences (Sprache & Text) and search for U.S. Tick the checkbox next to it and you can now select the U.S. Keyboard from the OSX menu bar.

Tipp: If you have the screen real estate to share and are still learning the english keyboard layout it's really useful to enable the "Keyboard overview" (Tastaturübersicht anzeigen in german). You can see in real-time what keys are mapped to what buttons on your keyboard while holding down modifier keys.

Filed under osx, programming

My Photography business

Projects

dynamic css for .NET

Archives

more