Jason Fox

Icon

programming, products, and pontifications…

The iPad is the Wii of Computing

the_ipad_is_the_wii_of_computing

I think the geeks have it wrong.  The iPad is a revolutionary device and a game changing one at that.  I believe that the iPad is to computing what the Nintendo Wii is to video gaming.  While it may not have the most amazing graphics, the most powerful CPU (though it just might), the most storage or even all of the features that we want such as multitasking, it does not matter.  I repeat, it does not matter, just as it did not matter for the Wii.

The Nintendo Wii is really just a GameCube in different packaging just like the iPad is just an iPod Touch in bigger packaging.   The “magic” of the Wii is not it’s amazing technical specifications like say the Sony Playation 3.  No, the real magic of the Wii is in its ability to change the way that the game is played; literally and figuratively.

The Wii is appealing because anyone can play the games, old, young, veteran video gamers or newcomers and have fun playing them.  The Wii removes the requirement of being a video gamer to play video games.  There’s no need to master impossible sequences of key presses just to be able to challenge your friend to a game of tennis.  Instead you just pick up the controller and play; it requires no instruction and therefore lowers the barriers to video gaming.  The iPad does the same thing for computing.

The iPad is the first “computer” that I would consider buying my mom (actually the Litl Webook was the first, however, it is now surely doomed).  The trick of the iPad is that it removes the “computer-y” things from the computer.  This one aspect of the iPad is the key thing that absolutely makes it a revolutionary device irrespective of it’s technical specifications or naive feature set.  The iPad allows anyone young, old, tech savvy or not to be able to intuitively use a computer for the first time in history.  This to me is why the iPad is a game changer and is one reason why the iPad will not be a flop.

The iPad is a harbinger of things to come in computing, specifically in human-computer interaction models and I, for one, welcome it.

Wireless Audio Streaming with Apple’s Airport Express, Airfoil and VLC

Streaming audio with Apple’s Airport express is seamless and simple.  You plug in the Airport Express into the wall, plug in the audio cables (NOT INCLUDED) to your stereo and off you go.  However, if you want to watch movies on your computer and enjoy the same wireless audio you get with iTunes, things get a bit more complicated.

First off, Apple’s Airtunes protocol apparently has a built in 2-ish second delay before it starts playing the audio you’ve summoned up.  That’s not a problem if you’re listening to music, but, if your audio is paired with some video the result is unsycnhronized viewing.  More importantly, though, is the fact that iTunes only let’s you stream music to the Airport Express.  What about that pirated copy of Paranormal Activity you just downloaded from bit torrent?  Fear not, there is a solution.

First you need to get a nice little app called Airfoil.  Airfoil allows you to stream ANY audio from any application to your Airport Express.  Wow, perfect!  Well, hold on a second, let’s return to that little issue with Apple’s Airtunes protocol before you plop down your $25 for a license (you were going to BUY a license, weren’t you?).

The problem again is that any audio you play over the air with your Airport Express will be delayed about 2 seconds.  This means that your audio will lag behind your video.  Booooo… Ok, so, let’s just delay the video a bit so that the audio has time to catch up!  Simple solution, right?  Yes and no.

Desynchronization of audio and video will work in video players like VLC.  VLC makes desynchronization of audio and vidoe really, really simple.  In fact, you can change the sychronization settings on the fly by pressing the “f” and “g” keys.  I found a post that explains it all.  (Note that his instructions are for an older version of VLC.  However, the instructions are the same except that in the new one you select the “All” radio button in the bottom left hand corner of the preferences pane instead of the “Advanced” checkbox to access VLC’s full array of settings.  Also I found -2100 to be a better delay for me.)

Unfortunately there is no solution that I know of for synchronizing internet video like Hulu.com with the delayed audio of the Airport Express.  That’s a bit of a let down as Hulu.com is really the only way I watch “television” these days (It’s not exactly television if I watch it on my computer, now is it? I’m really “watching computer”.  Oh what will we do when the mediums we’re used to are no more?  How will we know what to call things anymore? Will a newspaper still be called a newspaper if we read it on Apple tablet or will it be a newstablet?)  If anyone knows of a solution please let me know.

In conclusion, a combination of Apple’s Airport Express, Airfoil and VLC allow you to cut the cords and enjoy audio on your stereo wirelessly, however, it’s not without faults and frustrations and some big exceptions (read: no Hulu.com). Oh, I should mention that Airfoil does ship with its own video player that handles the audio desyncrhonization for you.  I however was unable to get it to play several of my videos.

killall Dock - the most awesome command in the world

Ever have Expose freeze up on you? Command-TAB stops working, Spaces stops working, the Dock stops working, show desktop stops working, show windows stops working; you’re trapped!  Well, if you happen to have a terminal window open or can launch one, fear not!  Simply issue the following command (make sure to use a capital ‘D’) and you’re golden.  No restart required!

$ killall Dock

Share and enjoy!

Backgroundjob (Bj) Won’t Start

Recently I had a problem with Bj where it would not start up.  Nothing was written to the backgroundjob log or Rails log and no exception was being thrown.  To make the problem even stranger, Bj would start-up just fine in development but not in production but worked just fine in production from script/console.  After digging into the Bj code and adding some debug statements I found the problem.

