Circular path with webring links Hotline Webring < Previous Next >

Nuthole

All they wanted was a villain, and all they had was me

The Great iPhone Swindle

Tech Sweden is abuzz with news of Telia’s iPhone pricing plans having been released today. Unlike the AT&T contracts in the U.S., Telia’s contracts for Sweden don’t directly include unlimited data transfer. Also unlike the AT&T contracts, at first blush (and subsequent for that matter) the Telia contracts seem really pretty expensive, especially the iMaxi plan, which starts at about $150/month!

So, looking to maximize my bang for the buck, I worked up a little spreadsheet showing the monthly and total costs for the various phone models and plans.



  • The figures in bold are prices straight from Telia’s site.

  • The figures in light blue are monthly recurring costs for the stated data amounts, and a second row for unlimited data amounts (arrived at by adding in the cost of Telia’s 9kr/day “maxtaxa”; Note that this represents the maximum amount you’d pay in a month, assuming you blew past the free amount in the first day and kept using some amount of data transfer every single day of the month)

  • The pale green figures show the absolute smallest total cost for each of the two models, and the pale purple figures show the smallest total cost for each of the two assuming unlimited data. Note that these all wind up being for 18-month contracts, so for comparison’s sake I’ve included extended calculations for the 18-month contracts, adding a row for what you’d pay if you continued with a normal Telia “fastpris” account at 199/month, and another row that adds in that plus the “maxtaxa” to arrive at the costs for unlimited data.

  • The dark green figures show the smallest total 24-month cost for each model, and the dark purple figures show the smallest total 24-month cost for each model assuming unlimited data.

  • I haven’t calculated anything around extra minutes or extra SMS, since I (and probably many other iPhone users) assume that data usage will be a much more important factor, and in my case I’m sure that I’ll seldom use more than 100 minutes or 100 SMS per month.

Some interesting points pop out when looking at this. For one thing, the more expensive plans really seem disastrously expensive, especially iMaxi. If you’re not planning on calling for 16 hours a month or sending 1000 SMS/month (who does that?) then those really seem like a waste. Even if you were using that much, it seems like the standard tariffs, combined with the iMini plan, would still be much cheaper. Again, for my anticipated usage I really don’t care, but maybe someone who really is a big voice or SMS user will calculate these things.

Another thing that strikes me is that there is an interesting pattern to these numbers. If you look at the dark purple and dark green figures, the cheapest totals (for minimum and unlimited data) for each model, they both are for a 24-month contract. Compared to building an equivalent usage period by combining an 18-month contract and a 6-month “fastpris”, they are just barely cheaper; precisely 200kr in each case. And that’s all assuming that Telia’s “fastpris” and “maxtaxa” will remain at their current levels for the next 18 months. If they get even just a tiny bit cheaper, or if another operator has a better deal for iPhone users 18 months from now, then the 18-month contract will turn out to be a better deal in the long run.

So, it seems that financially, whichever of the two models you’re looking to buy, the iMini 18-month plan seems like the way to go. Again, things may be different if you plan on doing lots of voice calls or SMS, but I’ll leave that for someone else to figure out.

Twitter? Twucket.

Just in time for WWDC ’08, allow me to introduce you to Twucket.

Twucket is a new Twitter client for Mac OS X that I am releasing as freeware. I created Twucket because I wasn’t happy with any of the available ways to view my Twitter page. The actual twitter website is a hugely-rendered page, and requires you to go to the browser now and then to see if anything has come in; The standalone clients I tried were either wasteful of screen real estate, or didn’t fit in with the overall Mac GUI, or contained ads.

Twucket suffers from none of those problems. Its interface is minimalist and small, it behaves like a normal Mac application, and it doesn’t insert ads into the display. What it does offer is a compact, simple Twitter interface with a few features that Twitter users will probably appreciate. It uses a relatively small amount of screen real estate per message, so you can leave a small window open in a corner of your screen that is still large enough to show the latest 4 or 5 messages you’ve received.

