Futzing around with Ruby, other languages, and further occasional idiosyncrasies.

Friday, October 16, 2015

Dino Family

Tuesday, November 13, 2012

iTunes has jumped the shark

This is what you get if you search iTunes for "Adele Skyfall":

All but one of these is a "tribute", otherwise known as a cover by an unknown artist. Who knows if they are actually legal, though it's hard to see that they would be. Or they might be legal under some sort of fair use, remix usage.

Either way, the whole point people use iTunes over file sharing sites, torrents and Napster-descendants is to avoid the horrible hit or miss multiple-downloads-until-you-get-something, and to provide a safe environment to spend money where you don't get scammed. At least with the other ones you don't have to worry about losing any money.

Their design decision to hide the songs' rating and download numbers (and have "Popularity") doesn't help at all.

What are they thinking allowing this? Steve, where are you?

Tuesday, July 17, 2012

Thoughts on the new MacBook Pro Retina

After 4 years of dutiful constant amazing service, relegating the original Unibody MacBook Pro to backup duty, for the svelte new Retina version.

The Good:

- Snappy! the PicCollage project compiles in like 5 seconds, so the development cycle is much faster than the usual "code, compile, go check email for 2 minutes, debug". More and faster features coming soon!

- Holy crap, where did the pixels go? I'm old, but not so old as that my eyesight cannot tell the difference, but enough that after 30 years of seeing pixels, my brain still does a double take every time I sit down to work, and asks me why I'm typing into a glossy magazine page.

- Completely noiseless, it's like using an iPad with a keyboard. The only way I can tell it's on is by feeling to see if it's warm.

- The keys are somehow harder and not as clickable, but still it's amazing how it's the same keyboard everywhere and the same Moshi ClearGuard still works.

The Bad (nitpicks):

- One of my favorite design elements of the old MacBook Pro was the invisible almost-microscopic white LED lights that it used to have to show battery life and whether it was sleeping. It was sheer magic to have lights appear on smooth brushed aluminum. Those are sadly gone, and the anal side of me misses being able to tell whether the computer was sleeping ok by seeing them "breathe" (this is what I do with my real kids too).

- Safari looks great, but Google Chrome (my default) looks horribly pixellated. Luckily Google Chrome Canary looks super slick. But maybe it will blow up on me spectacularly.

- New form factor means I can't find a sleeve or case for it. 

- The new "MagSafe 2" power connector is incompatible (thinner than the previous one). How Apple spoiled us by having a consistent power connector across their whole line. Now I have to have a mini magnetic dongle to use the power adapters in the office. Only $10, but very very losable.

- They got rid of the Kensington lock slot. Seems unnecessary, I used to carry around a lock for when you have to leave it plugged into in somebody's office. $2300 is a lot of computer to have boosted.

Saturday, May 15, 2010

Open-sourced Projects

We've been busy these last few months, here's a couple of libraries we open sourced:
  • rest-graph: A simple wrapper to access Facebook's Graph API.
  • cerialize: A drop-in replacement for Rails' "serialize" to use Marshal (or others) instead of slow YAML.

Thursday, October 15, 2009

Rails i18n truly default locales

The now built-in i18n functionality in Rails is a great and simple way of internationalizing a Rails app. However, one annoying out-of-the-box feature is that if one of your locales is missing a translation string, it will default it to a message like "translation missing: es, whassup", so you have to make sure that every string on every locale is set, which can be a pain.

A gentler approach would be to fallback to a "default" locale, and look up the string there. Not to be confused with the I18n.default_locale which is the locale to use when no locale at all is specified by the request.

Luckily the designers left us a backdoor to deal with this in the form of the exception_handler. To setup the fallback functionality have this code run somewhere (an initializer perhaps):

require 'i18n'
module I18n  # Reopen library module
  def self.fallback_default_exception_handler(exception, locale, key, options)
    # Recursive case should fall through
    if exception.kind_of?(MissingTranslationData) && locale != self.default_locale
        return translate(key, options.merge(:locale => self.default_locale, :raise => true))
          # Always raise so we can catch it
      rescue MissingTranslationData
        # Fall through and handle as below
    send :default_exception_handler, exception, locale, key, options

I18n.exception_handler = :fallback_default_exception_handler

Sunday, September 27, 2009

Argument defaults for partials in Rails

It has bugged me, ever since I started using Rails, that when using partials with arguments, it is not easy to define default values for arguments. Matthew Moore sets out an example and has a good solution.

His solution is to check the parameters thusly:
title = nil if local_assigns[:title].nil? 
This can be improved by checking instead whether the value key is there, to handle the case in which you actually want to set the value to nil:
title = :defaultvalue unless local_assigns.has_key? :title
Since this use of local_assigns is a bit of an undocumented hack (and so subject to change), and also a bit (actually documented, thanks Benjamin) long to remember and type, we could do better by hiding this behind a helper. However, local_assigns is a local variable itself, so how to access it from inside the helper?

Ah, but there is a back door! eval allows code to be executed in another context (and hence access to its local variables) provided we have a block to extract a binding from. So, we can make our helper interface be used like this:
title = opt(:title) { :defaultvalue }
Then we implement our helper thusly:
module OptHelper
  def opt(name, &block)
    if eval("local_assigns.has_key? :#{name}", block.binding)
      eval name.to_s, block.binding
The first eval checks to see whether the variable was assigned, second eval is so that we can return that value. The yield executes the passed-in block to get the default value. This implementation also has the advantage that the default value can be an expensive operation that only gets executed if it's needed.

It turns out however that eval is a rather slow call (the string must be parsed and compiled), so a few benchmarks show that it is better to preemptively lump the two evals together:
module OptHelper
  def opt(name, &block)
    was_assigned, value = eval(
      "[ local_assigns.has_key?(:#{name}), local_assigns[:#{name}] ]", 
    if was_assigned

Friday, September 25, 2009


Why? because some of my colleagues believe code they find on blogs more than the some of the stuff I write, so the solution: publish my own blog. But seriously, also to give some back for the myriad times I've gotten unstuck thanks to some helpful blogger.

Some logistics: I'll expect to be having source code, so some easy way to publish code is needed. I found this: SyntaxHighlighter. Does it work?
class DoesItWork
  def yay!

The documentation is a bit unclear, but to get it working using the author's hosted css and js files, you add this to the bottom of the page:
<link href='' rel='stylesheet' type='text/css'>
<link href='' rel='stylesheet' type='text/css'>
<script language='javascript' src=''>
<script language='javascript' src=''>
<script language='javascript' src=''>
<script language='javascript' src=''>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.defaults.gutter = false;
SyntaxHighlighter.config.clipboardSwf = '';

I added this to the bottom of the Blogger template, and then simply surrounded the code with
<pre name="code" class="brush:ruby">
class DoesItWork
  def yay!

The .swf (Adobe/Macromedia Shockwave) is to enable the neat clipboard functionality.