# database.yml
development:
  adapter: mysql
  database: my_development
  username: me
  password: password
  host: localhost
  port: 3306

test:
  adapter: mysql
  database: my_test
  username: me
  password: password
  host: localhost
  port: 3306

production:
  development

Bj was getting an ActiveRecord::ConnectionNotEstablished exception but was swallowing it.  The solution was to explicitly define the production database connection in database.yml.

Disk Utility: “File system formatter failed.”

If you receive the “File system formatter failed” error message while trying to partition a large hard drive using Disk Utility in OSX you need to change the partition type to GUID.  Click the Options… button at the bottom of the partition list and select the GUID Partition Table:

screen-capture-12

Iomega Prestiege 1TB Review - First Impressions

iomega_prestiege

Just got my two Iomega Prestiege 1TB hard drives from Amazon ($104/each) to support my new backup strategy (more on that later).  First impressions: PROS: Very quiet, very solid feeling construction, CONS: Activity light placement forces you to put it to the left of you, the color is not at all like the picture; the drive is more of a gun metal, putty grey than a shiny silver aluminum like the MacBook Pro.  Oh well, all I ask is that it will last longer than my Western Digital MyBook.

Decemberists <3 Bon Jovi?

Is it just me or does the guitar riff in the song “Margaret in Captivity” on the Decemberists’ new album “The Hazards of Love” sound almost exactly like the guitar riff from Bon Jovi’s “Wanted Dead or Alive?”

acts_as_universally_unique

I recently found the need to provide UUIDs for ActiveRecord models in a service that I’m developing.  I wasn’t able to find a suitable soution, so, I rolled my own.  Enter acts_as_universally_unique.  The plugin simply adds a (customizabe) UUID field to all ActiveRecord models that act_as_universally_unique.  I will be adding additional methods (and test cases) to it shortly.

XML-RPC, SOAP and Polymorphism

According to the XML-RPC specification a XML_RPC request may only contain scalar <value>s or non-scalar <struct>s. The specification unfortunately does not provide any standard for encoding the type of data encoded in the <struct>s. This has the side effect of not being able to support polymorphism in service method parameters as it leaves the sever no choice but to rely on the method signature in the API declaration when trying to determine what to instantiate for a given <struct> in the XML-RPC request.

Let’s say you have the following declarations:

class SubscriptionsApi < ActionWebService::API::Base
  api_method(
    :create_subscription,
    :expects => [
      { :customer => Logical::Customer },
      { :payment_method => Logical::PaymentMethod }
    ]
  )
end
module Logical
  class PaymentMethod < ActionWebService::Struct
  end
  class CreditCard < PaymentMethod
    member :card_number, :string
    # ...
  end
  class PayPal < PaymentMethod
    member :login, :string
    # ...
  end
end

Now you want to make a call to the service method and pass either a CreditCard or a PayPal. XML-RPC will encode the request like so:

<methodCall>
  <methodName>create_subscription</methodName>
  <param>
    <struct>
      <member>
        <name>card_number</name>
        <value>4111-1111-1111-1111</value>
      </member>
    </struct>
  </param>
</methodCall>

This provides no type information to the server so the server will attempt to instantiate a Logical::PaymentMethod which will of course not have a card_number member as it’s specific to the CreditCard subclass. SOAP, on the other hand, does encode the parameter types allowing you to utilize this type of polymorphism in your service parameters. Here’s the same request encoded in SOAP.

<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<env:Body>
  <n1:CreateSubscription xmlns:n1="urn:ActionWebService" env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <payment_method xmlns:n2="http://www.ruby-lang.org/xmlns/ruby/type/custom" xsi:type="n2:Logical..CreditCard">
      <card_number xsi:type="xsd:string">1</card_number>
    </payment_method>
  </n1:CreateSubscription>
 </env:Body>
</env:Envelope>

The current implementation of ActionWebService resurrected by datanoise did not support this type of polymorphism in SOAP requests. However, I submitted a patch recently which provides for this functionality. Hopefully it’s accepted. :)

MySQL Allows NULLs Where They Are Not Welcome

I recently came across an annoying bug in MySQL v5.1 (also in 6.0 apparently) that bit me hard, so, I thought I’d post on it in case you are being bitten by the same bug.

If you attempt to update a column that does not allow NULL to NULL, MySQL will set the column’s value to the default value for that column’s data type.  This is true only when you are not running MySQL strict mode.  Here’s an example to illustrate.

mysql> create table null_test (id int not null unique(id), name varchar(25)
null default null);
Query OK, 0 rows affected (0.01 sec)

mysql> show create table null_test;
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                           |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
| null_test | CREATE TABLE `null_test` (
  `id` int(11) NOT NULL,
  `name` varchar(25) default NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-----------+--------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> insert into null_test (id, name) values (1, 'Jane');
Query OK, 1 row affected (0.00 sec)

mysql> update null_test set id = null;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 0  Changed: 0  Warnings: 0

mysql> select * from null_test where name = 'Jane';
+----+------+
| id | name |
+----+------+
|  0 | Jane |
+----+------+
1 row in set (0.00 sec)

More information about this bug can be found in the bug report submitted Janurary 4, 2008.