I do have additional plans for future versions of Twucket, but today is the day for 1.0.0. If you’re a Twitter user, please give it a try and let me know what you think!

Demand JoCo

I’ve told you before about Jonathan Coulton and why you must love him and give him your money. Lately Jonathan has been extending the range of his touring outside the U.S. with a recent show in England, and he’s thinking about coming to Europe again and wonders where his fans are. He’s even set himself up on Eventful to figure it out.

Obviously it’s time to rouse the Nuthole Army out of its slumber. Arise, Nutholios, and commence with the clicking!

Click here to demand Jonathan Coulton in Stockholm!

Of course you could probably click through there and demand him for some other city instead. But I won’t help you there.

Your New Favorite Podcasts

Podcasts. Either you’re listening to them, or you’re not. For me, living geographically removed from the American mediasphere, podcasts are a great way to keep up with American and other English-language professionally-produced audio content, not to mention all the stuff that people are putting out there on their own.


It’s a bit like having your own radio station, just full of stuff you actually want to hear, that you can listen to whenever you want. I’ve usually got my iPod half-full with a variety of shows; I don’t listen to each episode of each show, but I’ve got a pretty wide span so I can pick whatever I want at whatever moment I feel like listening.


I don’t often see people writing about what podcasts they’re listening to, and randomly browsing podcast sites looking for good shows takes time, so it’s not always easy to find the good stuff that’s out there. Just for the sake for sharing, here are a few of my favorites.

Le Show


Harry Shearer, the voice of many of the Simpsons characters, and one of the co-stars of the classic film Spinal Tap (in the role of Derek Smalls, the one with the incredible sideburns/mustasche combo) gives us this weekly glimpse into the news, focusing on politics and entertainment, rounded off with a bit of sketch comedy. Satirical, insightful, almost always funny.
This American Life


Each week, This American Life picks a topic, and presents a handful of segments about it using interviews, short-story readings, or other forms of audio journalism. No matter what the subject matter, it always feels like an hour well-spent. Chicago Public Radio produces this (mostly-)weekly show.

Undercover Songs


This is one of the very first podcasts I ever subscribed to. Nuno Nunes presents a handful of covers, songs performed by someone other than the original artists. This is huge fun! Although the frequency of updates has declined steadily—first weekly, then bi-weekly, now basically bi-annually—the content is great, and you will always hear something new and unexpected.

Savage Love


Many people have seen Dan Savage’s Savage Love advice column in the alternative press; I read it for years in one of the Minneapolis/StPaul free papers before moving to Sweden. Fortunately Dan has embraced this new digital age, and now offers a phone number where people can call in and record their questions, and he offers them advice, sometimes calling them back to get more info. Though the vast majority of the callers have problems and concerns far from my own life, it’s pretty interesting to hear the concerns of bisexual grammar fetishists living in poly relationships with jesus freaks. If this sounds vaguely Jerry Springer-esque, don’t worry, it’s not.

<!—


XXXXXXXXXXXXXXXXXXXXXXXXXX



XXXXXXXXXXXXXXXXXXXXXXXXXX

XXXXXXXXXXXXXXXXXXXXXXXXXX

—>

Well, that’ll do for now. If anyone else feels like sharing, don’t forget to use the comments, now less-broken than they’ve been in months!

Wake Up, Patriots

I’ve been so busy (and having so much fun with) work lately, that I’ve been neglecting politics to some extent, especially here. In fact, I now see that my latest entry filed under politics was 19 months ago!


Well, time to catch up. Here’s an interview with Naomi Wolf, discussing topics from her latest book, The End of America. In this interview, she describes having discerned 10 steps that tyrants of the 20th century used to subvert democratic systems in their own countries, converting them to dictatorships. It shouldn’t surprise anyone to learn that the piratical crew at the helm of the U.S. government have already implemented a number of these items, with more on the way.

