<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Nathan de Vries - Home</title>
  <id>tag:www.atnan.com,2010:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  <link href="http://www.atnan.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.atnan.com/" rel="alternate" type="text/html"/>
  <updated>2010-11-05T11:12:50Z</updated>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-08-09:5126</id>
    <published>2009-08-09T10:29:00Z</published>
    <updated>2010-11-05T11:12:50Z</updated>
    <category term="app store"/>
    <category term="apple"/>
    <category term="java verified"/>
    <category term="submissions"/>
    <link href="http://www.atnan.com/2009/8/9/apple-s-app-store-submission-process-java-verified" rel="alternate" type="text/html"/>
    <title>Apple's App Store Submission Process &amp; Java Verified</title>
<content type="html">
            &lt;p&gt;There&#8217;s a lot of discussion going on at the moment about Apple&#8217;s App Store submission process and the role that carriers play in vetting applications. When the App Store was announced, I naïvely believed that Apple had successfully cut out the carrier middleman responsible for crippling every other mobile development platform. Unfortunately, the carrier protectionist oligopoly lives on, albeit on a slightly smaller scale.&lt;/p&gt;


	&lt;p&gt;But it&#8217;s not all doom and gloom. I see two major issues:&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;Carriers are barring applications they deem disruptive to their business&lt;/li&gt;
&lt;li&gt;The submissions process is completely opaque&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;If history is anything to go by, the first issue is going to be very difficult to resolve directly. It&#8217;s the second issue I think we&#8217;re in a position to easily fix.&lt;/p&gt;


	&lt;p&gt;First, I think it would be productive to look at the &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; platform.&lt;/p&gt;


	&lt;p&gt;One of the biggest issues that&#8217;s plagued &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; has been greedy carriers standing in the way of developers trying to bring their applications to market (ring any bells?). To access run-of-the-mill features like the address book, networking or &lt;span class=&quot;caps&quot;&gt;GPS&lt;/span&gt; APIs you need to sign your application. Problem is, certificates from well known CAs like Verisign are stripped from carrier-branded phones in favour of carrier issued certificates. Many carriers run their own developer program to facilitate code-signing of applications that will run on their network.&lt;/p&gt;


	&lt;p&gt;The industry&#8217;s &#8220;answer&#8221; to this problem was to come up with &lt;a href=&quot;http://javaverified.com&quot;&gt;Java Verified&lt;/a&gt;, a process that allows developers to submit their applications to one of a handful of &#8220;Authorized Test Houses&#8221; and pay around $300USD to have it taken through a standard test procedure. If it passes, you get a signed application which will run on most carriers and devices. If it fails, you pay again for the privilege of having it retested. Also note that you&#8217;re paying to have your application tested on a specific device of your choosing, so if you&#8217;d like your application tested on multiple devices, you pay per device.&lt;/p&gt;


	&lt;p&gt;Disregarding the fact that the Java Verified process will leave you thousands of dollars poorer once you&#8217;ve released a few versions of your application to a handful of devices, it&#8217;s quite similar to Apple&#8217;s verification process. You submit your application, it gets tested according to a criteria that carriers are happy with, and if your application passes you&#8217;re good to go.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;&lt;span class=&quot;caps&quot;&gt;BUT&lt;/span&gt;&lt;/em&gt;, there&#8217;s one minor difference; the Java Verified testing houses are all following the same open, standard test script. It&#8217;s called the &lt;a href=&quot;http://javaverified.com/graphics/PDF/UTC_3_0_FINAL.pdf&quot;&gt;Unified Testing Criteria (PDF)&lt;/a&gt;, and it&#8217;s made available to developers so that they know how their applications are being scrutinised by the testers.&lt;/p&gt;


	&lt;p&gt;I think Java Verified&#8217;s Unified Testing Criteria would form a great basis for a similar document to be written for the App Store submission process. It would cover areas like:&lt;/p&gt;


&lt;ul&gt;
&lt;li&gt;High-level APIs being used (GPS, address book etc.), how frequently they&#8217;re used, and whether or not they remove user data (address book entries etc.)&lt;/li&gt;
&lt;li&gt;Remote content used in the application. Where does it come from? Is it interpreted and/or executed to change the behavior of the application? Could it contain offensive content? Does the application&#8217;s rating take into account mature content?&lt;/li&gt;
&lt;li&gt;Data usage over 3G, including a clear set of quantitative guidelines that take into account what carriers deem appropriate on their networks&lt;/li&gt;
&lt;li&gt;Rights to publish content, either through ownership, licensing or fair use&lt;/li&gt;
&lt;li&gt;Use of advertising&lt;/li&gt;
&lt;li&gt;Whether or not behavior, usage and metrics about the user are recorded&lt;/li&gt;
&lt;li&gt;Stability, performance, memory, network and battery usage tests&lt;/li&gt;
&lt;li&gt;Adherence to the Human Interface Guidelines (HIG)&lt;/li&gt;
&lt;li&gt;Handling of memory warnings&lt;/li&gt;
&lt;li&gt;Handling of registered &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; schemes&lt;/li&gt;
&lt;li&gt;Ability to run during a call or tethering&lt;/li&gt;
&lt;li&gt;Ability to handle lack of network access or network delays&lt;/li&gt;
&lt;li&gt;Appropriate use of the keychain for secure storage&lt;/li&gt;
&lt;/ul&gt;

	&lt;p&gt;The document would likely take the form of a questionnaire, with a clear definition of pass/fail conditions for the various questions. If a developer filled out the questionnaire and received a clear pass but Apple&#8217;s testing produced a fail, the difference between their questionnaires would form the basis for productive communication to resolve the issues and allow for resubmission. The document would evolve over time, hopefully reaching a point where if you filled out the questionnaire yourself and got a pass, you&#8217;re almost guaranteed to get through the submission process.&lt;/p&gt;


	&lt;p&gt;I really think this would make a world of difference, and wouldn&#8217;t require any drastic changes for Apple other than a little bit more open documentation of the existing process.&lt;/p&gt;


	&lt;p&gt;Thoughts?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-07-29:4945</id>
    <published>2009-07-29T04:00:00Z</published>
    <updated>2010-11-05T11:16:43Z</updated>
    <category term="atom"/>
    <category term="feedburner"/>
    <category term="feeds"/>
    <link href="http://www.atnan.com/2009/7/29/my-feed-urls-have-changed" rel="alternate" type="text/html"/>
    <title>My Feed URLs Have Changed</title>
<content type="html">
            &lt;p&gt;With Google&#8217;s acquisition of Feedburner, I&#8217;ve been locked out of my Feedburner account. Since Google doesn&#8217;t seem to be providing any level of support for the relocation process, I&#8217;ve been forced to recreate my feeds. If you&#8217;re subscribed to the article feed (&lt;a href=&quot;http://feeds.feedburner.com/atnan&quot;&gt;http://feeds.feedburner.com/atnan&lt;/a&gt;) or comments feed (&lt;a href=&quot;http://feeds.feedburner.com/atnan-comments&quot;&gt;http://feeds.feedburner.com/atnan-comments&lt;/a&gt;), you should point your feed reader to these new feed URLs:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://feeds.feedburner.com/atnan-articles&quot;&gt;http://feeds.feedburner.com/atnan-articles&lt;/a&gt;
