Posts from jlaine.net...

Sonera's at it again

[UPDATE] Now the people in the Nordic have followed the lead of fuckyourogers.com:

Sonera, the poor man’s AT&T, the old Finnish national telcom that got “famous” in the dawn of the century by buying thin German air for $7.5 Billions (and later writing it off as worthless), is on fire again. The company that’s nowadays merged with its Swedish counterpart Telia, announced a while ago that they will be the ones bringing the 3G iPhone to the Northern Europe. I guess some warning bells should have been in place considering the company is pretty much the only one that still doesn’t offer a reasonable unlimited data plan for its GSM customers. However, initially the excitement over iPhone finally (officially) reaching this corner of the world took over and I even considered becoming a Sonera client.

Today, the ugly truth was revealed when the iPhone 3G plans were announced. Not a single plan has unlimited data. Not even the €90/month Large plan (which has 1GB/month of data). The small and medium plans come with measly 100 and 250 MB a month. Considering that watching a few YouTube movies consumes pretty much the whole monthly quota, the plans seem nothing but laughable1.

[UPDATE] Here’s the whole pricing table:

Plan Small Medium Large
Price 31,69 €/month + 159 €/8 GB or 245 €/16 GB iPhone 51,49 €/month + 79 €/8 GB or 165 €/16 GB iPhone 89,99 €/month + 1 €/8 GB or 85 €/16 GB iPhone
Includes
(min/month) 100 250 1000
SMS messages/month 100 250 1000
Data (MB/month) 100 250 1000
Home Run hotspot usage yes yes yes
Additional calls
Starting a call 0,049 € 0,049 € 0,049 €
Cost/min 0,079 € 0,079 € 0,079 €
Additional text msg 0,079 € 0,079 € 0,079 €
Data/MB 1,49 € 1,49 € 1,49 €

Now, the plans might have been ok 5 years ago2, but they totally overlook the platform what iPhone has become in the countries it’s been on sale so far. An iPhone is not just a phone anymore, it’s a whole new computing platform, which pretty much needs an unlimited data plan.

One huge selling point for the new phone will no doubt be Mobile Me. The chance to automatically and wirelessly sync your life between your computers and your phone sounds almost too good to be true. With €1.49/MB for the over quota data transfer, the syncing doesn’t exactly sound like a realistic option anymore.

Fortunately everything is not lost for us. You can buy the phone from Sonera even without the ridiculous plans. The 8GB and 16GB models cost €429 and €519 respectively if you don’t take any real plan with them. You do have to sign up for a custom plan for 24 months, though, but the cheapest comes at €1.99/month and thus only adds €48 to the total cost of ownership. That might just about cut it for me, but for the masses? Not so much. I hope I’ll be wrong, but to me it seems that Sonera is once again going to kill something that would’ve had potential to be something disruptive.

Oh well, I hear they’re going to sell cheap unlocked iPhones in Italy…

[UPDATE] Gruber links to The Unofficial Apple Weblog’s entry about Rogers unveiling their plans as well, stating that ‘they suck’. However, compared to the offering from Sonera, Rogers’ plans seem to be downright cheap (even the cheapest plan comes with 400MB of data and 150 mins of weekday calls compared to 100MB and 100 mins all the time). Thanks also to Vesa for the comment about Rogers’ plans.

1 The prices seem even more laughable considering that pretty much every other operator offers unlimited data plans starting from €10/month.

2 Even though we did, in fact, have unlimited GPRS plans in here back then, something which was unheard of in the Middle Europe where I used to live those days.

Tags: apple, iphone, life

Specifying indeces in DataMapper

I’ve been working with Merb and DataMapper in the context of a new project for a week now, and the experience has been both pleasant and interesting. On one hand the stack is solid and super-fast (like, desktop app fast), on the other there are a lot of things that catch you if you don’t manage to remove the Rails hat off your head. The youth of the frameworks still shows (especially in DataMapper which has recently seen a major refactoring to make it more modular the same way Merb was reworked a bit earlier) but at the same time I get the chance to help with some really cool up-and-coming open source software. If you don’t consider that a plus, maybe you should still wait a couple months before you consider these critters for a production app.