Near the end she mentions the American Freedom Campaign, a bi-partisan movement determined to take away the powers that Bush has grabbed for himself, and restore the checks and balances described by the constitution. This seems like a good thing to me.


Really, it’s hard for me to understand head-in-the-sand republicans who willfully ignore the power imbalance that the current administration has created, giving so much power to the executive branch. It works out well for republicans as long as there’s a republican president, but what if (gasp) a democrat actually wins the presidency the next time? Do they want a democratic president having the same kinds of powers that Bush now has, but applying them towards the progressive goals they so despise? Or is there a unspoken understanding amongst this crowd that things have been sufficiently “fixed” that there simply cannot be anything but republicans in the presidency, come hell or high water?


(via Giles)

Defective C++

At my previous job, I worked as a C++ programmer. The job, which started out primarily working with Objective-C and Objective-C++ to port a Windows application to Mac OS X, became progressively more a C++ job as time went on. I came to learn C++ fairly well, just enough to realize how much I dislike it. I haven’t properly been able to summarize just why I dislike C++ so much, but fortunately someone else has: The Defective C++ page, part of the larger “C++ FQA, lays bare a number of problems inherent to the design of the C++ language.


In less than two years of C++ usage, I encountered nearly every one of these problems. Some of them can be dealt with by deciding upon and following “best practices” within the team, which we did (to give credit where credit is due, the more experienced C++ developers I was working with pretty much laid out the best practices for the rest of us to follow), but some of them are just things that you pretty much have to live with, and end up turning the development process into a real straightjacket.


(via Another Day in the Code Mines, which had picked it up from a discussion at Joel On Software; check out the comments in that discussion if you want to see some extremely blindered C++ apologists in action…)

New Apple Logic Studio: Bigger but Smaller

Yesterday I installed Apple’s new Logic Studio. The system I was installing it on was already crowded, with the first four Jam Packs among other things, and I only had about 11 gigs free. To top it off, the Jam Packs weren’t properly installed; I had manually copied them from an older machine, but in a slightly non-standard location, without the .pkg files etc, so the Logic Studio installer couldn’t see them and wanted to do a fresh install of the new versions included with Logic Studio.

So I figured I’d wipe out the old Jam Packs manually, and let Logic reinstall them, and hope I’d have room for all the parts of Logic I wanted. I stumbled across this thread on Apple’s support site, which mentioned that the new versions of the Jam Packs in Logic Studio now have audio saved in compressed (but lossless) format, so they’re a bit smaller. Cool!

So, I wiped out my old Jam Packs, and installed most of Logic Studio, including all software and all 5 Jam Packs, but not the new extra audio content (which as far as I can tell seems to be intended mostly for soundtrack use). After installing all that, I ended up with 17 gigs of free space! Installing the new version, with more stuff, saved me 6 gigs! Woot!

Ruby Metaprogramming: Not Scary at All

There seems to be a sort of mystique around the concept of metaprogramming, but in Ruby it’s really not mystical at all. It’s all about leveraging a few existing methods in smart ways to let you eliminate boring code. This sort of thing is possible in my “native language” of Objective-C, but in Ruby it turns out to be even easier.

Today I’m going to talk about how to use the method_missing method to eliminate repetitive boilerplate code. method_missing is Ruby’s fallback strategy for unresolvable method names encountered at runtime. If you try to call a non-existent method on any object, the Ruby runtime will instead call method_missing on that object; The default behavior of this method is to raise an exception, but we can override it to do smart things based on the method name.

The Badness

The Rails application I’m working on has a role-based permissions scheme, with a ManagementRole model that sits between User and Program models, allowing us to define roles that a User can have relative to a given Program, which in turn constrain what they’re allowed to do with the application. These roles are expressed concretely as simple subclasses of ManagementRole, with names like RoleSearchMembers and RoleCreateMemberships. Up until recently, checking whether a User were allowed to perform certain tasks within a Program consisted of calling one of several nearly-identical class methods defined on ManagementRole, such as these:


  def self.allow_search_members?(user, program)
    return User.is_administrator?(user) ||
      self.program_role_exists?(user, program, "RoleSearchMembers")
  end
  
  def self.allow_create_memberships?(user, program)
    return User.is_administrator?(user) ||
      self.program_role_exists?(user, program, "RoleCreateMemberships")
  end

  # etc
  
  # the program_role_exists? method, not listed here, simply checks
  # for the existence of a matching ManagementRole object