&lt;a href=&quot;http://feeds.feedburner.com/atnan-all-comments&quot;&gt;http://feeds.feedburner.com/atnan-all-comments&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Sorry for any inconvenience&#8212;I know I&#8217;ve found it a bit of a pain when other blogs have changed their feed URLs on me!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-07-27:4916</id>
    <published>2009-07-27T13:19:00Z</published>
    <updated>2010-11-05T11:13:04Z</updated>
    <category term="apns"/>
    <category term="development"/>
    <category term="iphone"/>
    <category term="logging"/>
    <category term="verbose"/>
    <link href="http://www.atnan.com/2009/7/27/enabling-verbose-push-notification-service-apns-logs" rel="alternate" type="text/html"/>
    <title>Enabling Verbose Push Notification Service (APNS) Logs</title>
<content type="html">
            &lt;p&gt;Those of you who are developing iPhone applications that utilise Apple&#8217;s Push Notification Service (APNS) will understand that sometimes it feels like a bit of a black hole. Fortunately, Matt Drance (Apple&#8217;s current Application Frameworks Evangelist) has made a device configuration profile available which enables verbose logging in &#8220;apsd&#8221;, the daemon that runs on devices and is responsible for connecting to the &lt;span class=&quot;caps&quot;&gt;APNS&lt;/span&gt; servers and retrieving push notifications.&lt;/p&gt;


	&lt;p&gt;You can grab a copy of the configuration profile directly from my site (&lt;a href=&quot;http://www.atnan.com/APNsLogging.mobileconfig&quot;&gt;http://www.atnan.com/APNsLogging.mobileconfig&lt;/a&gt;), or by visiting the &lt;a href=&quot;https://devforums.apple.com/message/58759&quot;&gt;original thread&lt;/a&gt; Matt attached the file to on Apple&#8217;s developer forums.&lt;/p&gt;


	&lt;p&gt;To install the profile on your device, you can point Mobile Safari directly at the file on my site, email the file to your device, or install it via the iPhone Configuration Utility. For those of you who are unfamiliar with *.mobileconfig files, you should read Apple&#8217;s &lt;a href=&quot;http://manuals.info.apple.com/en_US/Enterprise_Deployment_Guide.pdf&quot;&gt;Enterprise Deployment Guide&lt;/a&gt; which provides much more detailed instructions.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-07-10:4546</id>
    <published>2009-07-10T05:14:00Z</published>
    <updated>2010-11-05T11:17:34Z</updated>
    <category term="development"/>
    <category term="iphone"/>
    <category term="xcode"/>
    <link href="http://www.atnan.com/2009/7/10/running-two-or-more-versions-of-xcode-for-stable-beta-iphone-development" rel="alternate" type="text/html"/>
    <title>Running Two or More Versions of Xcode for Stable/Beta iPhone Development</title>
<content type="html">
            &lt;p&gt;This is a simple but useful tip for people like myself who want to stay up to date with the latest beta releases of the iPhone &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;, but who also rely on having a stable version of the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; installed for things like deploying to the App Store, reproducing bugs from in-the-wild, or client work that doesn&#8217;t take advantage of any new &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; features.&lt;/p&gt;


	&lt;p&gt;The first time I grabbed a beta version of the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;, all I did was hit the install button and let it do its thing. However, if you don&#8217;t change any of the default install settings, you&#8217;ll quickly find that the beta &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; has been installed straight over the top of your stable version of the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;The solution is to install two copies of Xcode and the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;; the stable version goes in &#8221;/Developer&#8221;, and the beta version goes in &#8221;/Developer Beta&#8221;.&lt;/p&gt;


	&lt;p&gt;If you&#8217;ve already installed a beta version of the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; in &#8221;/Developer&#8221;, you&#8217;ll need to remove it. To do this, you should run the following from the command line:&lt;/p&gt;


&lt;pre&gt;sudo /Developer/Library/uninstall-devtools --mode=all&lt;/pre&gt;

	&lt;p&gt;You can then proceed to install the stable &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; in &#8221;/Developer&#8221; and the beta in &#8221;/Developer Beta&#8221;. If you ever need to blow away your beta copy of Xcode and the &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;, you should run the same command as above but from the beta directory instead:&lt;/p&gt;


&lt;pre&gt;sudo /Developer Beta/Library/uninstall-devtools --mode=all&lt;/pre&gt;

	&lt;p&gt;Finally, to launch Xcode with the stable &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; you run &#8221;/Developer/Applications/Xcode.app&#8221; and to launch Xcode with the beta &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;, run &#8221;/Developer Beta/Applications/Xcode.app&#8221;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-06-19:3837</id>
    <published>2009-06-19T03:03:00Z</published>
    <updated>2010-11-05T11:17:39Z</updated>
    <category term="apple"/>
    <category term="caldav"/>
    <category term="google calendar"/>
    <category term="iphone"/>
    <link href="http://www.atnan.com/2009/6/19/configuring-multiple-caldav-google-calendars-on-iphone-os-3-0" rel="alternate" type="text/html"/>
    <title>Configuring Multiple CalDAV / Google Calendars on iPhone OS 3.0</title>
<content type="html">
            &lt;p&gt;One of the cool features of Leopard was the addition of CalDAV support to iCal, which allows you to read/write/edit/delete calendars hosted by third parties like Google Calendar. Similar functionality was available on the iPhone, but only via Apple&#8217;s MobileMe service. That&#8217;s changed with iPhone &lt;span class=&quot;caps&quot;&gt;OS 3&lt;/span&gt;.0.&lt;/p&gt;


	&lt;p&gt;If you&#8217;ve configured a bunch of CalDAV calendars in iCal, unfortunately they&#8217;re synced to the iPhone as read-only calendars which is a real pain. In lieu of a fix by Apple, we&#8217;ll need to remove the iCal CalDAV accounts from the iTunes calendar sync list, and configure them on the iPhone itself.&lt;/p&gt;


	&lt;p&gt;To set up a new CalDAV account, you&#8217;ll need to navigate through the following screens on your iPhone:&lt;/p&gt;


	&lt;p&gt;Settings → Mail, Contacts, Calendars → Add Account&#8230; → Other → Add CalDAV Account&#8230;&lt;/p&gt;


	&lt;p&gt;Once you&#8217;re there, you&#8217;ll be presented with a dialogue that lets you enter a CalDAV server, username, password and description. This dialogue is incredibly misleading, because the &#8220;server&#8221; field will not only accept a hostname like &#8220;www.google.com&#8221;, but also a full CalDAV &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; like &#8220;https://www.google.com/calendar/dav/&amp;lt;CALENDAR_ID&amp;gt;/user&#8221;. If you&#8217;re using Google Calendar with only one calendar, enter your Google Calendar credentials like the following example:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.atnan.com/assets/2009/6/19/Standard_Google_Account.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;If you&#8217;ve got multiple CalDAV calendars, it starts to get a little bit hairier. Initially, I emailed myself a list of my CalDAV URLs (4 in total) and used the new copy-paste features to manually configure each account using the previous instructions, only instead of using &#8220;www.google.com&#8221; in the server field, I pasted the entire CalDAV &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; instead. As you can imagine, this is incredibly tedious.&lt;/p&gt;


	&lt;p&gt;Fortunately Apple also released a new version of the iPhone Configuration Utility (ICU), which is a really handy tool for creating iPhone configuration bundles for deployment in enterprise environments. Among other things, this new version allows you to configure CalDAV accounts. If you haven&#8217;t already, you should grab a copy of &lt;span class=&quot;caps&quot;&gt;ICU&lt;/span&gt; &lt;a href=&quot;http://support.apple.com/downloads/iPhone_Configuration_Utility_2_0_for_Mac_OS_X&quot;&gt;for &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt;&lt;/a&gt; or &lt;a href=&quot;http://support.apple.com/downloads/iPhone_Configuration_Utility_2_0_for_Windows&quot;&gt;Windows&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Launch &lt;span class=&quot;caps&quot;&gt;ICU&lt;/span&gt;, create a new configuration profile, and open the CalDAV pane. For each CalDAV calendar you want to configure, you&#8217;re going to want to fill it in like this:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.atnan.com/assets/2009/6/19/iPhone_Configuration_Utility.png&quot;&gt;&lt;img src=&quot;http://www.atnan.com/assets/2009/6/19/iPhone_Configuration_Utility.png&quot; width=&quot;100%&quot; /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;If you&#8217;re looking at the Principal &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; field and wondering what &#8221;&amp;lt;CAL_ID&amp;gt;&#8221; is, you&#8217;ll find it in the calendar settings page of Google Calendar under Calendar Address (it should look like an email address).&lt;/p&gt;


	&lt;p&gt;Once you&#8217;ve entered all your CalDAV accounts, plug in your iPhone, select it in &lt;span class=&quot;caps&quot;&gt;ICU&lt;/span&gt; and open the Configuration Profiles tab. You should see the configuration profile you just created, with an &#8220;Install&#8221; button next to it. Hit the &#8220;Install&#8221; button.&lt;/p&gt;


	&lt;p&gt;You iPhone should show a screen like this:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.atnan.com/assets/2009/6/19/Install_Profile.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;If you hit &#8220;More Details&#8221;, you&#8217;ll see the CalDAV calendars listed:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.atnan.com/assets/2009/6/19/Install_Profile_More_Details.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Hit &#8220;Install&#8221;, confirm, and open up the Calendar App to see if everything works as expected. You should be able to create, edit and delete calendar entries in your CalDAV accounts, and have them update in iCal / Google Calendar. If you ever want to add a new CalDAV calendar, I think you need to remove the configuration via the iPhone Configuration Utility and re-install the edited configuration bundle.&lt;/p&gt;


	&lt;p&gt;Hopefully it doesn&#8217;t take too long for Apple to make the CalDAV integration between iCal and the iPhone more seamless.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-04-04:1563</id>
    <published>2009-04-04T07:21:00Z</published>
    <updated>2010-11-05T11:13:17Z</updated>
    <category term="internet tethering"/>
    <category term="iphone"/>
    <link href="http://www.atnan.com/2009/4/4/enabling-internet-tethering-via-optus-virgin-on-iphone-os-3-0" rel="alternate" type="text/html"/>
    <title>Enabling Internet Tethering via Optus/Virgin/Vodafone/Telstra on iPhone OS 3.0</title>
<content type="html">
            &lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; Due to changes in the public release of iTunes 8.2, you will now need to quit iTunes and run a command in your Terminal before proceeding with the instructions below. The command is: &#8220;defaults write com.apple.iTunes carrier-testing -bool &lt;span class=&quot;caps&quot;&gt;TRUE&lt;/span&gt;&#8221;.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; I&#8217;ve downloaded the Telstra and Vodafone bundles and made similar modifications, so they&#8217;re now available in the guide. If you&#8217;re using Telstra/Vodafone and my modified settings bundles work, please let me know in the comments as I&#8217;m unable to test it myself.&lt;/p&gt;


	&lt;p&gt;The following instructions are intended for members of the &lt;a href=&quot;http://developer.apple.com/&quot;&gt;Apple Developer Connection&lt;/a&gt; (ADC), running an iPhone with a developer version of the iPhone &lt;span class=&quot;caps&quot;&gt;OS 3&lt;/span&gt;.0 software. This guide also only provides Australian carrier settings for Telstra, Vodafone and Optus (plus resellers like Virgin), but if you follow the link to Crunchgear in the first step there are instructions on downloading and modifying the carrier setting bundles.&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;Download &lt;a href=&quot;http://www.atnan.com/Telstra_au.ipcc.zip&quot;&gt;Telstra_au.ipcc&lt;/a&gt;, &lt;a href=&quot;http://www.atnan.com/Vodafone_au.ipcc.zip&quot;&gt;Vodafone_au.ipcc&lt;/a&gt; or &lt;a href=&quot;http://www.atnan.com/Optus_au.ipcc.zip&quot;&gt;Optus_au.ipcc&lt;/a&gt;, which were created as per the &lt;a href=&quot;http://www.crunchgear.com/2009/03/19/how-to-enable-tethering-under-iphone-firmware-30/&quot;&gt;AT&#38;T instructions on Crunchgear&lt;/a&gt; (note that the file should have an &#8221;.ipcc&#8221; extension, not &#8221;.zip&#8221;. If your downloaded file has a &#8221;.zip&#8221; extension, unzip it to produce a &#8220;Carrier_au.ipcc&#8221; file)&lt;/li&gt;
&lt;li&gt;Open iTunes&lt;/li&gt;
&lt;li&gt;Plug in your iPhone&lt;/li&gt;
&lt;li&gt;Select you iPhone under devices&lt;/li&gt;
&lt;li&gt;In the Summary tab, ⌥-click (option-click) the &#8220;Check for Update&#8221; button&lt;/li&gt;
&lt;li&gt;Select the previously downloaded Telstra_au.ipcc / Vodafone_au.ipcc / Optus_au.ipcc file and click &#8220;Open&#8221;&lt;/li&gt;
&lt;li&gt;Once the settings have been copied, disconnect your iPhone&lt;/li&gt;
&lt;li&gt;Restart your iPhone&lt;/li&gt;
&lt;li&gt;Open the Settings application on your iPhone, and navigate to General, then Network, and finally Internet Tethering&lt;/li&gt;
&lt;li&gt;Turn Internet Tethering on. At this point, tethering is now possible via &lt;span class=&quot;caps&quot;&gt;USB&lt;/span&gt; when your iPhone is plugged in. If you&#8217;d like to use Bluetooth, continue reading&lt;/li&gt;
&lt;li&gt;You will be prompted to turn bluetooth on if it&#8217;s not on already. Select yes if prompted&lt;/li&gt;
&lt;li&gt;On your laptop, turn on bluetooth and open the Bluetooth Preference pane&lt;/li&gt;
&lt;li&gt;Click &#8220;Set Up New Device&#8230;&#8221;, which will open the Bluetooth Setup Assistant&lt;/li&gt;
&lt;li&gt;Select &#8220;Mobile Phone&#8221; as the Device Type&lt;/li&gt;
&lt;li&gt;Select your iPhone from the device list&lt;/li&gt;
&lt;li&gt;A number should appear on your laptop, and your iPhone should prompt you for a pin&lt;/li&gt;
&lt;li&gt;Enter the pin from your laptop into your iPhone&lt;/li&gt;
&lt;li&gt;Once paired, make sure you keep &#8220;Use device as network port&#8221; selected&lt;/li&gt;
&lt;li&gt;In the Bluetooth Preference Pane, make sure &#8220;Show Bluetooth status in the menu bar&#8221; is selected, since it makes things easier for starting and stopping tethering&lt;/li&gt;
&lt;li&gt;Click the Bluetooth icon in your status bar, where you should now see your iPhone under devices&lt;/li&gt;
&lt;li&gt;Click on the menu item for your device, and select &#8220;Connect to Network&#8221;&lt;/li&gt;
&lt;li&gt;On your iPhone, you should now notice that the top of the screen has a blue bar titled &#8220;Internet Tethering&#8221;&lt;/li&gt;
&lt;li&gt;You can now use the Internet!&lt;/li&gt;
&lt;li&gt;As an optional extra, you can open Network Preferences and rename the two new network devices to &#8220;iPhone &lt;span class=&quot;caps&quot;&gt;USB&lt;/span&gt;&#8221; and &#8220;iPhone Bluetooth&#8221;&lt;/li&gt;
&lt;/ol&gt;

	&lt;p&gt;Hope that helps someone! Not really a difficult process, but it can be a bit fiddly. Downloading my Optus_au.ipcc file also saves mucking around in Property List Editor too, which most people will attest is a bit of a pain.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2009-04-04:1559</id>
    <published>2009-04-04T04:53:00Z</published>
    <updated>2010-11-05T11:17:46Z</updated>
    <category term="chunked transfer encoding"/>
    <category term="mod_rails"/>
    <category term="passenger"/>
    <category term="rails"/>
    <category term="ruby"/>
    <link href="http://www.atnan.com/2009/4/4/chunked-transfer-encoding-support-in-apache-passenger" rel="alternate" type="text/html"/>
    <title>"Chunked" Transfer-Encoding Support in Apache/Passenger</title>
<content type="html">
            &lt;p&gt;I wrote an article last year about &lt;a href=&quot;http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http&quot;&gt;the lack of Apache support for &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; requests with the &#8220;Transfer-Encoding: chunked&#8221;&lt;/a&gt;. Of course, this problem really only affects those of us who use Apache modules that were developed against the Apache 1.3 &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; (pre-HTTP 1.1). One such module was &lt;a href=&quot;http://www.modrails.com&quot;&gt;Phusion Passenger&lt;/a&gt; &#8211; also known as &#8220;mod_rails&#8221; &#8211; which I was using at the time to provide a web service to &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; MIDlets and an iPhone application (among other things). To get around the lack of support, I presented a solution involving the use of mod_proxy to buffer the chunked request and rewrite it as a new request before passing it to the non-HTTP 1.1 compliant backend.&lt;/p&gt;


	&lt;p&gt;Thankfully as of two days ago, that hack is no longer required if you&#8217;re using Passenger.&lt;/p&gt;


	&lt;p&gt;Hongli Lai (the lead developer of Phusion Passenger) has &lt;a href=&quot;http://github.com/FooBarWidget/passenger/commit/5038157db90d2cd12c65d29154774c98a9e6a0b7&quot;&gt;checked in a change&lt;/a&gt; that enables support for chunked transfer-encoding, which means no more dreaded &#8220;HTTP/1.1 411
Length Required&#8221; responses. So the fix is checked into the tree, and &lt;a href=&quot;http://code.google.com/p/phusion-passenger/issues/detail?id=114&quot;&gt;according to the bug report&lt;/a&gt; will be made available in the next release of the Passenger gem &#8211; version 2.1.4.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2008-11-28:1004</id>
    <published>2008-11-28T11:25:00Z</published>
    <updated>2010-11-05T11:15:01Z</updated>
    <link href="http://www.atnan.com/2008/11/28/configuring-apache-to-accept-chunked-http-requests-from-j2me-cldc-and-midp" rel="alternate" type="text/html"/>
    <title>Configuring Apache to accept chunked HTTP requests from J2ME (CLDC and MIDP)</title>
<content type="html">
            &lt;p&gt;A few months ago, I wrote an article (&lt;a href=&quot;http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http&quot;&gt;&#8220;Transfer-Encoding: chunked&#8221;, or, Chunky &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;!&lt;/a&gt;) describing a solution for accepting chunked &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; requests made by &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; devices to non-HTTP 1.1 compliant servers unable to accept such requests (Mongrel, Lighttpd, Nginx etc.).&lt;/p&gt;


	&lt;p&gt;One of the commenters was concerned that &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; developers suffering from this problem might find it difficult to find my article since I didn&#8217;t really mention &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; MIDlets much at all. So, if you&#8217;re a &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; developer suffering from problems like those described &lt;a href=&quot;http://forums.sun.com/thread.jspa?threadID=5326661&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;http://www.ruby-forum.com/topic/142852&quot;&gt;here&lt;/a&gt; or &lt;a href=&quot;http://forums.sun.com/thread.jspa?threadID=5251115&quot;&gt;here&lt;/a&gt;...check out the &lt;a href=&quot;http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http&quot;&gt;original article&lt;/a&gt; for a simple solution.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2008-11-28:1003</id>
    <published>2008-11-28T11:06:00Z</published>
    <updated>2010-11-05T11:18:05Z</updated>
    <link href="http://www.atnan.com/2008/11/28/issues-with-corefoundation-chunked-requests-iphoneos-2-x-os-10-5-x-and-apache-mod_proxy" rel="alternate" type="text/html"/>
    <title>Issues with CoreFoundation chunked requests (iPhoneOS 2.x / OS 10.5.x) and Apache / mod_proxy</title>
<content type="html">
            &lt;p&gt;A comment was made in my previous article, &lt;a href=&quot;http://www.atnan.com/2008/10/16/memory-issues-with-nsmutableurlrequest-s-sethttpbody-method-in-iphoneos-2-1&quot;&gt;Memory issues with NSMutableURLRequest&#8217;s setHTTPBody: method in iPhoneOS 2.1&lt;/a&gt;, stating that the &#8220;c&#8221; of &#8220;chunked&#8221; in the &#8220;Transfer-Encoding: chunked&#8221; header is similarly capitalised in &lt;span class=&quot;caps&quot;&gt;OS 10&lt;/span&gt;.5.5, which means that the flaw in Apache&#8217;s mod_proxy is exposed by more than just the iPhone.&lt;/p&gt;


	&lt;p&gt;So if you&#8217;re trying to do chunked &lt;span class=&quot;caps&quot;&gt;HTTP POST&lt;/span&gt; requests using the CFNetwork stack, make sure your Apache configuration can deal with the chunked header:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;RequestHeader edit Transfer-Encoding Chunked chunked early&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2008-10-16:757</id>
    <published>2008-10-16T09:04:00Z</published>
    <updated>2010-11-05T11:18:09Z</updated>
    <category term="chunked"/>
    <category term="http"/>
    <category term="iphone"/>
    <category term="objective-c"/>
    <category term="passenger"/>
    <category term="post"/>
    <category term="rails"/>
    <link href="http://www.atnan.com/2008/10/16/memory-issues-with-nsmutableurlrequest-s-sethttpbody-method-in-iphoneos-2-1" rel="alternate" type="text/html"/>
    <title>Memory issues with NSMutableURLRequest's setHTTPBody: method in iPhoneOS 2.1</title>
<content type="html">
            &lt;p&gt;The iPhone developers at my work have been tearing their hair out over the last few days, trying to resolve the last few memory issues in our iPhone application before we send it off for approval by Apple. One of the problem areas they&#8217;ve noticed is when a photo is uploaded to our service via &lt;span class=&quot;caps&quot;&gt;HTTP POST&lt;/span&gt; (both from the camera and otherwise).&lt;/p&gt;


	&lt;p&gt;Not sure who had the bright idea, but one of the developers decided to try passing in the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; body as an NSInputStream (via &lt;code&gt;NSMutableURLRequest&lt;/code&gt;&#8217;s &lt;code&gt;setHTTPBodyStream:&lt;/code&gt;), rather than as &lt;code&gt;NSMutableData&lt;/code&gt; (via &lt;code&gt;NSMutableURLRequest&lt;/code&gt;&#8217;s &lt;code&gt;setHTTPBody:&lt;/code&gt;). Magically, this seems to have solved the memory leak issues.&lt;/p&gt;


	&lt;p&gt;Unfortunately, it created another issue.&lt;/p&gt;


	&lt;p&gt;You might remember that 3 months ago I &lt;a href=&quot;http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http&quot;&gt;wrote an article&lt;/a&gt; on how much of a pain in the arse it was to accept &lt;span class=&quot;caps&quot;&gt;HTTP POST&lt;/span&gt; requests from user agents specifying a &lt;code&gt;Transfer-Encoding&lt;/code&gt; HTTP header value of &lt;code&gt;chunked&lt;/code&gt; (resulting in a &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt; request with no content length). In that article, I proposed a solution using Apache 2 and &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_proxy.html&quot;&gt;mod_proxy&lt;/a&gt;&#8217;s &lt;code&gt;proxy-sendcl&lt;/code&gt; option to get things working again. This worked fine for our &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; clients, but when our iPhone application started blowing chunks at us, our server crapped out with the dreaded 500 error I thought I&#8217;d fixed for good:&lt;/p&gt;


&lt;pre&gt;Chunked Transfer-Encoding is not supported&lt;/pre&gt;

	&lt;p&gt;After whipping out &lt;a href=&quot;http://www.wireshark.org&quot;&gt;Wireshark&lt;/a&gt;, we realised that there was a tiny difference between between what our &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; client was doing and what the iPhone was doing.&lt;/p&gt;


	&lt;p&gt;This is the header the &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; app was sending:&lt;/p&gt;


&lt;pre&gt;Transfer-Encoding: chunked&lt;/pre&gt;

	&lt;p&gt;And this is the header the iPhone was sending:&lt;/p&gt;


&lt;pre&gt;Transfer-Encoding: Chunked&lt;/pre&gt;

	&lt;p&gt;As much as I&#8217;d like to think the different casing of &lt;code&gt;chunked&lt;/code&gt; and &lt;code&gt;Chunked&lt;/code&gt; wouldn&#8217;t affect the behaviour of &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_proxy.html&quot;&gt;mod_proxy&lt;/a&gt;, it seems it does. Fortunately, we can work around this problem too by using Apache&#8217;s &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_headers.html&quot;&gt;mod_headers&lt;/a&gt; module. This allows us to do the following:&lt;/p&gt;


&lt;pre&gt;RequestHeader edit Transfer-Encoding Chunked chunked early&lt;/pre&gt;

	&lt;p&gt;When combined with the solution from my previous article, this leaves us with the following complete solution:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;ProxyRequests Off

&amp;lt;Proxy http://localhost:81&amp;gt;
  Order deny,allow
  Allow from all
&amp;lt;/Proxy&amp;gt;

Listen 80

&amp;lt;VirtualHost *:80&amp;gt;

  RequestHeader edit Transfer-Encoding Chunked chunked early

  SetEnv proxy-sendcl 1
  ProxyPass / http://localhost:81/
  ProxyPassReverse / http://localhost:81/
  ProxyPreserveHost On
  ProxyVia Full

  &amp;lt;Directory proxy:*&amp;gt;
    Order deny,allow
    Allow from all
  &amp;lt;/Directory&amp;gt;

&amp;lt;/VirtualHost&amp;gt;

Listen 81

&amp;lt;VirtualHost *:81&amp;gt;
  ServerName ooboontoo
  DocumentRoot /path/to/my/rails/root/public
  RailsEnv development
&amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Hopefully this saves someone a little bit of time :).&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2008-08-08:405</id>
    <published>2008-08-08T01:44:00Z</published>
    <updated>2010-11-05T11:15:25Z</updated>
    <category term="apache2 mod_proxy transfer-encoding chunked mod_passenger mod_rails"/>
    <link href="http://www.atnan.com/2008/8/8/transfer-encoding-chunked-chunky-http" rel="alternate" type="text/html"/>
    <title>"Transfer-Encoding: chunked", or, Chunky HTTP!</title>
<content type="html">
            &lt;p&gt;Providing a web service for a bunch of browsers is a relatively straightforward affair. It&#8217;s really only once you jump out of the back-end and into the front-end side of things where issues like browser incompatibilities start to become a problem. Thankfully, I feel like I&#8217;m in the position where I think I&#8217;ve got my head wrapped around what&#8217;s involved in providing solutions to these problems.&lt;/p&gt;


	&lt;p&gt;And then mobile phones came along.&lt;/p&gt;


	&lt;p&gt;The service I&#8217;m working on at the moment is consumed by a bunch of clients, including but not limited to web browsers, &lt;span class=&quot;caps&quot;&gt;WAP&lt;/span&gt; browsers, the Flash player, iPhones, &lt;span class=&quot;caps&quot;&gt;J2ME&lt;/span&gt; devices. It&#8217;s the last one that&#8217;s causing headaches at the moment.&lt;/p&gt;


	&lt;p&gt;You see, despite the fact that &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1 is about 9 years old, not all web servers support the features that were introduced. The particular one I&#8217;m talking about is &lt;a href=&quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1&quot;&gt;chunked tranfer encoding&lt;/a&gt;, but I&#8217;m sure there are many others.&lt;/p&gt;


	&lt;p&gt;To give you a general idea, the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; implementations on many mobile handsets will decide to use a chunked transfer encoding if the payload of a &lt;span class=&quot;caps&quot;&gt;PUT&lt;/span&gt;/POST request is over an arbitrary threshold. This causes issues with servers like &lt;a href=&quot;http://nginx.net&quot;&gt;Nginx&lt;/a&gt;, &lt;a href=&quot;http://www.lighttpd.net&quot;&gt;Lighttpd&lt;/a&gt;, &lt;a href=&quot;http://mongrel.rubyforge.org&quot;&gt;Mongrel&lt;/a&gt;, and &lt;a href=&quot;http://code.macournoyer.com/thin&quot;&gt;Thin&lt;/a&gt;, since most of those assume that an incoming &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; request with a payload will also include a Content-Length header.&lt;/p&gt;


	&lt;p&gt;Well guess what? As of 9 years ago, that hasn&#8217;t been the case.&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;http://www.atnan.com/assets/2008/8/8/chunky_bacon.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Take a look at this request:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;POST /search.json HTTP/1.1&lt;tt&gt;
&lt;/tt&gt;User-Agent: curl/7.16.4 (i486-pc-linux-gnu) libcurl/7.16.4 OpenSSL/0.9.8e zlib/1.2.3.3 libidn/1.0&lt;tt&gt;
&lt;/tt&gt;Host: ooboontoo&lt;tt&gt;
&lt;/tt&gt;Accept: */*&lt;tt&gt;
&lt;/tt&gt;Transfer-Encoding: chunked&lt;tt&gt;
&lt;/tt&gt;Content-Type: multipart/form-data; boundary=----------------------------ab5090ac7869&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;92&lt;tt&gt;
&lt;/tt&gt;------------------------------ab5090ac7869&lt;tt&gt;
&lt;/tt&gt;Content-Disposition: form-data; name=&amp;quot;query&amp;quot;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;zoooom&lt;tt&gt;
&lt;/tt&gt;------------------------------ab5090ac7869--&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;0&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Notice anything? If not, try and find a Content-Length header. Pre-HTTP/1.1 you&#8217;d expect to get an &lt;span class=&quot;caps&quot;&gt;HTTP 411&lt;/span&gt; error (length required), but after &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1 it&#8217;s pretty clear what the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1 applications are obliged to do:&lt;/p&gt;


&lt;blockquote cite=&quot;http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1&quot;&gt;All &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1 applications that receive entities &lt;span class=&quot;caps&quot;&gt;MUST&lt;/span&gt; accept the &#8220;chunked&#8221; transfer-coding (section 3.6), thus allowing this mechanism to be used for messages when the message length cannot be determined in advance.&lt;/blockquote&gt;

	&lt;p&gt;That&#8217;s why I find it so surprising that hacks are involved in allowing mobile clients to &lt;span class=&quot;caps&quot;&gt;POST&lt;/span&gt;/PUT to what I&#8217;d traditionally thought of as &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt;/1.1 compliant web servers.&lt;/p&gt;


	&lt;p&gt;But anyway, you want to see the solution right?&lt;/p&gt;


	&lt;p&gt;Well, our initial solution involved &lt;a href=&quot;http://geraldkaszuba.com&quot;&gt;Gerald&lt;/a&gt; writing a little web server in Python which went by the name of &#8220;Dechunker&#8221;. You can imagine what it did, but we quickly found that while it was the simplest way to avoid the problem, it also meant that over time we would end up needing to implement the functionality that was already available in most other web servers. Servers like &lt;a href=&quot;http://httpd.apache.org&quot;&gt;Apache2&lt;/a&gt; and &lt;a href=&quot;http://www.lighttpd.net&quot;&gt;Lighttpd&lt;/a&gt; have become incredibly hardy over the years, and we&#8217;re not going to achieve that overnight.&lt;/p&gt;


	&lt;p&gt;So I then took another look at &lt;a href=&quot;http://httpd.apache.org&quot;&gt;Apache2&lt;/a&gt;, knowing that some modules do support chunked transfer encoding while others don&#8217;t. What I discovered was that Apache&#8217;s &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_proxy.html&quot;&gt;mod_proxy&lt;/a&gt; module could be used in front of anything that doesn&#8217;t support chunked encoding, since it can be configured to &#8220;dechunk&#8221; requests before passing them to a backend.&lt;/p&gt;


	&lt;p&gt;It looks a little something like this:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;25&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;ProxyRequests Off&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;Proxy http://localhost:81&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  Order deny,allow&lt;tt&gt;
&lt;/tt&gt;  Allow from all&lt;tt&gt;
&lt;/tt&gt;&amp;lt;/Proxy&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;VirtualHost *:80&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  SetEnv proxy-sendcl 1&lt;tt&gt;
&lt;/tt&gt;  ProxyPass / http://localhost:81/&lt;tt&gt;
&lt;/tt&gt;  ProxyPassReverse / http://localhost:81/&lt;tt&gt;
&lt;/tt&gt;  ProxyPreserveHost On&lt;tt&gt;
&lt;/tt&gt;  ProxyVia Full&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;Directory proxy:*&amp;gt;&lt;tt&gt;
&lt;/tt&gt;    Order deny,allow&lt;tt&gt;
&lt;/tt&gt;    Allow from all&lt;tt&gt;
&lt;/tt&gt;  &amp;lt;/Directory&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;/VirtualHost&amp;gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Listen 81&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;lt;VirtualHost *:81&amp;gt;&lt;tt&gt;
&lt;/tt&gt;  ServerName ooboontoo&lt;tt&gt;
&lt;/tt&gt;  DocumentRoot /path/to/my/rails/root/public&lt;tt&gt;
&lt;/tt&gt;  RailsEnv development&lt;tt&gt;
&lt;/tt&gt;&amp;lt;/VirtualHost&amp;gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;As you can see I&#8217;ve got &lt;a href=&quot;http://httpd.apache.org&quot;&gt;Apache2&lt;/a&gt; listening on port 80, which uses the &#8220;proxy-sendcl&#8221; environment variable available in &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_proxy.html&quot;&gt;mod_proxy&lt;/a&gt; to repack the &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; body and add a Content-Length header to the request. This request is then passed back to a virtual host running on port 81, which is configured to use &lt;a href=&quot;http://www.modrails.com&quot;&gt;Phusion Passenger&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Turns out it&#8217;s pretty simple, and from what I&#8217;ve seen there haven&#8217;t been any negative performance impacts by proxying all requests. It&#8217;s not a permanent solution, and as soon as &lt;a href=&quot;http://www.modrails.com&quot;&gt;Phusion Passenger&lt;/a&gt; fixes the &lt;a href=&quot;http://code.google.com/p/phusion-passenger/issues/detail?id=114&quot;&gt;chunked encoding bug&lt;/a&gt;, I&#8217;ll drop &lt;a href=&quot;http://httpd.apache.org/docs/2.0/mod/mod_proxy.html&quot;&gt;mod_proxy&lt;/a&gt; from our configuration.&lt;/p&gt;


	&lt;p&gt;Hope that helps someone!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2008-04-08:348</id>
    <published>2008-04-08T05:35:00Z</published>
    <updated>2010-11-05T11:11:40Z</updated>
    <category term="rails ruby serialisation activerecord"/>
    <link href="http://www.atnan.com/2008/4/8/activerecord-model-serialisation" rel="alternate" type="text/html"/>
    <title>ActiveRecord Model Serialisation</title>
<content type="html">
            &lt;p&gt;I&#8217;ve been working on a &lt;span class=&quot;caps&quot;&gt;JSON API&lt;/span&gt; for mobile clients recently, and in doing so I&#8217;ve realised how much you need to repeat serialization options throughout Rails applications despite options generally being model specific.&lt;/p&gt;


	&lt;p&gt;This little patch solves that problem by allowing you to decorate your Rails models with model-wide serialization options, like so:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;Article&lt;/span&gt; &amp;lt; &lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  has_many &lt;span class=&quot;sy&quot;&gt;:comments&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  serialization_options &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt; =&amp;gt; &lt;span class=&quot;sy&quot;&gt;:comments&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This means that whenever you call &lt;code&gt;to_json&lt;/code&gt; or &lt;code&gt;to_xml&lt;/code&gt; on an instance of &lt;code&gt;Article&lt;/code&gt;, you&#8217;ll get the comment association thrown in for you. You&#8217;ll find you can clean up your Controllers and remove explicit calling of &lt;code&gt;to_json&lt;/code&gt;, which previously would have looked like this:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;respond_to &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |format|&lt;tt&gt;
&lt;/tt&gt;  format.json &lt;span class=&quot;sy&quot;&gt;:json&lt;/span&gt; =&amp;gt; &lt;span class=&quot;iv&quot;&gt;@article&lt;/span&gt;.to_json &lt;span class=&quot;sy&quot;&gt;:include&lt;/span&gt; =&amp;gt; &lt;span class=&quot;sy&quot;&gt;:comments&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;But can now be change to this:&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;respond_to &lt;span class=&quot;r&quot;&gt;do&lt;/span&gt; |format|&lt;tt&gt;
&lt;/tt&gt;  format.json &lt;span class=&quot;sy&quot;&gt;:json&lt;/span&gt; =&amp;gt; &lt;span class=&quot;iv&quot;&gt;@article&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;While it&#8217;s very simple, some people might find it useful. If you do, chuck this in your &lt;code&gt;/lib&lt;/code&gt; directory and require it in &lt;code&gt;environment.rb&lt;/code&gt;.&lt;/p&gt;


&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;15&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;r&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;SerializationOptions&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;serialization_options&lt;/span&gt;(options = {})&lt;tt&gt;
&lt;/tt&gt;    class_inheritable_accessor &lt;span class=&quot;sy&quot;&gt;:serialization_options&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;pc&quot;&gt;self&lt;/span&gt;.serialization_options = options.dup&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;co&quot;&gt;ActiveRecord&lt;/span&gt;::&lt;span class=&quot;co&quot;&gt;Base&lt;/span&gt;.send(&lt;span class=&quot;sy&quot;&gt;:extend&lt;/span&gt;, &lt;span class=&quot;co&quot;&gt;SerializationOptions&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;cl&quot;&gt;ActiveRecord::Serialization::Serializer&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  alias_method &lt;span class=&quot;sy&quot;&gt;:old_initialize&lt;/span&gt;, &lt;span class=&quot;sy&quot;&gt;:initialize&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;fu&quot;&gt;initialize&lt;/span&gt;(record, options = {})&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;if&lt;/span&gt; record.respond_to? &lt;span class=&quot;sy&quot;&gt;:serialization_options&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      options = record.serialization_options.merge(options)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    old_initialize(record, options)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class=&quot;r&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2007-09-27:104</id>
    <published>2007-09-27T03:42:00Z</published>
    <updated>2010-11-05T11:13:51Z</updated>
    <category term="css eleven wd07 andy clarke"/>
    <link href="http://www.atnan.com/2007/9/27/andy-clarke-announces-the-css-eleven-wd07" rel="alternate" type="text/html"/>
    <title>Andy Clarke Announces the "CSS Eleven" (WD07)</title>
<content type="html">
            &lt;p&gt;Opening session at Web Directions today was given to Andy Clarke, who proceeded to wrap it up with an announcement of a group put together to tackle the recent issues regarding submission of proposals and recommendations to the &lt;span class=&quot;caps&quot;&gt;W3C&lt;/span&gt;. The eleven involved are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Cameron Adams&lt;/li&gt;
		&lt;li&gt;Jina Bolton&lt;/li&gt;
		&lt;li&gt;Mark Boulton&lt;/li&gt;
		&lt;li&gt;Dan Cederholm&lt;/li&gt;
		&lt;li&gt;Andy Clarke&lt;/li&gt;
		&lt;li&gt;Jeff Croft&lt;/li&gt;
		&lt;li&gt;Aaron Gustafson&lt;/li&gt;
		&lt;li&gt;Jon Hicks&lt;/li&gt;
		&lt;li&gt;Roger Johansson&lt;/li&gt;
		&lt;li&gt;Richard Rutter&lt;/li&gt;
		&lt;li&gt;Jonathon Snook&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;From what was explained, their aim is to work through the &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; specifications and give feedback and examples for some of the more difficult issues, and then provide a body of work to the &lt;span class=&quot;caps&quot;&gt;W3C&lt;/span&gt; and/or browser vendors with the hope that it things along a little faster than is currently the case. More details are sure to appear on the &lt;a href=&quot;http://www.csseleven.com&quot;&gt;&lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; Eleven&lt;/a&gt; website.&lt;/p&gt;


	&lt;p&gt;Here&#8217;s a snap of his slide:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://www.atnan.com/assets/2007/9/27/CSS-Eleven-Announcement.jpg&quot;&gt;&lt;img src=&quot;http://www.atnan.com/assets/2007/9/27/CSS-Eleven-Announcement_medium.jpg&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2007-08-29:85</id>
    <published>2007-08-29T05:22:00Z</published>
    <updated>2010-11-05T11:12:06Z</updated>
    <category term="apple adobe flash player h.264 video"/>
    <link href="http://www.atnan.com/2007/8/29/adobe-made-their-move-now-it-s-apple-s-turn" rel="alternate" type="text/html"/>
    <title>Adobe Made Their Move, Now It's Apple's Turn</title>
<content type="html">
            &lt;p&gt;Despite the speculative bullshit that always seems to spout from &lt;a href=&quot;http://mailbox.allthingsd.com/20070705/questions-about-apples-iphone&quot;&gt;Walt Mossberg&lt;/a&gt; and &lt;a href=&quot;http://scobleizer.com/2007/07/06/apple-working-on-adobe-flash-support-for-iphone&quot;&gt;Robert Scoble&#8217;s&lt;/a&gt; mouths, we still don&#8217;t really know what&#8217;s driving Apple&#8217;s decision to not support Flash content on the iPhone. They&#8217;ve also removed the Flash content from their website, which leads me to believe that this issue runs far deeper than I previously thought.&lt;/p&gt;


	&lt;p&gt;Adobe&#8217;s &lt;a href=&quot;http://www.adobe.com/aboutadobe/pressroom/pressreleases/200708/082107FlashPlayer.html&quot;&gt;recent announcement&lt;/a&gt; of H.264/AAC support (among other things) in their Flash Player 9 product, has overnight turned Adobe&#8217;s Flash Player and Apple&#8217;s Quicktime Player into competing products. If you read &lt;a href=&quot;http://www.mainconcept.com/site/news-9/current-news-129/adobe.html&quot;&gt;between the lines&lt;/a&gt;, however, you might see something interesting:&lt;/p&gt;


&lt;blockquote&gt;&#8220;Adobe has licensed the x86, PowerPC and &lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;ARM&lt;/span&gt;&lt;/strong&gt; versions of MainConcept’s H.264 and &lt;span class=&quot;caps&quot;&gt;AAC&lt;/span&gt; decoders&#8221;&lt;/blockquote&gt;

	&lt;p&gt;Keyword, &lt;strong&gt;&#8220;ARM&#8221;&lt;/strong&gt;. Previously, Adobe have not had a Flash Player 9 &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; for the &lt;span class=&quot;caps&quot;&gt;ARM&lt;/span&gt; architecture. For this reason, products like the Opera Browser on the Nintendo Wii have needed to settle for Flash Player 7, or in the case of Apple&#8217;s iPhone they&#8217;ve decided not to settle at all and instead ignored support for Flash altogether. Now, it seems that Adobe might be planning on releasing an &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt; for the &lt;span class=&quot;caps&quot;&gt;ARM&lt;/span&gt; architecture since the H.264/AAC support only affects the version 9 product.&lt;/p&gt;


	&lt;p&gt;Once Adobe releases an &lt;span class=&quot;caps&quot;&gt;SDK&lt;/span&gt;, Apple will have the &lt;em&gt;means&lt;/em&gt; to support the plugin on the iPhone. As an added benefit, they won&#8217;t need to worry about licencing On2&#8217;s &lt;span class=&quot;caps&quot;&gt;VP6&lt;/span&gt; codec since the H.264 videos which currently play on the iPhone, iPod and iTV will also play within the Flash Player too. Not only that, but the annoucement from Adobe also mentions support for reading iTunes metadata (&#8220;list&#8221; atom) embedded in audio and video files.&lt;/p&gt;


&lt;blockquote&gt;Adobe are playing straight into Apple&#8217;s hands!&lt;/blockquote&gt;

	&lt;p&gt;So what&#8217;s Apple going to do about it? Should they embrace these changes and welcome Adobe with open arms? Keep in mind that according to the &lt;a href=&quot;http://labs.adobe.com/wiki/index.php/Flash_Player:9:Update:H.264&quot;&gt;Adobe &lt;span class=&quot;caps&quot;&gt;FAQ&lt;/span&gt;&lt;/a&gt;, &#8220;new releases of Flash Player take approximately 12 months to reach 90% penetration&#8221;. We&#8217;ll see this Flash Player in the wild as a release version sometime in September, so I expect Apple to have at least polarised by then.&lt;/p&gt;


	&lt;p&gt;I honestly hope that they chose to support the Flash Player. By doing so, they will put the power back in the hands of the content providors. While this doesn&#8217;t mean I expect them to re-instate Flash content on their own website, at least we&#8217;ll be left with a choice in the matter.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.atnan.com/">
    <author>
      <name>Nathan de Vries</name>
    </author>
    <id>tag:www.atnan.com,2007-06-19:62</id>
    <published>2007-06-19T14:41:00Z</published>
    <updated>2010-11-05T11:11:51Z</updated>
    <category term="ruby hpricot"/>
    <link href="http://www.atnan.com/2007/6/19/which-do-you-prefer-and-_why" rel="alternate" type="text/html"/>
    <title>Which Do You Prefer, And _Why?</title>
<content type="html">
            &lt;p&gt;This is in response to Greg Borenstein&#8217;s article titled &lt;a href=&quot;http://www.urbanhonking.com/ideasfordozens/archives/2007/06/a_beginners_gui.html&quot;&gt;A Beginner&#8217;s Guide to Practical Syntactic Magic: the tale of Hpricot&#8217;s sudo-constructor&lt;/a&gt; and Stuart Halloway&#8217;s follow-up article, &lt;a href=&quot;http://www.relevancellc.com/2007/6/13/with-great-power-comes-great-responsibility&quot;&gt;With great power comes great responsibility&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Both articles make reference to the odd method-naming tricks used in Why The Lucky Stiff&#8217;s &lt;a href=&quot;http://code.whytheluckystiff.net/hpricot/&quot;&gt;Hpricot&lt;/a&gt; library for parsing &lt;span class=&quot;caps&quot;&gt;XML&lt;/span&gt; (commonly &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt;). In light of those tricks, I have a question for you all&#8230;&lt;/p&gt;


	&lt;p&gt;Which of the following two snippets of code would you:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Prefer to read&lt;/li&gt;
		&lt;li&gt;Be inclined to write&lt;/li&gt;
	&lt;/ul&gt;


This:
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;doc = &lt;span class=&quot;co&quot;&gt;Hpricot&lt;/span&gt;.parse(open(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://www.atnan.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;title = doc.at(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;articles = doc.search(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.entry&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

Or this:
&lt;table class=&quot;CodeRay&quot;&gt;&lt;tr&gt;
  &lt;td title=&quot;click to toggle&quot; class=&quot;line_numbers&quot;&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class=&quot;code&quot;&gt;&lt;pre&gt;doc = Hpricot(open(&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;http://www.atnan.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;))&lt;tt&gt;
&lt;/tt&gt;title = doc % &lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;articles = doc/&lt;span class=&quot;s&quot;&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;.entry&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;

I&#8217;m interested in hearing your feedback in the comments below :)
          </content>  </entry>
</feed>
