<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title>P is for Programming</title>
	
	<link>http://www.jacopretorius.net</link>
	<description />
	<lastBuildDate>Tue, 14 May 2013 14:00:04 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/PForProgramming" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="pforprogramming" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Debugging CoffeeScript Line-by-Line</title>
		<link>http://www.jacopretorius.net/2013/05/debugging-coffeescript-line-by-line.html</link>
		<comments>http://www.jacopretorius.net/2013/05/debugging-coffeescript-line-by-line.html#comments</comments>
		<pubDate>Tue, 14 May 2013 14:00:04 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=960</guid>
		<description><![CDATA[One of the main arguments against using CoffeeScript is that of debugging. CoffeeScript is compiled down to JavaScript before being sent to the browser which means we can only debug the compiled JavaScript version of our code, not the original CoffeeScript. Until now, that is. Michael Ficarra&#8217;s successful kickstarter project to create a &#8216;better CoffeeScript [...]]]></description>
				<content:encoded><![CDATA[<p>One of the main arguments against using CoffeeScript is that of debugging.  CoffeeScript is compiled down to JavaScript before being sent to the browser which means we can only debug the compiled JavaScript version of our code, not the original CoffeeScript.  Until now, that is.</p>
<p>Michael Ficarra&#8217;s <a href="http://www.kickstarter.com/projects/michaelficarra/make-a-better-coffeescript-compiler">successful kickstarter project</a> to create a &#8216;better CoffeeScript compiler&#8217; now allows us to generate source maps for our CoffeeScript.  Google Chrome already supports source maps, which means you can now debug CoffeeScript right in the browser.</p>
<h4>Example</h4>
<p>Here is some very simple CoffeeScript that I&#8217;m going to try and debug.</p>
<pre class='brush: js;'>
eat = (food) ->
  console.log food

eat(food) for food in ['toast','cheese','wine'] when food isnt 'cheese'
</pre>
<p>I&#8217;m going to use the CoffeeScript compiler that is packaged through <a href="https://npmjs.org/">npm</a> to compile the example.  Version 1.6 (or later) has native support for source maps.</p>
<p>To compile with source maps, you simply need to pass the <strong>-m</strong> flag.</p>
<pre class='brush: bash;'>
coffee -cm example.coffee
</pre>
<p>This will generate 2 files &#8211; example.js and example.map.  More importantly, the compiler will put a comment in the JavaScript file to indicate to the browser where to find the source map file.</p>
<pre class='brush: js;'>
/*
//@ sourceMappingURL=example.map
*/
</pre>
<p>I created some very simple HTML to load my JavaScript.</p>
<pre class='brush: xml;'>
&lt;html&gt;
&lt;head&gt;
  &lt;script type='text/javascript' src='example.js'&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;Example of CoffeeScript Debugging&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The last step is to enable source maps in Google Chrome.  Open up the developer tools and look for the settings icon in the bottom right.</p>
<p><img src="https://lh3.googleusercontent.com/-f56X-1usTds/UYLCnj_9mvI/AAAAAAAAAro/yiFufvYun1E/w225-h144/Screen+Shot+2013-05-02+at+3.45.52+PM.jpg" alt="Source Maps Config" /></p>
<p>Now if you look in sources you should see your CoffeeScript file and be able to add break points, hover to view variables, etc.</p>
<p><img src="https://lh3.googleusercontent.com/-RhuMzxDF7lQ/UYLDeEi1BrI/AAAAAAAAArw/RcxrL7qH4-Y/w548-h168/Screen+Shot+2013-05-02+at+3.49.36+PM.jpg" alt="Debugging CoffeeScript" /></p>
<p>The problem of debugging CoffeeScript, the most popular and strongest argument for not using it in the browser, has been solved!  We still can&#8217;t type CoffeeScript into the console, but that day can&#8217;t be far off.  Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/debugging-coffeescript-line-by-line.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Create a Patch with Git</title>
		<link>http://www.jacopretorius.net/2013/05/how-to-create-a-patch-with-git.html</link>
		<comments>http://www.jacopretorius.net/2013/05/how-to-create-a-patch-with-git.html#comments</comments>
		<pubDate>Mon, 13 May 2013 14:00:48 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[SourceControl]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=953</guid>
		<description><![CDATA[Today I needed to transfer a few commits from my pair&#8217;s laptop to my own. Since git is a distributed source control system you can actually pull commits directly from any git repo (including someone&#8217;s local repo) &#8211; as you would from GitHub. Unfortunately this requires SSH access which we didn&#8217;t have on the (corporate) [...]]]></description>
				<content:encoded><![CDATA[<p>Today I needed to transfer a few commits from my pair&#8217;s laptop to my own.  Since git is a distributed source control system you can actually pull commits directly from any git repo (including someone&#8217;s local repo) &#8211; as you would from GitHub.  Unfortunately this requires SSH access which we didn&#8217;t have on the (corporate) network we were on.  I really wanted something simpler &#8211; I wanted to create a patch.</p>
<p>This is actually really easy to do with git.  Basically git allows us to use the result of a <strong>diff</strong> statement as a patch.  For example, if you have some local changes which are not yet committed you can run a simple <strong>&#8216;git diff&#8217;</strong> to see the changes.  If you want to package these changes as a patch you can simply pipe the result into a patch file.</p>
<pre class='brush: bash;'>
git diff > changes.patch
</pre>
<p>Now you can apply this patch to any other repo.</p>
<pre class='brush: bash;'>
git apply changes.patch
</pre>
<p>By modifying the <strong>diff</strong> statement it&#8217;s very easy to create the patch you want.  In my case I wanted to package the last 4 commits as a single patch.</p>
<pre class='brush: bash;'>
git diff HEAD~4 > changes.patch
</pre>
<p>Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/how-to-create-a-patch-with-git.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Amend Multiple Commit Messages with Git</title>
		<link>http://www.jacopretorius.net/2013/05/amend-multiple-commit-messages-with-git.html</link>
		<comments>http://www.jacopretorius.net/2013/05/amend-multiple-commit-messages-with-git.html#comments</comments>
		<pubDate>Fri, 10 May 2013 14:00:56 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[SourceControl]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=949</guid>
		<description><![CDATA[Today my pair and I were about to push multiple commits when I realized we had forgotten to add the story number to all of the commit messages. Basically when I was looking at my git log: git log --oneline I would see something like the following. e16f24e Fourth Commit b4bbd67 Third Commit 57a2ca3 Second [...]]]></description>
				<content:encoded><![CDATA[<p>Today my pair and I were about to push multiple commits when I realized we had forgotten to add the story number to all of the commit messages.  Basically when I was looking at my git log:</p>
<pre class='brush: bash;'>
git log --oneline
</pre>
<p>I would see something like the following.</p>
<pre class='brush: bash;'>
e16f24e Fourth Commit
b4bbd67 Third Commit
57a2ca3 Second Commit
3790b98 First Commit
</pre>
<p>Our usual convention is to add the story number to the commit message.  I knew that I could amend a single commit with &#8216;git commit &#8211;amend&#8217;, but I&#8217;ve never had to rewrite the git history like this.</p>
<p>To do this, we need to do an interactive rebase.</p>
<pre class='brush: bash;'>
git rebase -i HEAD~5
</pre>
<p>Git will now show you the commits you specified &#8211; the last 5 in my case &#8211; in <strong>reverse</strong> order.</p>
<pre class='brush: bash;'>
pick a8b8553 Previous commit message
pick 3790b98 First Commit
pick 57a2ca3 Second Commit
pick b4bbd67 Third Commit
pick e16f24e Fourth Commit
</pre>
<p>You now need to specify the commits you wish to edit &#8211; in my case this was the last four commits.</p>
<pre class='brush: bash;'>
pick a8b8553 Previous commit message
e 3790b98 First Commit
e 57a2ca3 Second Commit
e b4bbd67 Third Commit
e e16f24e Fourth Commit
</pre>
<p>Git will now step through each of the commits you specified and ask you to make your changes.</p>
<pre class='brush: bash;'>
Stopped at 3790b98... First Commit
You can amend the commit now, with

        git commit --amend

Once you are satisfied with your changes, run

        git rebase --continue
</pre>
<p>In my case I simply needed to <strong>amend</strong> each commit to change the commit message.</p>
<pre class='brush: bash;'>
git commit --amend
</pre>
<p>After the message is changed you need to tell git to <strong>continue</strong>.</p>
<pre class='brush: bash;'>
git rebase --continue
</pre>
<p>Do this for each commit and your history is rewritten!</p>
<pre class='brush: bash;'>
90644d6 [Story #15] Fourth Commit
87006ff [Story #15] Third Commit
83de86b [Story #15] Second Commit
d35b899 [Story #15] First Commit
</pre>
<p>Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/amend-multiple-commit-messages-with-git.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Custom Sorting in AngularJS</title>
		<link>http://www.jacopretorius.net/2013/05/custom-sorting-in-angularjs.html</link>
		<comments>http://www.jacopretorius.net/2013/05/custom-sorting-in-angularjs.html#comments</comments>
		<pubDate>Thu, 09 May 2013 14:00:45 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=942</guid>
		<description><![CDATA[Today I had to implement custom sorting in AngularJS. As with most things in Angular it&#8217;s very simple once you figure out how. AngularJS has an orderBy function which can be used to sort a list of objects by any property. A common use case is when we want to sort by one of a [...]]]></description>
				<content:encoded><![CDATA[<p>Today I had to implement custom sorting in AngularJS.  As with most things in Angular it&#8217;s very simple once you figure out how.</p>
<p>AngularJS has an <a href="http://docs.angularjs.org/api/ng.filter:orderBy">orderBy function</a> which can be used to sort a list of objects by any property.  A common use case is when we want to sort by one of a few pre-determined sort orders.</p>
<h4>Sort by a Property</h4>
<p>As an example, let&#8217;s create a list of contacts.</p>
<pre class='brush: js;'>
function ContactListCtrl($scope){
  $scope.contacts = 
  [
    { "name":"Richard", "surname":"Stallman", "telephone":"1234 98765" },
    { "name":"Linus", "surname":"Torvalds", "telephone":"2345 87654" },
    { "name":"Donald", "surname":"Knuth", "telephone":"3456 76543" }
  ];
};
</pre>
<p>I can now easily display these contacts in a table by using the <strong>ng-repeat</strong> directive.</p>
<pre class='brush: xml;'>
&lt;table class="contacts"&gt;
  &lt;tr&gt;
    &lt;th&gt;Name&lt;/th&gt;
    &lt;th&gt;Telephone&lt;/th&gt;
  &lt;/tr&gt;

  &lt;tr ng-repeat="contact in contacts"&gt;
    &lt;td ng-class-even="'even'"&gt;{{contact.name}}, {{contact.surname}}&lt;/td&gt;
    &lt;td ng-class-even="'even'"&gt;{{contact.telephone}}&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
</pre>
<p>Now let&#8217;s add a <strong>select</strong> with 2 different sort options.  As per <a href="http://docs.angularjs.org/api/ng.filter:orderBy">the documentation</a>, we can specify a property to sort by and optionally a + or &#8211; to specify ascending or descending.</p>
<pre class='brush: xml;'>
&lt;select ng-model="sortorder"&gt;
  &lt;option value="+surname"&gt;Surname (A-Z)&lt;/option&gt;
  &lt;option value="-surname"&gt;Surname (Z-A)&lt;/option&gt;
&lt;/select&gt;
</pre>
<p>Because we are using <strong>ng-model</strong> here we also need to specify a default sort order in our controller.</p>
<pre class='brush: js;'>
$scope.sortorder = 'surname';
</pre>
<p>Now we simply need to specify the <strong>orderBy</strong> clause in the <strong>ng-repeat</strong> directive.</p>
<pre class='brush: xml;'>
&lt;tr ng-repeat="contact in contacts | orderBy:sortorder"&gt;
</pre>
<p>You can see the full example in this <a href="http://jsfiddle.net/vjF2D/">jsFiddle</a>.</p>
<h4>Sort with a Custom Function</h4>
<p>The documentation also says that we can sort using a function instead of a simply property.  Let&#8217;s see how that would work.</p>
<p>I&#8217;m going to use the same HTML and contacts as before, but I&#8217;m going to change the <strong>ng-repeat</strong> directive to the following:</p>
<pre class='brush: xml;'>
&lt;tr ng-repeat="contact in contacts | orderBy:randomSort"&gt;
</pre>
<p>Now I&#8217;m going to implement a function called randomSort which will be used to sort the objects.</p>
<pre class='brush: js;'>
$scope.randomSort = function(contact) {
  return Math.random();
};
</pre>
<p>The function takes a single parameter &#8211; a contact object.  The value you return here will be used to sort on, so you could combine any properties on the contact object to do the sorting.</p>
<p>You can see the full example in this <a href="http://jsfiddle.net/q6kv7/">jsFiddle</a>.  Every time you run the example you should see a different sort order.</p>
<h4>Sort by a List of Properties</h4>
<p>The documentation also says that we can sort by a list of properties.  I&#8217;m going to modify my original example to sort by surname first and name second.</p>
<p>Again, I&#8217;m going to change the <strong>ng-repeat</strong> directive to specify an array of properties.</p>
<pre class='brush: xml;'>
&lt;tr ng-repeat="contact in contacts | orderBy:['surname','name']"&gt;
</pre>
<p>That&#8217;s all we need to do.  You can see the full example in this <a href="http://jsfiddle.net/Teabf/">jsFiddle</a>.</p>
<p>As with most things in Angular, sorting is very simple once you figure out how.  Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/custom-sorting-in-angularjs.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>C99 Initializer Syntax in Objective C</title>
		<link>http://www.jacopretorius.net/2013/05/c99-initializer-syntax-in-objective-c.html</link>
		<comments>http://www.jacopretorius.net/2013/05/c99-initializer-syntax-in-objective-c.html#comments</comments>
		<pubDate>Wed, 08 May 2013 14:00:39 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[iOS]]></category>
		<category><![CDATA[Objective-C]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=937</guid>
		<description><![CDATA[This week a colleague sent me a snippet of Objective-C syntax I had never seen before. self.imageView.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size}; This is (apparently) called C99 Initializer Syntax. This type of syntax can be used to initialize any struct in C (and Objective C) which is especially useful when working with CGRect and CGPoint. The [...]]]></description>
				<content:encoded><![CDATA[<p>This week a colleague sent me a snippet of Objective-C syntax I had never seen before.</p>
<pre class='brush: oc;'>
self.imageView.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size};
</pre>
<p>This is (apparently) called <a href="http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Flanguage%2Fref%2Fstrin.htm">C99 Initializer Syntax</a>.  This type of syntax can be used to initialize any struct in C (and Objective C) which is especially useful when working with CGRect and CGPoint.</p>
<h4>The Syntax</h4>
<p>Let&#8217;s take a look at the standard way of defining a CGRect.</p>
<pre class='brush: oc;'>
CGRect frame = CGRectMake(60, 80, 200, 300);
</pre>
<p>I&#8217;ve never really thought about this, but the syntax only makes sense if you already know the order of the parameters and what they mean.  This is not really an issue with CGRectMake &#8211; since you use this so often it&#8217;s impossible <em>not</em> to know the parameters &#8211; but it&#8217;s not ideal.</p>
<p>Take a look at the equivalent in C99 syntax.</p>
<pre class='brush: oc;'>
CGRect frame = (CGRect){
    .origin.x = 60, 
    .origin.y = 80, 
    .size.width = 200, 
    .size.height = 300
};
</pre>
<p>This is much more readable and would be especially helpful if you were passing expressions instead of contants.</p>
<pre class='brush: oc;'>
CGRect frame = (CGRect){
    .origin.x = (x / 2) + 60, 
    .origin.y = (y / 2) + 80,
    .size.width = x * 2, 
    .size.height = y * 2
};
</pre>
<p>What&#8217;s really nice about this syntax is that it&#8217;s not only more readable, it&#8217;s actually a bit safer.  We can also write the following:</p>
<pre class='brush: oc;'>
CGRect frame = (CGRect){
    .size.width = 200, 
    .size.height = 300,
    .origin.x = 60, 
    .origin.y = 80
};
</pre>
<p>We can also change the order of the parameters in the original struct without having to change this code.  Obviously I&#8217;m not expecting the definition of CGRect to change, but it could be useful for your own structs or those of a library.  (Remember that this syntax works for <em>all</em> structs)</p>
<p>The best usage of this syntax (in my opinion) is for when we want to specify the size or origin as a single value.  For example, it&#8217;s not uncommon to do something like this:</p>
<pre class='brush: oc;'>
CGRect frame = CGRectMake(
    self.view.frame.origin.x, 
    self.view.frame.origin.y, 
    200, 
    300
);
</pre>
<p>However, with the C99 syntax we can now write this:</p>
<pre class='brush: oc;'>
CGRect frame = (CGRect){
    .origin = self.view.frame.origin, 
    .size.width = 200, 
    .size.height = 300
};
</pre>
<p>Which is definitely much more readable.</p>
<h4>Default Values</h4>
<p>Any parameters which are not specified will default to zero.  So the following statements are actually equivalent.</p>
<pre class='brush: oc;'>
CGPoint point = (CGPoint){.x = 0,.y = 0};
CGPoint point = (CGPoint){};
</pre>
<p>Using this syntax we can actually rewrite the original snippet I was looking at:</p>
<pre class='brush: oc;'>
self.imageView.frame = (CGRect){.size=image.size};
</pre>
<p>Pretty neat.</p>
<h4>Actual Usage</h4>
<p>C99 Syntax can definitely be helpful in the right situation.  Used correctly it can improve readability, used incorrectly it can make your code overly verbose.</p>
<p>Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/c99-initializer-syntax-in-objective-c.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mobile Web versus Native Apps</title>
		<link>http://www.jacopretorius.net/2013/05/mobile-web-versus-native-apps.html</link>
		<comments>http://www.jacopretorius.net/2013/05/mobile-web-versus-native-apps.html#comments</comments>
		<pubDate>Tue, 07 May 2013 14:00:38 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[HTML5]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=921</guid>
		<description><![CDATA[The topic of mobile web versus native apps comes up quite often. The typical scenario is that of a company who already has a web presence and wants to bridge the gap to be more engaging to mobile users. The challenge is then to decide which platform (or platforms) to support. The company is now [...]]]></description>
				<content:encoded><![CDATA[<p>The topic of mobile web versus native apps comes up quite often.  The typical scenario is that of a company who already has a web presence and wants to bridge the gap to be more engaging to mobile users.  The challenge is then to decide which platform (or platforms) to support.</p>
<p>The company is now left with the decision of native versus mobile web (which includes embedded web implementations such as <a href="http://phonegap.com/">PhoneGap</a>).</p>
<h4>The Argument for Mobile Web</h4>
<p>There are 2 scenarios where a mobile web approach is often seen as more appropriate:</p>
<ul>
<li>Multiple platforms need to be supported (iPhone and Android, for example)</li>
<li>There is already an existing web platform which can be leveraged in a mobile effort</li>
</ul>
<p>The mobile web approach also offers several advantages over a native approach.</p>
<p>Possibly the greatest advantage is having a single codebase to maintain.  One codebase, one technology stack.  This also offers the implicit advantage that a single team of developers would be able to maintain the entire mobile codebase.  Even better, web developers can often be skilled up in mobile web development pretty easily making resourcing less of a problem.</p>
<p>Another advantage is the ability to apply updates instantly to all users, even multiple times per day.  Facebook engineering manager Dave Fetterman described the approach at f8, Facebook’s developer conference, in 2011:</p>
<blockquote><p>Being able to write it once today and ship it tomorrow? That is something that Facebook is really good at and that we love doing, and that is at the center of being able to move fast. Move fast has an implicit third clause &#8211; move fast, break things, and fix things fast. That is very difficult to do if you have already shipped your binary to Apple or Android and they have to download another version of it.</p>
</blockquote>
<p>The technologies involved in building a mobile web experience are also very popular at the moment.  HTML5 is a massive buzzword and JavaScript frameworks are numerous &#8211; all making the mobile web approach very attractice.</p>
<h4>The Argument for Native Support</h4>
<p>With all the advances being made in HTML5 and JavaScript you would almost expect native apps to become less popular.  But that hasn&#8217;t quite been the case.</p>
<p>This month <a href="http://venturebeat.com/2013/04/17/linkedin-mobile-web-breakup/">LinkedIn became the latest company</a> to publicly switch from a mobile web to native approach.  <a href="http://readwrite.com/2012/08/23/how-facebook-ditched-the-mobile-web-went-native-with-its-new-ios-app">FaceBook&#8217;s switch to a native</a> iOS platform is also well-documented.  FaceBook CEO Mark Zuckerberg even went so far as to say the mobile web approach was <a href="http://money.cnn.com/2013/04/11/technology/facebook-zuckerberg-home.pr.fortune/index.html">&#8220;one of the biggest mistakes [FaceBook] ever made&#8221;</a>.</p>
<p>There are several reasons why I think a native approach is superior and will remain superior for the foreseeable future.</p>
<p>The first and foremost is the user experience.  No matter how much effort is made to the contrary, the mobile web experience is simply not nearly as good as the native counterpart.  Mobile web applications often try to mimic a native application, but I have found that you will very quickly reach the limits of the technology.</p>
<p>The second reason is platform conventions.  Each mobile platform &#8211; iOS, Android, BlackBerry, Windows Phone &#8211; has it&#8217;s own convention in terms of what UI elements (buttons, toolbars, etc) look like how interactions (transitions, popups, etc) work.  This is typically what gives each platform it&#8217;s unique flavor and while it&#8217;s possible to mimic this (to a certain extent) for a specific platform it&#8217;s incredibly difficult (or maybe impossible) to do so for multiple platforms.  For example, if we try and mimic an iPhone application with our mobile web approach the app will look and feel broken to an Android user.</p>
<p>The bottom line is that a native approach leads to a better user experience.  It&#8217;s difficult to argue with this.</p>
<h4>Asking the Right Questions</h4>
<p>There are obviously still scenarios where a mobile web approach makes sense.  For example, if you&#8217;re reading this blog on your phone you&#8217;re doing so on a <a href="http://www.jacopretorius.net/2013/04/a-responsive-redesign.html">responsive design</a>.  I can think of several websites which are optimized for mobile devices and work very well &#8211; <a href="http://www.amazon.com/?tag=pisforprog-20">Amazon</a>, <a href="http://www.cnn.com/">CNN</a>, <a href="http://www.kayak.com/">Kayak</a>, etc.</p>
<p>There are some good questions to ask when deciding between a mobile web and native approach.</p>
<p><strong>Do we really need to support multiple platforms?</strong>  This seems like an obvious question, but I&#8217;ve been surprised by how many times the answer is no.  For example, a client may simply want to be able to showcase the web application on an iPad.  If the answer is no, the argument for a native application becomes much stronger.</p>
<p><strong>How important is the offline experience?</strong>  It&#8217;s important here to understand the common connectivity scenario for users &#8211; will the app be used on the subway or in areas where there is limited network connectivity?  Or will the app only be used in an office setting where a strong wifi connection is always available?  The more important the offline experience, the stronger the argument for a native implementation.</p>
<p>When thinking of mobile, think audience first, and determine what’s most valuable: the convenience of the web or the robustness of an app.  Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/mobile-web-versus-native-apps.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>10 CoffeeScript Features You Might Not Know</title>
		<link>http://www.jacopretorius.net/2013/05/10-coffeescript-features-you-might-not-know.html</link>
		<comments>http://www.jacopretorius.net/2013/05/10-coffeescript-features-you-might-not-know.html#comments</comments>
		<pubDate>Mon, 06 May 2013 14:00:04 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=915</guid>
		<description><![CDATA[This week I&#8217;ve spent some time researching different CoffeeScript resources to be used for training at a client. In the process I&#8217;ve discover a few CoffeeScript features that I didn&#8217;t know about or are not that well known. Iterations You probably know the standard way of iterating through a list in CoffeeScript. for name in [...]]]></description>
				<content:encoded><![CDATA[<p>This week I&#8217;ve spent some time researching different CoffeeScript resources to be used for training at a client.  In the process I&#8217;ve discover a few CoffeeScript features that I didn&#8217;t know about or are not that well known.</p>
<h4>Iterations</h4>
<p>You probably know the standard way of iterating through a list in CoffeeScript.</p>
<pre class='brush: js;'>
for name in ['Tom','Dick','Harry']
  alert "Hi, #{name}"
</pre>
<p>But did you know that by passing an extra argument, you can also get the current iteration index?</p>
<pre class='brush: js;'>
for name, i in ['Tom','Dick','Harry']
  alert "Hi, #{name} - you are number #{i}"
</pre>
<h4>Splatting</h4>
<p>JavaScript (and therefore CoffeeScript) doesn&#8217;t enforce that you pass the correct number of parameters to a function.  In this example the last few parameters will just get dropped.</p>
<pre class='brush: js;'>
planets = (first, second, third) ->
  alert third
  
planets 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter'
# alert will be 'Earth'
</pre>
<p>But did you know that CoffeeScript supports splatting?</p>
<pre class='brush: js;'>
planets = (first, second, others...) ->
  alert others

planets 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter'
# alert will be 'Earth','Mars','Jupiter'
</pre>
<h4>Comprehensions</h4>
<p>CoffeeScript also supports comprehensions &#8211; a little bit like the map function in Ruby.</p>
<pre class='brush: js;'>
class Person
  constructor: (name, email) ->
    @name = name
    @email = email

userEmails =
  tom: 'tom@example.com'
  dick: 'dick@example.com'
  harry: 'harry@example.com'

contacts = for name, email of userEmails
  new Person(name,email)
</pre>
<h4>Destructuring Assignment</h4>
<p><em>Destructuring Assignment</em> is just a fancy way of saying we can assign multiple variables at once.  You can use it to switch the value of two variables in a single line.</p>
<pre class='brush: js;'>
one = 1
two = 2
[one, two] = [two, one]
</pre>
<p>You can also use this to assign variables to the result of a function.</p>
<pre class='brush: js;'>
date = ->
  [25,'April',2013]

[day, month, year] = date()
</pre>
<p>It even works with deeply nested objects!</p>
<pre class='brush: js;'>
person =
  name: 'John'
  email: 'john@example.com'
  address:
    street: [
      '123 Main Street'
      'Apt 8B'
    ]
    city: 'Gotham'
    zip: '8442'

{ address: { street: [_, apartment], city } } = person
</pre>
<h4>Destructuring Assignment combined with Splatting</h4>
<p>Destructuring Assignment also works when combined with Splatting, which gives you another powerful way of dealing with arrays of variable length.</p>
<pre class='brush: js;'>
daysOfTheWeek = "Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday"

[first, rest..., last] = daysOfTheWeek.split ','
</pre>
<h4>Chained Comparisons</h4>
<p>CoffeeScript also allows us to do Chained Comparisons (borrowed from Python) &#8211; which allows us to easily test if a value fall within a certain range.</p>
<pre class='brush: js;'>
temperature = 72
niceDay = 82 > temperature > 68
</pre>
<h4>Block Strings</h4>
<p>You probably know that CoffeeScript supports string interpolation (using the same syntax as Ruby).</p>
<pre class='brush: js;'>
name = "John"
surname = "Doe"

greeting = "Hi, #{name} #{surname}"
</pre>
<p>But did you know that JavaScript supports block strings?  This is very useful for formatted or indentation-sensitive text.  The indentation level that begins the block is maintained throughout, so you can keep it all aligned with the body of your code.</p>
<pre class='brush: js;'>
html = """
       &lt;p&gt;
       Hi, #{name} #{surname}
       &lt;/p&gt;
       """
</pre>
<h4>Prototype Shorthand</h4>
<p>You probably know that @ is the shorthand for accessing <em>this</em> in CoffeeScript.  But did you know that CoffeeScript has a similar shorthand for accessing the prototype of a class?</p>
<pre class='brush: js;'>
String::pipeDelimited = ->
  @split '|'

alert "ABC|abc".pipeDelimited()
</pre>
<h4>Binding Parameters to Properties</h4>
<p>CoffeeScript allows us to bind parameters to properties directly by using the @ shorthand.  For example, you often want to set properties in the constructor.</p>
<pre class='brush: js;'>
class Person
  constructor: (name) ->
    @name = name
</pre>
<p>But we can just bind this property in the function declaration.  CoffeeScript is the only language that I know of that allows you to do this.</p>
<pre class='brush: js;'>
class Person
  constructor: (@name) ->
</pre>
<h4>Class/Static Functions</h4>
<p>The @ shorthand also allows us to define class functions.</p>
<pre class='brush: js;'>
class Number
  @random: ->
    return 4  # chosen by fair dice roll
              # guaranteed to be random
              
alert Number.random()
</pre>
<p>My random implementation is a <a href="http://xkcd.com/221/">reference to XKCD</a>.</p>
<p>Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/10-coffeescript-features-you-might-not-know.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resources for Learning CoffeeScript</title>
		<link>http://www.jacopretorius.net/2013/05/resources-for-learning-coffeescript.html</link>
		<comments>http://www.jacopretorius.net/2013/05/resources-for-learning-coffeescript.html#comments</comments>
		<pubDate>Fri, 03 May 2013 14:00:48 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[CoffeeScript]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=906</guid>
		<description><![CDATA[CoffeeScript is a little language that compiles down to JavaScript. I&#8217;m a big fan of JavaScript, but it&#8217;s definitely a very quirkly language. CoffeeScript eliminates some of those quirks and brings JavaScript&#8217;s syntax more in line with languages like Ruby and Python. The Little Book on CoffeeScript If you&#8217;re just starting out with CoffeeScript a [...]]]></description>
				<content:encoded><![CDATA[<p>CoffeeScript is a little language that compiles down to JavaScript.  I&#8217;m a big fan of JavaScript, but it&#8217;s definitely a very quirkly language.  CoffeeScript eliminates some of those quirks and brings JavaScript&#8217;s syntax more in line with languages like Ruby and Python.</p>
<h4>The Little Book on CoffeeScript</h4>
<p>If you&#8217;re just starting out with CoffeeScript a great resource is <a href="http://arcturo.github.io/library/coffeescript/index.html">The Little Book on CoffeeScript</a>.  This book will only take about an hour to read but will step you through the ideas behind CoffeeScript, the syntax, compilation and common pitfalls.  It&#8217;s a great resource and it&#8217;s <em>free</em>.</p>
<h4>Js2coffee</h4>
<p>Next up you&#8217;ll probably want to start playing around with CoffeeScript.  <a href="http://js2coffee.org/">Js2coffee</a> is a great resource here &#8211; it allows you to convert regular JavaScript files to their CoffeeScript equivalents.  This is an excellent sandbox where you can see the difference between JavaScript and CoffeeScript.</p>
<p>Js2coffee is also available as a NodeJS module &#8211; this is particularly useful if you&#8217;re migrating a project from JavaScript to CoffeeScript.</p>
<pre class='brush: bash;'>
$ npm install js2coffee
$ js2coffee file.js > file.coffee
</pre>
<h4>CodeSchool</h4>
<p>If you&#8217;re looking a bit more structure to your CoffeeScript learning head over to <a href="http://coffeescript.codeschool.com/">CodeSchool</a>.  They have a 6-part series titled &#8216;A sip of CoffeeScript&#8217; that guides through all the syntax and pitfalls of CoffeeScript.</p>
<p>I especially like this series because it really covers <em>all</em> of CoffeeScript.  This is another great resource and it&#8217;s free to members.</p>
<h4>CoffeeScript.org</h4>
<p>The last resource for learning CoffeeScript is &#8211; no surprise &#8211; the <a href="http://coffeescript.org/">official CoffeeScript website</a>.  Here you will find documentation for the NPM CoffeeScript module as well as an in-depth breakdown of CoffeeScript syntax.</p>
<p>CoffeeScript is a great language and it&#8217;s definitely worth it (and easy) to learn.  Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/resources-for-learning-coffeescript.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Switching to Mac – Two Years Later</title>
		<link>http://www.jacopretorius.net/2013/05/switching-to-mac-two-years-later.html</link>
		<comments>http://www.jacopretorius.net/2013/05/switching-to-mac-two-years-later.html#comments</comments>
		<pubDate>Thu, 02 May 2013 14:00:42 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[OSX]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=893</guid>
		<description><![CDATA[Two years ago I became a Mac user. It was a pretty bold move for me at the time. At that point I had been doing mainly C# development for almost 5 years &#8211; all of it on Windows. It was the combination of great hardware and software that convinced me to take the plunge [...]]]></description>
				<content:encoded><![CDATA[<p>Two years ago I became a Mac user.</p>
<p>It was a pretty bold move for me at the time.  At that point I had been doing mainly C# development for almost 5 years &#8211; all of it on Windows.  It was the combination of great hardware and software that convinced me to take the plunge and switch to the Mac platform.</p>
<p>I was in the market for a new laptop and the MacBook Pro was a very attractive prospect &#8211; both because of the aesthetics and because the hardware is so well-balanced.  More importantly, I had been working on a Dell for the previous two years and I couldn&#8217;t stomach the thought of continuing in the same direction.</p>
<p>This was also at a time when I wanted to get serious about Ruby development.  I had done quite a bit of Ruby already, but I was getting increasingly frustrated by the experience on Windows.  Most of the tools were barely supported on Windows and the community was also heavily focused on the Mac/Unix platforms.</p>
<p>I&#8217;m going to look at 3 categories of use for my laptop &#8211; as a development environment, as a general workstation and for gaming.</p>
<h4>Development Environment</h4>
<p>The Mac is the most versatile development environment available.  I feel pretty confident in this statement &#8211; the only real contender here is Unix, but OSX is required for iOS development.  In the past two years I have done Ruby, Rails, JavaScript, Python, Haskell and iOS development on my MacBook.  I even did 6 months of C# development via Bootcamp!</p>
<p>In my experience the performance on a Windows machine will generally degrade over time.  The more applications you install, the slower it gets.  OSX doesn&#8217;t seem to suffer from the same problems.  Startup time is still lightning fast &#8211; on the rare occasions that I do need to restart.  I also don&#8217;t miss the 5-minute startup time on Visual Studio.</p>
<h4>General Workstation</h4>
<p>Apart from doing development there is obviously a multitude of other tasks I do on my laptop &#8211; blogging, reading, watching movies, listening to music, online chat, etc.  Ten years ago you might have struggled to find OSX-versions of some of the software you use, but not today.  Even Microsoft Office is available on OSX &#8211; and works really well too!</p>
<p>The only culprit (that I can think of) is Skype.  Skype for OSX is simply terrible &#8211; and unfortuntely every update seems to make it worse.  Perhaps Microsoft believes that at some point we will all abandon OSX in order to use Skype on Windows.</p>
<h4>Gaming</h4>
<p>I&#8217;m not a very avid gamer, but I still like to kick back and kill some monsters once in a while.  Luckily for me my favourite game is Diablo 3 &#8211; which is available on OSX.  Unfortunately for pretty much everything else you need to use Windows.  I don&#8217;t think I would recommend a MacBook Pro to a hardcore gamer.</p>
<h4>My Next Laptop</h4>
<p>My next laptop will be a 15&#8243; MacBook Pro Retina.  No doubt about it.  I know it&#8217;s an expensive machine, but in my experience it&#8217;s worth it.  I can&#8217;t even imagine using anything else.</p>
<p>Two years ago I became a Mac user.  I&#8217;ve never looked back.  Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/switching-to-mac-two-years-later.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Top Reads for April</title>
		<link>http://www.jacopretorius.net/2013/05/top-reads-for-april.html</link>
		<comments>http://www.jacopretorius.net/2013/05/top-reads-for-april.html#comments</comments>
		<pubDate>Wed, 01 May 2013 14:00:09 +0000</pubDate>
		<dc:creator>Jaco Pretorius</dc:creator>
				<category><![CDATA[TopReads]]></category>

		<guid isPermaLink="false">http://www.jacopretorius.net/?p=889</guid>
		<description><![CDATA[I do a lot of reading. Most of what I read comes from a combination of Twitter, Hacker News, Reddit and a long list of blogs in my RSS feed. (My RSS feed obviously includes quite a few aggregate feeds as well, such as ThoughtBlogs and Alvin Ashcraf&#8217;s Morning Dew) The result is that I [...]]]></description>
				<content:encoded><![CDATA[<p>I do a lot of reading.  Most of what I read comes from a combination of Twitter, Hacker News, Reddit and a long list of blogs in my RSS feed.  (My RSS feed obviously includes quite a few aggregate feeds as well, such as <a href="http://www.thoughtworks.com/blogs">ThoughtBlogs</a> and <a href="http://www.alvinashcraft.com/">Alvin Ashcraf&#8217;s Morning Dew</a>)</p>
<p>The result is that I go through quite a few articles in a month.  This blog post is my attempt at highlighting the best ones I&#8217;ve read in the past month.  &#8216;Best&#8217; in this context could mean quite a few things &#8211; interesting, thought-provoking, funny or a cool new open source project.  This is my first attempt at creating such an aggregate &#8211; only time will tell if I can make it into a monthly post.</p>
<p>So here are the top things I read in April.</p>
<ul>
<li><a href="http://www.daedtech.com/comments-heres-my-code-and-im-sorry">Comments: Here&#8217;s my code and I&#8217;m sorry</a></li>
<li><a href="http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx">Video Tutorial: AngularJS Fundamentals in 60-ish Minutes</a></li>
<li><a href="http://blog.teamleadnet.com/2013/04/interviewing-bad-practices.html">How not to do Interviews</a></li>
<li><a href="http://www.youtube.com/watch?v=Il4swGfTOSM">Video by a Google Engineer about what it takes to render a web page in under 1 second</a></li>
<li><a href="http://stackoverflow.com/questions/234075/what-is-your-best-programmer-joke">What is your best programmer joke?</a></li>
<li><a href="http://theosom.com/p/k9HI">The Trick To Good Software</a></li>
<li><a href="http://highscalability.com/blog/2013/4/15/scaling-pinterest-from-0-to-10s-of-billions-of-page-views-a.html">Pinterest &#8211; Scaling from 0 to 10s of Billions of Page Views a Month in Two Years</a></li>
<li><a href="http://sporto.github.io/blog/2013/04/12/comparison-angular-backbone-can-ember/">A Comparison of Angular, Backbone, CanJS and Ember</a></li>
<li><a href="http://www.codeproject.com/Articles/571408/The-Star-Wars-intro-in-pure-CSS3-thanks-to-3D-tran">Star Wars Intro in Pure CSS</a></li>
<li><a href="http://www.forbes.com/sites/danschawbel/2013/03/29/david-heinemeier-hansson-every-employee-should-work-from-home/">DHH: Every employee should work from home</a></li>
<li><a href="http://www.yearofmoo.com/2012/11/angularjs-and-seo.html">AngularJS and SEO</a></li>
</ul>
<p>Happy coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jacopretorius.net/2013/05/top-reads-for-april.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