As you can see, this is extremely repetitive, and adding new types of permissions means adding new, nearly-identical methods. As of now there are 18 methods like this, and that number will just go up in the future, leading to even more boilerplate code. Where will this madness end?

The Goodness

Providing a simple definition for method_missing in the same class lets me eliminate all those 18 methods, and will automatically deal with any new ManagementRole subclasses. It looks like this:


  # instead of a bunch of allow_xxx_xxx_xxx? methods that differ only slightly, 
  # we just catch all such calls here.
  def self.method_missing(method_id, *args)
    if match = /allow_([_a-zA-Z]\w*)\?/.match(method_id.to_s) and args.size==2
      return User.is_administrator?(args[0]) || 
        self.program_role_exists?(args[0], args[1], "Role#{match[1].camelize}")
    else
      super
    end
  end

The first thing this does is examine the method and the argument list, to determine if it looks like the kind of method we are trying to replace. If the method name looks anything like “allow_xxx_yyy_zzz?”, and if there are exactly 2 arguments, then we’ll do something interesting. Otherwise, we’ll just call super and let the parent class deal with it.

In the “interesting” case, we simply perform the same checks we did before to determine whether we return true or false, but now we’re using indexed values from the args array, and constructing the string naming the MangementRole subclass by using the result of the earlier regexp match. Voila!

The Even-Betterness

Of course, software development being what it is, any time you revisit an old design to try to improve it, the act of improving it can lead you to discover new, further improvements. While writing this, I realized something that would have avoided all this boilerplate code, and the metaprogramming it led to, in the first place: Instead of asking the ManagementRole class explicitly about each of these permissions, I’ll be better off writing a single method called allow? in the ManagementRole class, which will do a lookup based on the recipient’s class-name, e.g. RoleSearchMembers, RoleCreateMemberships. And then instead of calling ManagementRole.allow_search_members?(u,p) , I will call RoleSearchMembers.allow?(u,p). That will lead to even less code than the metaprogramming version, and less code is always better code. I haven’t written it yet, but it’ll probably look something like this:


  def self.allow?(user, program)
    return User.is_administrator?(user) ||
      self.find_by_user_and_program(user, program)
  end

So this problem, with its metaprogramming-to-the-rescue solution, turned out to be easily solvable with more traditional object-orientation, but that’s OK! Hopefully this post will be helpful anyway, for someone else whose problem doesn’t have the same easy solution that mine turned out to have…

RailsConf Europe Notes

I attended RailsConf Europe 2007 in Berlin last week. This has already been blogged to death I suppose, but here’s my take on a few items:


Bratwurst on Rails

The local Berlin ruby brigade organized this event; The night before the conference began, over 400 rails nerds gathered to eat freshly-made sausage and drink beer. This was a great way to start things off, I had lots of interesting conversations with a variety of people.

Networking, in general

All throughought the 3+ days I was there, I had the opportunity to meet and speak to so many people doing so many interesting things. Anywhere you turned, you could find people ready and willing to strike up a conversation about rails, programming in general, business strategies, or anything else you might think of. This was just a great, friendly crowd to hang out with. Extra props to Thoughtworks for picking up the tab for everyone to get a beer or two at the hotel bar one evening!

JRuby