One clear symptom of the young age of both Merb and DataMapper is the lack of documentation. They both have documentation sections on their respective websites and there are other efforts such as Merbunity going on, but you still have to have the guts to dive into the source code if you want to find out how some of the less common use cases work.

Here’s a short piece on how to declare indeces for your DataMapper models. I plan to continue publishing this kind of tutorials for other functionality as well, and to contribute them back to the “official” docs when appropriate.

The big difference

The big conceptual different between ActiveRecord and DataMapper is that in ActiveRecord, the place where the properties of database tables are defined are the migration files. The actual tables are then built according to the migrations and the actual model classes build their property to methods from the database schema.

In DataMapper, the properties are defined in the actual model file. DM has so called auto migrations that compare the model file and the database schema, and modify the schema if the two don’t match.

Here’s an example DataMapper model:

class User
  include DataMapper::Resource

  property :id,         Integer, :serial => true
  property :first_name, String
  property :last_name,  String
  property :bio,        Text
  property :single,     Boolean
end

Seems clean, doesn’t it. Looking at a model it is clear what properties it has and what methods it supports. But what about indeces? In AR migrations, you would use the create_index method. In DataMapper, index is an option given to the property method:

property :last_name,    String, :index => true

Or, if you want the index to be unique:

property :last_name,    String, :unique_index => true

OK, but what if you need multi-column composite indeces? Easy. Instead of true, give the index a name using a symbol:

property :last_name,     String, :index => :name
property :first_name,    String, :index => :name

This will create an index called index_products_name for the table, spanning columns last_name and first_name. The columns are added to the index in order of appearance, so in this case the indexing order would be last name, first name. If you want to change that order, just change the order of you property calls in the model call definition.

There you have it! No rocket surgery, but something I had to dive into the source code to find out.

Tags: datamapper, merb, migrations

Start from the Heart

My friend Lars Pind is slowly migrating himself from a software developer to a coach. His new startup is called Start from the Heart, where Lars tries to help people start companies that represent their true soul. The guiding principle behind Start from the Heart is that there should be a deeper meaning in the business you pursue than just the money. As exactly that has been a driving force behind us at dotherightthing.com, it’s no wonder the premise of SftH really resonated with me.

Lars is putting up a series of exercises for the participants of the program and giving out them for free. I worked through the first assignment and must say that it’s a great one, getting a smile on your face. If you’re thinking about starting your own company (or have ever contemplated it), I would highly recommend giving Start from the Heart a try. I’m certainly enjoying it from the bottom of my heart (no pun intended).

Tags: entrepreneurship, life, spirit

&lified

UPDATE Now ampersand even has its own blog.

Ampersand has received a lot of press lately and I decided to put my oar in as well.

My recent history with ampersand is kind of embarrassing, to say the least. I was giving a Ruby class in UK a few years back and during a class, I asked a participant whether there is some other term for the at sign in English. “Sure”, she said, “it’s ampersand.” To this day I’m not sure whether she thought I said et sign, or genuinely mixed up asperand and ampersand. But for quite some time after that, I happily treated @ as ampersand.

But neither linguistics or typography is the topic of today’s article. Let’s rather talk about ampersand (the real one) in Ruby.

In Ruby, an ampersand denotes a block parameter. But let’s not get ahead of ourselves. A little background might be in place.

One of the coolest features in Ruby are code blocks, or closures. They are basically anonymous functions, but as pretty much everything in Ruby, they are also objects. They are anonymous functions, that have little use just by themselves. However, you can turn them into Proc objects either with the Proc.new constructor or using the lambda kernel method. The common best practice to mark code blocks is to use the curly braces with one-liners and do..end with blocks that span multiple lines:

yell = lambda { puts "AAARGH!!!" }
whisper = Proc.new do
 puts "whee" 
end
yell.call
whisper.call

?

AAARGH!!!
whee

Maybe the most useful application of Proc objects in Ruby are block parameters. Anyone with some knowledge of Ruby is familiar with the following:

>> arr = %w(apple orange kiwi)
=> ["apple", "orange", "kiwi"]
>> arr.each {|i| puts i[0,2]}
ap
or
ki
=> ["apple", "orange", "kiwi"]

As you can see, in this case you need to use neither Proc.new nor lambda with the block; it’s converted to a Proc object implicitly. But as the method receives just a Proc object as its parameter, you could also say something like this, right:

>> put_two = lambda {|i| puts i[0,2]}
=> #
>> arr.each(put_two)

Err, not quite. It turns out Ruby methods can take two kinds of parameters—a number of normal parameters and a block parameter. In the code above the interpreter will think that the put_two Proc object is passed as a normal parameter to the each call, and since each doesn’t take any normal parameters, you will get an error:

>> arr.each(put_two)
ArgumentError: wrong number of arguments (1 for 0)
    from (irb):42:in `each'
    from (irb):42

And this is what brings us back to the ampersand:

>> arr.each(&put_two)
ap
or
ki
=> ["apple", "orange", "kiwi"]

So the ampersand is used to tell the interpreter that the following reference is the block parameter of the method.

One fairly common idiom in the Rails world is this kind of construct:

>> arr.map(&:length)

It is effectively the same as

>> arr.map {|i| i.length }
=> [5, 6, 4]

However, if you start a plain irb session, you will notice something isn’t quite right:

>> arr.map(&:length)
TypeError: wrong argument type Symbol (expected Proc)
    from (irb):2

That’s right. The cool shorthand method that worked so nicely in your Rails app doesn’t work in plain Ruby. That’s because there is some Rails magic behind the &:method call. This magic is e.g. the reason why Ezra has prohibited using the shortcut in Merb framework code.

But let’s have a closer look at what’s actually happening behind the scenes in the shortcut. The thing that’s different from our earlier calls is that there is a colon between the ampersand and the word “length”. This means that we’re not using a variable or method called length, but the symbol :length. If you’re not familiar with Ruby symbols (or even if you are), reading Josh’s recent article on symbols is a worthwhile read.

Now that we know that we’re trying to pass a symbol as the block parameter to a method (and that it’s not really working, as the error above indicates), we need a way to convert it to a Proc object like expected by the method. Ruby has a slew of type conversion methods that are called implicitly whenever it’s clear that a certain type of object is needed. Inside a string for example, to_s is called automatically for every object that is not a string itself:

>> "Nice array: " + arr
TypeError: can't convert Array into String
    from (irb):6:in `+'
    from (irb):6
>> "Nice array: #{arr}" 
=> "Nice array: appleorangekiwi" 
>> "Nice array: " + arr.to_s
=> "Nice array: appleorangekiwi"

In the same vein, since a block parameter of a method needs to be a Proc object, to_proc is called automatically for all other objects in an effort to get a hold of a proc. So could it work if we just added a to_proc method to the Symbol class? Let’s find out!

class Symbol
  def to_proc
    lambda {|i| i.send(self)}
  end
end

Here we make to_proc a lambda function that will use the send method to call the method with the same name as the Symbol object in question (self) for the element that’s passed to it. (That got too confusing so let’s just use examples). So

arr.send(:length)

is the same as

arr.length

And thus

:length.to_proc

would become

lambda {|i| i.send(:length)}

Now, let’s see how our new method performs:

>> arr.map(&:reverse)
=> ["elppa", "egnaro", "iwik"]

Perfect!

While Symbol#to_proc is a clever and perhaps an elegant hack, it’s still kind of a hack. So should you use it in your code? I tend to side with Ezra on this. If you’re writing framework code, you should probably err on the side of readability and common usage, and thus avoid “magical shortcuts” like these. But in application code, why not. I certainly do.

Tags: ampersand, proc, ruby

Making capistrano not suffocate on cleanup