There was lots of emphasis on JRuby. Thoughtworks and others are pushing JRuby on Rails as an easy way to get Rails into the enterprise, since you can deploy on any standard Java app server; Sun includes support for JRuby (as well as normal Ruby) in NetBeans; and Ola Bini’s new book on the topic has just hit the shelves, and there’s a lot of interest and potential in JRuby overall. But at the same time, I’m somewhat skeptical of Sun’s involvement. It seems great that they’re embracing JRuby, but hopefully they won’t somehow turn it into the sort of bloated mess that Java has become. And frankly, I’m not convinced that the Java app server stack isn’t a part of the IT bloatware beast that Thoughtworks’ own Cyndi Mitchell was railing against during her short talk.

RejectConf

This was a hoot. The idea is that any presentation that had been rejected by the conference organizers, plus anything else that anyone wanted to present, could be shown in a severely time-limited format (20 seconds per slide). Lots of interesting presentations, in a short time and fun, friendly atmosphere. Unfortunately the venue was a little too small, it was tough to get close enough to be able to see and hear much, but hey.

Australians

Throughout the conference (including RejectConf), the presentations that were the most consistently funny and entertaining, while remaining informative and valuable, were almost always led by Australians. Make of that what you will.

The occasional bad presentation

I’m not going to name names here. But one presentation, held on the final day, was really a waste. The guy started off by telling us that some time after his topic was approved for the conference, further development of the topic revealed to him that what he was going to present really wasn’t working out that well in practice. Now this could have been interesting in and of itself, to see in detail how a seemingly-sound concept breaks down when pushed a bit farther. Instead of that, however, the audience were treated to a lot of hand-waving and disclaimers of “I’m not going to show you the code because it won’t work for you anyway”. When there was still half an hour of time left, he was completely out of material and stopped; At that point, at least a third of the audience had already given up and left.

DHH Keynote

I don’t think I’m going out on a limb if I say that DHH’s public speaking is known for balancing a fine line between self-confidence and arrogance. I think this one was edging towards the latter. Sure, it’s great to hear that Rails 2.0 is approaching quickly, etc, but the part of the speech where he was proclaiming that the Rails revolution is already over, we’ve won, and now we can rest on our laurels and “enjoy Rails”? I think he’s putting the cart before the horse. Maybe DHH is at this point surrounded by so many yes-men that to him, Rails seems like it’s truly the only game in town, but in reality it can still go so much farther, be applied to so many areas, that it strikes me as premature to proclaim victory. In some places and markets, Rails is still a very difficult sell; In Stockholm where I live, for example, as far as I can tell most of the big consulting firms that have dipped a toe into Rails development have had a really hard time making inroads into the Swedish enterprise market.

Installing RMagick on Mac OS X and Ubuntu

I haven’t done anything with RMagick at all, partly because it relies on ImageMagick which many consider difficult to install on Mac OS X. Lately I’ve had a reason to use the excellent Gruff charting library, so it was time to buckle down and install this stuff.


As it turns out, it’s really not as complicated as some people say. Assuming you’ve already got macports and rubygems installed, it basically comes down to this:


sudo port install freetype
sudo port install ghostscript
sudo port install imagemagick
#sudo port install graphicsmagick
sudo gem install rmagick

Somewhere I got the idea to also install graphicsmagick after imagemagick, but for some reason port doesn’t seem to be able to find the package; It tries a few dozen sites and fails, so I commented it out above, but feel free to try it yourself. But no matter, it seems to not be necessary; I can now create images, render text, write them to disk, etc.


On Ubuntu (6.10), the incantation is different, but even simpler (via EXPRESSICA:


sudo apt-get install imagemagick
sudo apt-get install libmagick9-dev ruby1.8-dev
sudo gem install rmagick

The only caveat is that if you’re running without swap space and have less than a couple hundred megs of free RAM (e.g. on a VPS server) you may need to stop some of your processes before attempting that last line, or you’ll get this not-so-helpful set of errors after it runs for a while, consumes all available RAM, and subsequently crashes:


Building native extensions. This could take a while…
ERROR: While executing gem … (Gem::Installer::ExtensionBuildError)
ERROR: Failed to build gem native extension.

Hopefully this will save someone a few hours.