When trying to deploy an app on the production server, the deploy:cleanup task always died for me like this:

  * executing `deploy:cleanup'
  * executing "ls -x /opt/sites/mysite/releases" 
    servers: ["myserver"]
    [myserver] executing command
    command finished
 ** keeping 3 of 4 deployed releases
  * executing "rm -rf /opt/sites/mysite/releases/20080220092659" 
    servers: ["myserver"]
    [myserver] executing command
 ** [out :: myserver] sudo: no passwd entry for app!
 ** [out :: myserver] 
    command finished
command "rm -rf /opt/sites/mysite/releases/20080220092659" failed on myserver

Turns out capistrano is for some reason trying to use a user called app in the cleanup task even though the :user parameter is set to something else in config/deploy.rb. The solution was to set the :runner parameter as well:

set :runner, 'someotheruser'

Don’t ask me why that worked. It seems a bit counterintuitive that the cleanup task uses the runner param rather than user. Found the hint towards the solution here.

Hate to say...

December 2007

For gawd’s sake, what did they smoke in your company’s Christmas party?

(A text message I sent to my buddy Thomas who works in Sampo Pankki in reference to the news that the bank (recently bought by Danske Bank) would deploy a new “security” system (that uses a Java applet) in their online banking solution).

April 2008

The latest reactions inclule [sic] 52-year old male customer returing to the bank with an axe after hearing that his account is empty, money exchange company Forex stopping accepting payment cards from Sampo Bank and Sampo Bank customers not being able to buy train tickets online.

(Finnish Sampo Bank’s ICT problems cause extreme reactions in their clientele)

Tags: blunder, sampo

On Multitasking

Now, this has been talked about in detail in the past, but here are two recent interesting discussions about multitasking. On the Ruby on Rails Podcast, Geoff interviews Dr. John Medina in a “two-part series about his new book, Brain Rules: 12 Principles for Surviving and Thriving at Work, Home, and School.

One of the most interesting topic in the discussion is about human multitasking, and to be precise, the lack of it. One of the hot topics in this discussion is the debate about talking in phone while driving. Medina brings up recent studies that show talking while driving is as dangerous as drunk-driving, no matter whether you use a hands-free set or not. As a reason, Medina proposes that when discussing with someone remote interactively, you build a mental image of the counterpart (just like you do when reading a novel) which takes your concentration away from driving. That sounds certainly believable. I have many times noticed that I’ve been driving for minutes while talking in the phone (with the iPhone headset, of course) and then suddenly kind of wake up back to the traffic.

Meanwhile, Rands explains how he doesn’t multitask even though it might appear as if he would to the outsider.

Tags: life, brain, multitask

A Track of Two

If you’re into photography, here’s a couple of quick links that might be of interest:

  1. Scott Bourne and Alex Lindsay, of MacBreak Weekly and many other fames, have started a new podcast under the Pixelcorps.tv umbrella: This Week in Photography. The guys are really great podcasters and the content is kind of semi-advanced so that it’s not boring even if you’re fairly competent (even pro, I would say) but also not overwhelmingly technical. Great stuff during long exercises like a track of two1. The third episode of TWIP discussed the state of Aperture and namely the lack of announcement of version 2 during the PMA. That gives us a nice segue to the next topic:
  2. Aperture 2 is here! Downloading it right now and have high hopes for the performance. Especially creating previews and exporting photos leaves a lot to be desired in 1.5, and if the first comments around the ‘net are to be trusted, the newcomer should be vastly better in this regard.

1 A track of two (or “kakkosen latu” in Finnish) is a term that came from a two-hour cross-country skiing (preferably classic) exercise and is now a synonym for any longer training pass (run, ski, hike, whatever) of around or over two hours.

Tags: apple, news, photo

The best of times, the worst of times

I’m kind of sad that Blu-ray has taken the lead in the next generation digital video disc race, and that has little to do with the fact that I don’t really like Sony. The reason the lurking death of HD DVD makes me really sad is that while it has smaller capacity than BD, it has one thing really going for it: it’s void of one of the pests of modern times: regional codes.

Jeremy Keith recently wrote about DVD’s and Wii games that he bought during his Christmas trip to US that he cannot use because they are limited to be played only by a player with the US region code. Now, there are region code-free players available, but that only makes the whole scheme more pointless.

Now, with HD DVD being free of the region codes, we could have gotten rid of them once and for all. However, with Blu-ray seemingly winning the war, we seem to be stuck with the same hassle into the unforeseeable future. And people wonder why Pirate Bay is the #1 movie distribution channel in Europe these days…

Tags: hd, life, tech

Note to self: when autotest fails...

I just run into the following error when running autotest within a Rails app:


/Users/jarkko/Sites/koulutusweb/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:402:in `to_constant_name': Anonymous modules have no name to be referenced by (ArgumentError)
    from /Users/jarkko/Sites/koulutusweb/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:214:in `qualified_name_for'
    from /Users/jarkko/Sites/koulutusweb/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:477:in `const_missing'
    from /Users/jarkko/Sites/koulutusweb/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb:7:in `reset'
    from /Users/jarkko/Sites/koulutusweb/vendor/plugins/rspec/lib/spec/example/example_group_factory.rb:59
    from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `gem_original_require'
    from /Library/Ruby/Site/1.8/rubygems/custom_require.rb:27:in `require'
    from /Users/jarkko/Sites/koulutusweb/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:496:in `require'
    from /Users/jarkko/Sites/koulutusweb/vendor/rails/activerecord/lib/../../activesupport/lib/active_support/dependencies.rb:342:in `new_constants_in'
     ... 59 levels...
    from /Library/Ruby/Gems/1.8/gems/rspec-1.0.8/lib/spec/runner/command_line.rb:17:in `run'
    from /Library/Ruby/Gems/1.8/gems/rspec-1.0.8/bin/spec:3
    from /usr/bin/spec:19:in `load'
    from /usr/bin/spec:19

It turned out I had typed “sudo gem update zentest” to get the latest version of the gem. However, the correct way would have been to use the camel-cased version ZenTest. The funny thing is, that if you run the command in lower case (like I’m use to do with RubyGems), you will get ZenTest, it’s just version 3.5.0 (as opposed to 3.8 that I supposedly got).

So here’s hoping that the next time I do the same mistake, this page will pop up from the big G.

Tags: autotest_zentest_rspec

Sony BMG "goes DRM-free" (or: Sony BMG, the dumbest of the dumb)

(cross-posted to dotherightthing.com)

Last weeks, the air has been thick about even Sony BMG, the last of the big four music labels finally abandoning it’s rootkit-stained history of draconian DRM schemes and publishing “at least part of its collection available DRM-free. However, the actual way of how it’s going to happen has been unclear until very recently. And boy, what scheme that came to be:

The No. 2 record company after Universal Music will sell plastic cards, called Platinum MusicPass, for individual albums for a suggested price of $12.99. Buyers enter a code from the card at new Sony BMG (SNE) site MusicPass.com to download that card’s album.

That’s right. Plastic frikkin’ cards. Marco has a good view of how this happens:

To get Sony BMG’s DRM-free music files, someone burns some coal to manufacture these petroleum-based plastic cards, then delivers them to stores on a series of diesel trucks. I drive to Best Buy in my 3056-pound gas-burning car and find my particular little plastic card, assuming that store carries the album I want in plastic-card format and it’s in stock. (If not, I need to drive to more stores, or just give up and try again next weekend.) But they probably have these cards taking up space somewhere in their massive store that requires tons of energy to keep well-lit and ventilated (since it has no windows).

And as far as the “part of the collection” part goes, the DRM-free collection will be a whopping 37 albums. Three-seven. Combining the convenience of going to a store to be able to buy tunes online, and the width of the supply, I’m sure people will be buying the albums like crazy.

John Gruber links to an article by John Scalzi, aptly titled Why It Won’t Work.

Kid #2: So to recap, what you’ve got here is a system that makes people leave their house in order to download music at their house, and makes them go to a store to get music that they could get at the store, somewhere else.

Sony BMG dude: Er.

Kid #1: Why don’t you just sell non-DRM’d MP3s off Amazon, like every other major music corporation?

Sony BMG dude: Well.

Kid #2: You don’t actually want to sell unprotected MP3s, do you? You want to be able to say you’re doing it, but really, you want to make it so ridiculously inconvenient that people keep just keep buying CDs and DRM’d tracks off iTunes. Just admit it, bro.

Sony BMG dude (pointing): Look! It’s Celine Dion! And Barry Manilow! (runs away as kids avert their eyes in terror)

Won’t they ever learn?

[UPDATE:] They will indeed start selling music through Amazon MP3, according to MacWorld. The question remains, why on earth did they publicize the born dead plastic card scheme if the whole Amazon deal was about to be announced. The other question is, doesn’t it sound like a cartel that three of the big four labels refuse to sell Apple DRM-free songs but sell them somewhere else? Let’s hope there are some announcements coming next week in San Francisco.

Tags: life_sony_bmg

Get your pan ready!

It’s hard to write a full book for a seasoned Rails hacker nowadays. Most of every tutorial-like tome will be fluff and even if there are some useful tidbits to gather, they’re often hard to find among the sea of surely useful but hardly nouvelle information. That’s why I really enjoy reading concise, to-the-point articles about specific solutions, and there is a genre of books that are chock-full of those nifty solutions: the cookbook style books. Chad’s Rails Recipes, Lucas’s and Leonard’s Ruby Cookbook and Rob’s Rails Cookbook have often made my day when even the mighty G has failed.

And now, fresh from the pragmatic oven, prepared with tenderness and love by Mike Clark and a slew of contributors, comes Advanced Rails Recipes. From a quick look through the beta PDF (available for purchase now through the beta book program), this will surely be one of the most useful Rails books for an advanced hacker ever written. Mike has managed to gather a respectful pile of recipes from experienced Rails people like Ezra, PJ and Chris, Adam, Giles and many, many more. Getting access to all these people’s heads within one book is something really unique and privileged.

Disclaimer: Advanced Rails Recipes contains a recipe written by me, “Validating Required Form Fields Inline”. However, I don’t get any royalties from the book sales so this recommendation is an honest review of the book. I really think it’s that good.

Tags: book_reviews, rails, rails_recipes

Harvest Time

Congrats to Sami Korjus and my cousin Jussi Syrjä for securing a spot for their short film Harvest Time at the Sundance Festival. I’ve seen the film now twice, in its premiere in the Tampere Film Festival last year (where it won the special prize) and last week on the national tv, and the mojo hasn’t worn off. It was one of the few movies in the festival shot on real 35mm film and the same quality can be seen throughout the whole film. If you’re into black comedies and heading to Sundance, I heartily recommend giving it a shot.

Tags: life_film

Do NOT hire iTechArt

It’s annoying enough that quite a few spam messages creep through Google Groups filters to the many mailing lists I’m subscribed to. Fortunately, SpamSieve has learned to bash them quite effectively. Today, however, spam on Rails-Core and Rails-Spinoffs hit the new low (right in there with people advertising pirate copies of the first AWDWR book on the Rails mailing lists a while back).

A company apparently specialized (among many other technologies, oh the irony) in Ruby on Rails development and outsourcing, iTechArt, considered it appropriate to advertise their services by spamming pretty much every Ruby and Rails-related mailing list on Google Groups. I not only think it’s pretty darn stupid to crap in your own cubicle (so to speak), I also think it’s worth giving them a lesson. So anyone considering outsourcing or buying Ruby or Rails development, please:

  1. Do not hire iTechArt.
  2. If you receive a proposal from them, let them know you won’t hire spammers.

In any case, if you’re a blogger, please spread the word. iTechArt is not worth anyone’s money.

Tags: activism, rails, spammer_rant

Mikontalolights

What would a bunch of geeks do while their dorm highrise is under renovation? Build the world’s biggest LED screen, of course.

Photo by StaneStane

One of the most infamous student dorm houses in my hometown and whole Finland, Mikontalo, is finally put under hammer and renovated to meet the standards of the third millennium. While the construction work is underway, a bunch of TUT geeks decided to get something more out of the works:

The object of MIKONTALOLIGHTS is to create the world’s physically largest colored graphics platform by using the windows of Mikontalo’s D-staircase as light pixels. The platform is used to play Tetris and other games and present demos created by the students of Tampere University of Technology.

Here’s a video of the grand opening, including rounds of Space Invaders and Tetris (controlled with a mobile phone, of course). Times Square, beware!

Tags: geeky, life, geeky_life

Leopard Terminal doesn't like ProFont

My clear favorite among monospaced fonts has so far been ProFont, 9pt with no antialiasing. I don’t think antialiasing works well for small type and I have yet to see as clear and crisp a font as ProFont. However… this is what a terminal window looks like after I updated to Leopard:

Leopard Terminal fucks royally up strings with slashes with ProFont

Not cool. Here’s exactly the same window after switching the font to Bitstream Vera Sans Mono:

In Vera Sans Mono everything's fine

Also not cool because of the ugliness but at least all the characters are shown. Anyone got an idea what’s happening with ProFont? Everything worked just pristine in Terminal in Tiger, and still does if I run iTerm.

[UPDATE, Dec 3 2007]

I played around with the different ProFont distributions a bit, and the only one that doesn’t break as above is the bitmap ATM version of the font. However, as you can see it’s just plain ugly with small text size (notice the pixelated k, : and ~).

Tags: font_apple_osx_profont

Letting the users choose

My friend Martin just posted a case study on Working With Rails about how Oakley has been migrating their web presence onto Rails. I’m a big fan of Oakley products. They’re a company that puts an enormous effort to make seemingly simple products better and better. In orienteering, where you really need some shield for your eyes (unlike in, say, pole vault), glasses with replaceable lenses with different colors for different weather conditions are a must. I’ve been using the M Frames for a couple of seasons, and refill my lens stock pretty much every time I visit US.

Martin’s interview with Ken Loh – the guy running the web group at Oakley – reveals an interesting point. The guys who actually build their apps got to choose the platform themselves. This is not too surprising for an innovative company such as Oakley, but it does show a clear contrast to the big E word, something Khoi Vinh and Jason Fried have lately talked about:

The people who buy enterprise software aren’t the people who use enterprise software. That’s where the disconnect begins. And it pulls and pulls and pulls until the user experience is split from the buying experience so severely that the software vendors are building for the buyers, not the users. The experience takes a back seat to the feature list, future promises, and buzz words.

(Jason Fried: Why Enterprise Software Sucks)

Tags: entrepreneurship, rails, sightings

Gartner Wisdom

In a Computerworld article telling about Steve Jobs and Apple fighting iPhone unlocking (emphasis mine):

Carolina Milanesi, a Gartner Inc. analyst who was at the London presentation, said she wondered if it matters much in the long run whether Apple stays a step ahead of hackers, as Jobs said it must do. “At the moment, as a consumer, you need to be very careful about unlocking the iPhone, and know how you want to use it,” she said. “If you unlock it, you are not going to have a flat rate, and you will not have access to the 7,500 hot spots.”

Huh? A 384Kbps (much more than iPhone can handle) flat rate plan runs around €10/month in Finland. And you have access to each and every wifi hotspot in the world with iPhone.

“If you unlock and then use the Internet and e-mail, you may be surprised by your first bill,” she added, referring to the pay-as-you-go data rates charged by most carriers in the country and elsewhere in Europe.

What the fsck does that have to do with iPhone? You pay what and how you pay regardless of the phone. You probably know what your existing contract charges for data if you’re contemplating buying and unlocking an iPhone.

Tags: apple_iphone

iPhone vs. Nokia E90 Communicator

(photos by Blackhorn and DanieVDM)

The arrival to the second installment of RailsConf Europe – this time in Berlin – meant even more for me than hanging around with friends from all over the world. It also meant the first time I was able to hold an iPhone in my own hands.

See, about the same time people in US got their hands on the first iPhones, I also got a new phone, a Nokia E90 Communicator. The situation in Finland with the Communicators was almost the same as the one in US with iPhones, it was almost impossible to get one. I was lucky enough to get one in about a week, as a part of a 24-month contract. Here’s the first-quarter report about my experiences.

First things first. E90 is a pretty impressive device. With full keyboard, Wifi, 3.5G, GPS and dual screens (of which the larger one is really good) there’s hardly anything more you could hope. But that’s just on paper. Much more important to me is how useful the phone is in day-to-day use.

The browser (which uses webkit) is fairly good, certainly one of the best in the mobile world. However, the lack of a “real” mouse makes some things really hard, one of the most annoying being the fact that you can’t scroll an iframe or a div with overflow: scroll. There is no notion of dragging.

One of the most disappointing aspects is the general coherence of Symbian, which unfortunately came as no surprise. Used to OS X, I just don’t find Symbian stable or slick enough. One example of that is the selection of a Wifi network. In theory, you click the web button, select a Wifi or 3G network and continue to the browser. In practice, about half the time you just end up back to the desktop after selecting the network.

A thing that I was really disappointed by was the GPS. I’m not quite sure if it’s just my device or if it’s a “feature”, but it just takes too long for the device to find itself on the map and there’s no real feedback on what’s happening. All the UI says is that there’s no GPS available, even though in reality it’s negotiating with the satellites all the time. If you’re moving at the same time, the phone won’t ever be able to locate itself. Therefore, the GPS function has so far been totally useless for me.

Now that I got to use an iPhone in real life, I can say the two UI’s are like from different planets. It’s nice to hear that Nokia and others are coming out with touch screen phones, but I wonder if they ever get it when it comes to usability. Symbian in E90 doesn’t really reassure me in that regard.

Would I swap my omnipotent Nokia for a device using years-old phone technology? In a heartbeat. While the E90 is really nice and all, it’s an epitome of feature list competition where the more buzzwords your feature list contains, the better your phone is. And while getting 3.5G speeds is really cool, the coverage is still so bad around Finland that just having Edge for a while (until the 3G iPhone comes out) wouldn’t be too bad.

It kind of hurts me to say this as a Finn, but at the moment it seems that a newcomer in the mobile phone market has beaten the current leader pretty badly. For the customer and the market in general, that’s all but certainly a good thing.

Tags: phone_mobile_iphone_nokia_communicator

Making Globalize play nice with specs

We’re using Globalize for our latest Rails project and I just ran against a problem when running specs with rake.

We specify the base language and the locales our app supports in environment.rb:

include Globalize
Locale.set_base_language('en-US')
SupportedLocales.define(['fi-FI', 'sv-SE', 'en-US'], 'en-US')

However, SupportedLocales.define expects that the language and country data exists in the database, otherwise it will die miserably. Of course, when you run specs with rake, it will wipe the database as its first action so you’re pretty much out of luck:

.../vendor/plugins/globalize/lib/globalize/localization/supported_locales.rb:282:in `setup': Globalize base language undefined! (RuntimeError)

I fixed this by copying the db:test:clone rake task from [RAILS]/railties/lib/tasks/databases.rake to its own file in lib/tasks and modifying it so that it will load some language and country fixtures automatically:

require(File.join(RAILS_ROOT, 'vendor', 'rails', 'activerecord', 'lib', 'active_record', 'fixtures'))

namespace :db do
  namespace :test do
    desc "Recreate the test database from the current environment's database schema" 
    task :clone => %w(db:schema:dump db:test:purge) do
      ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
      ActiveRecord::Schema.verbose = false
      Rake::Task["db:schema:load"].invoke
      Fixtures.create_fixtures("#{RAILS_ROOT}/spec/fixtures", [:globalize_countries, :globalize_languages])
    end
  end
end

The only thing differing from the original task is the last line creating the fixtures. For some reasons I also need to explicitly require the fixtures file on the top of the file. Aside from this, I needed to change Rakefile in the root of our Rails app to require config/environment.rb instead of config/boot.rb for everything to work.

Of course your fixture files need to include all the languages and countries you’re specifying in your SupportedLocales.define call.

After these modifications, rake runs through fine again.

Tags: rails, globalize_spec_rake
next page »