<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>Stoat - Where? &#187; LinkedIn</title>
	<atom:link href="http://jamietalbot.com/tag/linkedin/feed/" rel="self" type="application/rss+xml" />
	<link>http://jamietalbot.com</link>
	<description>Adventures in Engrish</description>
	<lastBuildDate>Sat, 29 Oct 2011 05:14:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Facebook Engineer Fired For Using Facebook Way Too Much At Work.</title>
		<link>http://jamietalbot.com/2011/06/15/facebook-engineer-fired-for-using-facebook-way-too-much-at-work/</link>
		<comments>http://jamietalbot.com/2011/06/15/facebook-engineer-fired-for-using-facebook-way-too-much-at-work/#comments</comments>
		<pubDate>Wed, 15 Jun 2011 21:34:12 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Humour?]]></category>
		<category><![CDATA[Facebook]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Satire]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=1108</guid>
		<description><![CDATA[A cautionary tale for those of you addicted to social networks.]]></description>
			<content:encoded><![CDATA[<p><em>Palo Alto, California.</em></p>
<p>A Facebook engineer has been fired for using Facebook too much at work.  </p>
<p>&#8220;It was ridiculous&#8221;, an anonymous source (who promised he wasn&#8217;t the employee&#8217;s direct manager) said.  &#8220;He was on it 24&#215;7.  Now, we&#8217;re a very tolerant company.  You have to be with these Gen-Y types.  I use it myself.  Well, uh, occasionally&#8221;, he added hastily.</p>
<p>&#8220;I know the importance of staying in touch with your friends and family, but he was jerking us around.</p>
<p>&#8220;He claimed to be researching the user interface, but all I could see was him chatting to his college buddies.  When I challenged him on it, he even rearranged his desk so I couldn&#8217;t see his screen!  Luckily, he was a Facebook friend, so I could see him on Facebook Chat.  I, uh, we had to let him go.  What?  No, I wasn&#8217;t his manager, I promise.&#8221;</p>
<p>Despite strong protests, James Greaves, 28, originally from Brentwood, Tennessee, was unable to save his job.</p>
<p>This was not the first time Jimmy had had problems with Facebook at Facebook.  &#8220;I was a bit foolish&#8221;, he admitted.  &#8220;When I was offered the job, I forgot to tell them I was best man for a wedding soon after I was supposed to start.  I called in sick so I could go to the bachelor party and then again the day after, but a groomsman checked me in on Facebook Places at <em>Aphrodite Nights</em> and then tagged photos of me half-naked and licking cake off a stripper.</p>
<p>&#8220;That was a hard one to explain&#8221;, he sighed.</p>
<p>&#8220;It&#8217;s ironic&#8221;, he continued.  &#8220;I actually pushed an update to the tagging functionality just a couple of days before that &#8211; my first piece of useful work.  My mate even mentioned how easy it was for him to do all the tagging in one place.  He probably wouldn&#8217;t have bothered otherwise.&#8221;</p>
<p>Jimbo had been at the company 6 months since joining from Google, where he was let go for not using Google enough.  &#8220;I was searching for information on &#8216;binary space partioning&#8217; and got to &#8216;bin&#8217; before Google Instant automatically took me to Bing.com&#8221;, he said.  &#8220;My manager was passing by and fired me on the spot for not being Googly enough.&#8221;</p>
<p>&#8220;I just don&#8217;t understand it. I&#8217;m fired for not using a service enough. Then I&#8217;m fired for using one too much. There needs to be some consiste&#8221;, Jay added in a tweet later on.</p>
<p>Facebook declined to give an official comment, though later in the day Facebook&#8217;s own Facebook status briefly changed to &#8220;officially has no official comment on Greavsie&#8217;s dismissal&#8221;.  No word on whether that was done on the responsible staff member&#8217;s own time or not.</p>
<p>Jim is now using LinkedIn to find a new position, and hopes that they will offer him a role soon.</p>
<p><em>After, and not in the same league as, <a href="http://www.theonion.com/" title="America's Finest News Source">The Onion</a>.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2011/06/15/facebook-engineer-fired-for-using-facebook-way-too-much-at-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>You Need A Montage</title>
		<link>http://jamietalbot.com/2011/01/31/you-need-a-montage/</link>
		<comments>http://jamietalbot.com/2011/01/31/you-need-a-montage/#comments</comments>
		<pubDate>Mon, 31 Jan 2011 10:53:03 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[GraphicsMagick]]></category>
		<category><![CDATA[Image Manipulation]]></category>
		<category><![CDATA[ImageMagick]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Montage]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=237</guid>
		<description><![CDATA[ImageMagick and GraphicsMagick are fantastic tools for manipulating images.  Here, I outline the montage sub-command and use it to tile two photos of differing dimensions, so that they can be easily aligned in a column format with other images.]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> Check out an online montage creator that builds on this and adds a lot more!  <a href="http://jamietalbot.com/projects/graphics/montage">Montage Away</a>!</p>
<hr />
<p>My girlfriend Emily Benjamin is something of a special photographer and she is finally putting together a site to show off some of her great pieces.  Naturally, I put her onto WordPress.  Emily wants the photos to go front and centre, which is a fine idea, so we put together a very simple one-column theme based on QuickPic, which will be uncluttered and allow the photos to shine.</p>
<p>Problems arose when trying to lay out images though.  Many of the photos are cropped for emphasis and impact, and being different dimensions, laying them all out on one page can look messy.  This can be avoided by cheating a bit and pre-processing them in pairs and combining them into a single image, so that each constituent photos&#8217; heights match.  Arty people like because it allows for some cool dynamic looking layout.  It also helps reduce the amount of HTTP requests which techy people care about.</p>
<p>How though to generate these tiled images?  You could hand-crank one with GIMP, but that gets pretty boring after a couple of times.  There are also a couple of commercial products out there that could help, but that seems like cheating.  No, Team America said it best &#8211; <a href="http://www.youtube.com/watch?v=JU9Uwhjlog8">you need a montage</a>!  ImageMagick&#8217;s <a href="http://www.graphicsmagick.org/montage.html">montage</a> command to be precise.  (I happen to use GraphicsMagick, as ImageMagick was giving me insidious &#8220;Bus Errors&#8221; on my MacBook, but the same commands will work with both tools.)  [Image|Graphics]Magick are some of the finest free tools available, and a shining example of the power of both open source communities and command line applications.</p>
<p>We start with two fine images, <a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/bell.png">a church in Budapest</a> and <a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/lamppost.png">a view at sunset from the Ponte Vecchio, Florence</a>.  They&#8217;re both huge, because DSLRs now take photos at up to 20MB in JPEG format (!).  So, we need to shrink them down a little bit and glue them together with a bit of whitespace, ensuring that the whole resulting image is 800 pixels wide (our chosen width for the main column).  </p>
<p>The montage command makes this simple enough:</p>
<pre class="brush: bash; title: ; notranslate">
gm montage -geometry x800+5 -background yellow lamppost.png bell.png -resize 800 output.png
</pre>
<p>You&#8217;ll notice that I&#8217;ve made the background yellow, just so we can see where the borders are here.  The geometry parameter says to make sure each component image fits within 800px vertically, leaving a 5px border on each side.  We decided that we wanted a 10px internal space between the photos, so 5px on the side of each photo works nicely.  The -resize command at the end takes effect after the montage has been created and resizes the entire outputted image to 800px wide, preserving the aspect ratio.  This is the size of photos that has been chosen for the host site, but on this site with a narrower main column I&#8217;ve forced it to 500px.  You can click on the images to see them at full 800px size if you want to.  I&#8217;ve chosen to output it as a PNG.  The image looks like this:</p>
<p><a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output.png"><img src="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output.png" alt="First pass at tiling photos" title="Stage 1" width="500" /></a></p>
<p>That&#8217;s not a bad first go, but there&#8217;s plenty we can improve.  The sunset photo is narrower than the church photo, so it has been centred within its cell.  There&#8217;s also an extraneous border around the outside.  We handle these with two additional parameters, gravity and trim.  Gravity allows us to &#8216;pull&#8217; each photo in a given direction within its cell, and trim gets rid of a border, whatever colour it is.</p>
<p>For the gravity, we want to pull the left photo rightwards, and the right photo leftwards, so the central spacing is consistent.  We do that by specifying -gravity East for the first photo and -gravity West for the second.</p>
<pre class="brush: bash; title: ; notranslate">
gm montage -geometry x800+5 -background yellow -gravity East lamppost.png -gravity West bell.png -resize 800 output.png
</pre>
<p><a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output1.png"><img src="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output1.png" alt="Centralising the tiled images" title="Stage 2" width="500" /></a></p>
<p>That&#8217;s looking better, but now we just have to get rid of that outer border.  We do that using the -trim command, and at the same time I&#8217;m going to make the background colour transparent:</p>
<pre class="brush: bash; title: ; notranslate">
gm montage -quality 100 -geometry x800+5 -background transparent -gravity East lamppost.png -gravity West bell.png -trim -resize 800 output.png
</pre>
<p>Notice that I do the trim before the final resize.  ImageMagick commands are executed sequentially from left to right.  I&#8217;ve also added a -quality parameter to keep the quality of the final image high.  (In this case it&#8217;s probably too high, but we won&#8217;t worry about that.)  Our image now looks like this:</p>
<p><a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output2.png"><img src="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output2.png" alt="Removing the border" title="Stage 3" width="500" /></a></p>
<p>and it&#8217;s looking pretty groovy.  But what happens if we want to tile two photos of vastly differing heights?  The &#8216;x800&#8242; is a decent enough guess, but if we start off with source images that are smaller than that (but which would still comfortably make a nice component image in a larger montage), we can end up with a pretty crazy result:</p>
<p><a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output3.png"><img src="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output3.png" alt="When images are too small, or different orientations, we get problems." title="All Falls Down" width="500" /></a></p>
<p>Not awesome.  The problem is that we are only guessing as to the height of the component images.  We can do better than that though, using *Magick&#8217;s identify command.  This tool gives everything you could possibly want to know about an image, but for now we&#8217;re only interested in the height, and that&#8217;s relatively straightforward:</p>
<pre class="brush: bash; title: ; notranslate">
gm identify -format &quot;%h&quot;
</pre>
<p>which gives us a simple single number.  Ideally, we only want to initially shrink the component images enough so that they are the same size vertically as the smallest vertical of the two.  In practise, this means we are only shrinking the image that is larger vertically in the first stage.  Once they are composed at the same height, we can glue them and shrink the resulting image.  A little bit of bash scripting gets this done for us in a couple of lines:</p>
<pre class="brush: bash; title: ; notranslate">
#!/bin/bash
HEIGHT_ONE=`gm identify -format %h $1`;
HEIGHT_TWO=`gm identify -format %h $2`;

if [ &quot;$HEIGHT_ONE&quot; -lt &quot;$HEIGHT_TWO&quot; ]
then
    MIN_HEIGHT=&quot;$HEIGHT_ONE&quot;
else
    MIN_HEIGHT=&quot;$HEIGHT_TWO&quot;
fi

gm montage -quality 100 -geometry x${MIN_HEIGHT}+5 -background transparent -tile 2x1 -gravity East $1 -gravity West $2 -trim -resize 800 output.png
</pre>
<p>(If you&#8217;re copying and pasting that, ensure you paste as backticks on lines 3 and 4, not quotes or apostrophes.)</p>
<p>Save that as &#8216;you-need-a-montage&#8217;, then make it executable and you can do:</p>
<pre class="brush: bash; title: ; notranslate">
./you-need-a-montage left-image.jpg right-image.jpg
</pre>
<p>to end up with something like this:</p>
<p><a href="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output4.png"><img src="http://jamietalbot.com/wordpress/wp-content/uploads/2011/01/output4.png" alt="A nicely formatted montage with a transparent separator." title="Finalised" width="500" /></a></p>
<p>Be sure to check out more of what ImageMagick and GraphicsMagick can do for you &#8211; this is just scratching the surface.  And keep an eye out for <a href="http://emilybenjamin.com">Emily Benjamin</a> too, once the site is up and running!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2011/01/31/you-need-a-montage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Now Reading&#8230; More</title>
		<link>http://jamietalbot.com/2011/01/27/now-reading-more/</link>
		<comments>http://jamietalbot.com/2011/01/27/now-reading-more/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 12:21:23 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Kindle]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Reading]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=186</guid>
		<description><![CDATA[On my recent joyful rediscovery of reading, a simple and inestimable pleasure that I let alone for too long, and a new bare-bones WordPress plugin I cobbled together tonight to list recently read books.]]></description>
			<content:encoded><![CDATA[<p>In keeping with my aim to read and write something every day, I&#8217;ve been busy putting the new Kindle to good use.  It remains the only tech purchase I&#8217;ve made that has exceeded my expectations, and for which I have no buyer&#8217;s remorse.  I got out of the habit of carrying books with me, but with the Kindle there&#8217;s no excuse.  I&#8217;ve rediscovered the act of reading for pleasure and have largely replaced time-wasting iPhone games like Angry Birds and Cut The Rope with something more meaningful.  Suddenly time on the bus is eagerly anticipated, rather than avoided, and the empty satisfaction of beating some poor AI on Monopoly is replaced by the genuine joy of finishing a novel.</p>
<p>I was using Amazon&#8217;s Reading List application on LinkedIn and writing short reviews there, but I quite like the idea of having a history of what I&#8217;ve read on my own site.  There are a couple of &#8220;now reading&#8221; plugins for WordPress, but none of them really did what I wanted, so I decided to scratch the itch and put something together.  30 minutes later and you can see the results in the sidebar on the homepage!  Writing plugins for WordPress hasn&#8217;t really changed much since I was active in that area a few years ago, but the main posts table now seems to be used for all kinds of content.  In that spirit, I just created a custom post type of &#8216;book&#8217;, inserted some data into the database and wrote a little widget to extract it.  Reusing the guid column for ISBNs lets me make use of the wonderful <a href="http://openlibrary.org/">Open Library</a> for covers and the post content just becomes the text.  I suppose I could have monetised it with Amazon links, but I&#8217;m sure I can live without the 5 bucks that would bring in a year!  There&#8217;s a little more to do yet, like flesh out a main library URL, and introduce a simple backend page for adding books, but for now it does what I want.</p>
<p>Now I only wish I&#8217;d done this years ago, as the list appears pretty thin at the moment!  I&#8217;ll just take that as yet another incentive to read more!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2011/01/27/now-reading-more/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Erlang Matrix Module</title>
		<link>http://jamietalbot.com/2011/01/18/an-erlang-matrix-module/</link>
		<comments>http://jamietalbot.com/2011/01/18/an-erlang-matrix-module/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 22:27:19 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Erlang]]></category>
		<category><![CDATA[GitHub]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[matrix]]></category>
		<category><![CDATA[module]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=152</guid>
		<description><![CDATA[A simple matrix module written in Erlang, using lists rather than tuples as its main implementation detail, which provides a number of standard matrix operations without the excessive copying and overhead that existing modules exhibit.]]></description>
			<content:encoded><![CDATA[<p>As part of a recent investigation into counting Hamiltonian Paths in undirected graphs, I began researching the work of Eric Bax, whose paper on <a href="http://portal.acm.org/citation.cfm?id=173192">Inclusion Exclusion</a> promised to yield a quick solution.  Although I ended up going in a different direction, his reliance on adjacency matrices that would be processed 2<sup>n</sup> times required a matrix module that was as efficient as possible.  Writing the solution in Erlang, I found a surprising lack of matrix code on the web, with the most developed I could find being <a href="http://dada.perl.it/shootout/matrix.erlang.html">here</a>.</p>
<p>Erlang perhaps isn&#8217;t the best language for dealing with matrices, with its &#8216;one-time&#8217; mathematical approach to assignment, however the existing methods all seemed to make use of tuple_to_list(), list_to_tuple() conversion and excessive list copying.  Below I present a simple module which is at least more efficient than the above, and relies on a list of lists, using lists:nth() to retrieve elements.  Perhaps in the future this will be superceded by new <a href="http://www.erlang.org/doc/man/array.html">array</a> syntax, but for now it suits my needs.</p>
<p>Matrices are generally stable, by which I mean unchanging in dimensions.  Of course matrices can be different sizes, but the majority of matrix operations that return a matrix result return one the same size as at least one of the inputs.  Given that we know the matrix dimensions, in theory this makes tuples a suitable choice for implementation, but in practice the immutability of tuples (even more immutable than lists) make them unwieldy and involve a lot of overhead when building them.  And with Erlang&#8217;s binding there will be lots of rebuilding.</p>
<p>The main approach is to accept that we will be rebuilding the matrix in full each time and generalise to a standard matrix building function that takes matrix size and cell content generator function parameters:</p>
<pre class="brush: erlang; title: ; notranslate">
new(Columns, Rows, ContentGenerator) -&gt;
  [
    [ContentGenerator(Column, Row, Columns, Rows)
      || Column &lt;- lists:seq(1, Columns)
    ]
    || Row &lt;- lists:seq(1, Rows)
  ].
</pre>
<p>which reads roughly &#8220;for each row, for each column on that row, call the content generation function for that cell&#8221;.</p>
<p>Each content generator function has the following spec:</p>
<pre class="brush: erlang; title: ; notranslate">
fun((pos_integer(), pos_integer(), pos_integer(), pos_integer()) -&gt; any()
</pre>
<p>where the four parameters are current column, current row, number of columns, number of rows.  A simple identity function is as follows:</p>
<pre class="brush: erlang; title: ; notranslate">
fun(Column, Row, _, _) -&gt;
  case Column of Row -&gt; 1; _ -&gt; 0 end
end
</pre>
<p>which will generate the identity matrix:</p>
<pre class="brush: erlang; title: ; notranslate">
[[1 0 0]
 [0 1 0]
 [0 0 1]]
</pre>
<p>A sequential matrix might be generated with the following function:</p>
<pre class="brush: erlang; title: ; notranslate">
fun(Column, Row, Columns, _) -&gt;
  Columns * (Row - 1) + Column
end
</pre>
<p>giving:</p>
<pre class="brush: erlang; title: ; notranslate">
[[1 2 3]
 [4 5 6]
 [7 8 9]]
</pre>
<p>while a matrix composed of pseudo-random numbers 1 to MaxValue could be:</p>
<pre class="brush: erlang; title: ; notranslate">
fun(_, _, _, _) -&gt;
  random:uniform(MaxValue)
end
</pre>
<p>where MaxValue is bound in a closure, giving (for example):</p>
<pre class="brush: erlang; title: ; notranslate">
[[3 9 6]
 [1 1 4]
 [6 2 1]]
</pre>
<p>With this general mechanism, matrix operations such and addition or multiplication become a lot simpler.  All that is required is to define a generator function that sets each cell correctly according to whatever operation you are performing.  Matrix addition is defined thus:</p>
<pre class="brush: erlang; title: ; notranslate">
% Adds two matrices together.
-spec add(num_matrix(), num_matrix()) -&gt; num_matrix().
add(A, B) -&gt;
  new(length(lists:nth(1, A)), length(A),
    fun(Column, Row, _, _) -&gt;
      element_at(Column, Row, A) + element_at(Column, Row, B)
    end
  ).
</pre>
<p>Performance isn&#8217;t great for modification of a single cell, as it rebuilds the entire matrix.  A future optimisation could include recognising that an entire row hasn&#8217;t changed and simply rebinding that.  However, for my current use cases, I haven&#8217;t needed efficient single-cell manipulation.  There are specs for the functions, but very little in the way of error checking.  There are no checks for the addition of matrices of two different sizes, for example.</p>
<p>Future extensions will include the &#8216;Hungarian&#8217; approach to the assignment problem, retrieval functions for entire columns or rows, some unit testing code, and confirmed support for NxM matrices.  (Non-square matrices currently work in theory, but not all functions have been tested to work with them.)  Check out the code <a href="https://github.com/majelbstoat/Morgana/blob/master/src/matrix.erl">on GitHub</a>.  It&#8217;s freely available to use and fork, and if you do, be sure to send a pull request!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2011/01/18/an-erlang-matrix-module/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>And The Water Continues Its Inexorable Ascent</title>
		<link>http://jamietalbot.com/2011/01/12/and-the-water-continues-its-inexorable-ascent/</link>
		<comments>http://jamietalbot.com/2011/01/12/and-the-water-continues-its-inexorable-ascent/#comments</comments>
		<pubDate>Wed, 12 Jan 2011 13:24:36 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Australia]]></category>
		<category><![CDATA[Brisbane]]></category>
		<category><![CDATA[floods]]></category>
		<category><![CDATA[LinkedIn]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=149</guid>
		<description><![CDATA[The recent floods have transformed Brisbane.  Here I describe the mood on the night of January 12th as we wait for the flood peak to come.]]></description>
			<content:encoded><![CDATA[<p>This is not the Brisbane I know.  The floods have been serious and tragic in North Queensland and have monopolised news for much of the last week, but being high and dry, or so we thought, it might as well have been happening in Europe.  Even in Camp Hill, it was hard to believe that there really was a problem at all, until we came back into the city this afternoon.  Reality bites hard. Making our way back across town, we began to see the so-called human impact of the torrent, whose original meaning has briefly reclaimed prominence in this part of the world from its Internet neologic sibling.</p>
<p>This is a different kind of flood to those in Toowoomba.  Whilst they were flash floods, caused by super storms dropping hundreds of millimeters of rain in a matter of hours, this is a more subtle, deceptive approach.  Like the T-2000, which walks because it has no need to run, the impending deluge will get here in its own sweet time.  The opening of the Wivenhoe floodgates necessitated by its 190% fill, combined with the winter King Tide and a river swollen with weeks of rain ensure the inevitable.  A regular Perfect Storm, it is being said.  Blue skies over much of Brisbane today belied the fact that tomorrow, water levels will reach their highest points in nearly 40 years, and may go higher.  And there is nothing to do but wait for it.  Not so much the calm before the storm, but in the eye of it.  With the severest weather apparently over, there is only the aftermath to come.  This may be the hardest thing to reconcile; that there can be such a delay from the event to the impact.</p>
<p>The supermarkets looked post-apocalyptic yesterday, with scenes typically assumed more appropriate for Soviet Russia, as people queued for bread and other staples.  The irony of having to purchase bottled water was lost on no-one, but concerns about the continued functioning of the water treatment plant meant people were leaving nothing to chance.   There were no queues today, with the cupboards already bare, but for some canned goods, and a single solitary pineapple.</p>
<p>With valuables safely stowed and sandbags in place, people stepped out, curious and keen to survey the newly-aquatic scenery.  Brisbane is a river city, not a beach city, and it is to here that people are drawn.  Amazement as ferry terminals and river restaurants slip their moorings and are deliberately sunk, to prevent them turning into tremendous torpedos.</p>
<p>Wandering around near Milton station, people appeared dazed and confused, with the same shocked expression resonating on every face as the scale of the sprawl became apparent.  Unlike Atlantis, which conjures visions of grandeur, we are instead treated to the mundane made novel.  Submerged street signs, an inundated McDonalds and debris floating lazily down new rivers contribute to the disbelief.  The commonplace becoming surreal, as water is juxtaposed with traffic lights and KFC.  No glorious Venice this, no grand cathedrals or Bridge of Sighs, though many sighed as all but one of the bridges closed.</p>
<p>No fear though, not here.  Unlike our colleagues in the North, we at least have had the warning and time to make preparations.  Excitement is the wrong word.  That is too glib for the tragedy that has ruined and will ruin so much.  Anticipation perhaps.  A sense in the air.  Not quite foreboding, but the biding of time.  Deserted city streets, as people heed the warning to leave their cars at home.  No public transport, no hum of industry.  Quiet and somewhat menacing.</p>
<p>An hour ago, the rains returned briefly.  The power is out in much of the town.  There is the smell of salt in the air.  And the water continues its inexorable ascent.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2011/01/12/and-the-water-continues-its-inexorable-ascent/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Giving Back: My 2011 Manifesto</title>
		<link>http://jamietalbot.com/2011/01/08/giving-back-my-2011-manifesto/</link>
		<comments>http://jamietalbot.com/2011/01/08/giving-back-my-2011-manifesto/#comments</comments>
		<pubDate>Sat, 08 Jan 2011 23:14:53 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Manifesto]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=145</guid>
		<description><![CDATA[Open source projects have immeasurably changed the world and my life for the better.  With no formal employment for the bulk of 2011, I pledge to give time and effort to people that need help, and projects that inspire me.]]></description>
			<content:encoded><![CDATA[<p>New Year&#8217;s resolutions are made to be broken, but as this is a week after the fact, perhaps I have a better chance.</p>
<p>The open source world has enriched my life significantly, both professionally, in providing the databases, languages, operating systems and IDEs that are my livelihood, and personally, in providing communications tools, entertainment and even this blogging platform.  Over the course of my career, I&#8217;ve tried to give back to these communities, both in time and code submissions, and I&#8217;ve contributed in some small way to a <a href="http://couchdb.org">number</a> <a href="http://wordpress.org">of</a> <a href="http://xinc.eu">projects</a>.  The challenging nature of my recent full-time employment has unfortunately meant that more recently I&#8217;ve only been able to do this in limited ways.</p>
<p>With my impending hiatus and upcoming travels, I hope to have more time to dedicate to the various online communities I follow.  This might be through forums such as <a href="http://stackoverflow.com/users/38812/majelbstoat">stackoverflow</a> where I&#8217;ve received answers to numerous difficult questions, or simply helping people in chatrooms.  It might be answering questions on Quora.  It will certainly involve code contributions, though to which projects I&#8217;m not sure.  No deed is entirely selfless, and regular development will ensure I stay sharp and widen my employment opportunities, but primarily this is about passion for development, which I&#8217;m certain I couldn&#8217;t live without for any length of time.  I&#8217;m very excited about CouchDB, which would also develop my capabilities in Erlang.  I value Zend Framework very highly, which would deepen my expertise in PHP.  Perhaps it will be both, or others instead.  But as the new year begins, I will make this my manifesto &#8211; that I will give back to those people and projects that have made my life, and many others&#8217; lives better.</p>
<p>My job title from January 22nd &#8211; Open Source Contributor.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2011/01/08/giving-back-my-2011-manifesto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ed Vaizey: A Danger To The Internet</title>
		<link>http://jamietalbot.com/2010/11/17/ed-vaizey-a-danger-to-the-internet/</link>
		<comments>http://jamietalbot.com/2010/11/17/ed-vaizey-a-danger-to-the-internet/#comments</comments>
		<pubDate>Wed, 17 Nov 2010 22:20:27 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Politics]]></category>
		<category><![CDATA[Danger]]></category>
		<category><![CDATA[Ed Vaizey]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Net Neutrality]]></category>
		<category><![CDATA[UK]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=115</guid>
		<description><![CDATA[Ed Vaizey has all disavowed Net Neutrality, saying instead that market forces should shape future access to the Internet.  He is dangerously wrong and underestimates the degree to which a tiered Internet will impinge upon creativity, innovation and free speech.]]></description>
			<content:encoded><![CDATA[<p>So Ed Vaizey took 2500 words to essentially say that Net Neutrality contradicts the Conservatives&#8217; views on a laissez-faire, &#8220;lightly-regulated&#8221; Internet and will not be enshrined in law, in <a href="http://www.guardian.co.uk/technology/2010/nov/17/net-neutrality-ed-vaizey">a speech</a> dressed up to confuse and sow doubt.  This is a tremendous mistake, a sop to big business and a danger to freedom of expression.</p>
<p>Allowing ISPs to charge different amounts for access to different content is abhorrent.  It is clear that large businesses will be able to pay the subscription fees which ensure that their content is delivered to the widest number of people at the fastest speeds.  The little guys, the independent bloggers and the startups won&#8217;t have access to the capital required to pay additional dues.  Remember that content providers already pay access fees to ISPs.  These scale naturally with the size of the company.  The more popular you are, the more bandwidth you require and the more you pay.  Expecting newly formed companies to pay additional fees on top of that, just to ensure that consumers receive a high-quality service will stifle innovation, reduce creative output and reduce the economic benefits that Ed Vaizey is so keen to champion. </p>
<p>It will also lower the value proposition for releasing an Internet product to the UK.</p>
<p>Other countries have already enshrined Net Neutrality in law.  If you had a new and innovative, but bandwidth-hungry product, would you release it in a country where everyone was guaranteed reasonable access, or a country where only those subscribers who could afford to see it would?  Social products in particular, which thrive on the basis that everyone is connected, would suffer.  You&#8217;d never start a Facebook in a country where there was a possibility half of the available audience wouldn&#8217;t see it or have high-quality access.  </p>
<p>Companies will have to pick which countries they choose to pay for access in, which could leave the UK behind in terms of access to content at reasonable speeds.  The UK already languishes behind the US in terms of release dates for media and services (c.f Netflix, Spotify, Google Voice) and this would compound the issue with slower speeds when and if they are finally made available.</p>
<p>For the same reason that companies go overseas to avoid taxation and find cheaper manufacturing options, the UK could become a country where Internet products are only released as an afterthought, and only if the access fees are acceptable.  For the few lucky companies that are popular enough to survive, but who don&#8217;t want to pay the access fees, It is the subscriber who will inevitably end up subsidising the payments through higher rates.</p>
<p>More insidiously, it will chill dissenting voices.  Aside from the massive economic benefits that governments love, the key innovation of the Internet has been to democratise ideas, knowledge and the power to influence.  The wild nature of the Internet means you can find supporting or dissenting opinions on every subject you care to think of.  The Conservatives conflate &#8220;lightly-regulated content&#8221; in terms of freedom of expression, which is A Good Thing, with &#8220;lightly-regulated access&#8221;, which allows ISPs to pick and choose which content you get to see, which is A Very Bad Thing.  </p>
<p>Once you remove the principle of Net Neutrality, there is no barrier to a filtered Internet.  The paradox of &#8220;lightly-regulated access&#8221; is that it inevitably leads to heavily-regulated content.  How long do you imagine it will be before ISPs, under pressure from various governments, choose to slow or deny access to important sites like <a href="http://wikileaks.org/">Wikileaks</a>?  They may not pay the ISPs to do so, but they have considerable leverage in terms of taxation and licensing.  How long before evangelical groups pressure ISPs to do the same to porn sites?  From there, it is a small but definitive step to a filtered, sanitised Internet, where you can only see what you should be allowed to see.  </p>
<p>Does this sound paranoid and ridiculous?  Consider the trialled &#8220;Net-Filter&#8221; in Australia, designed to prevent access to illegal content.  When the blacklist was leaked and published (by Wikileaks, no less), <a href="http://www.computerworld.com.au/article/296161/australia_web_blacklist_leaked/">plenty of sites</a> were found to be on it that weren&#8217;t illegal, but were simply outside the mainstream tolerance for fetishes and the like.  Even some legitimate businesses were excluded.  Abuses like this happen even in systems where everyone involved honestly tries to enforce the rules fairly.  Introduce a profit motive like &#8220;pay for access&#8221;, and human nature sadly dictates that freedoms will be impugned.</p>
<p>The only way to ensure those freedoms is to enshrine in law that ISPs have a duty to deliver all content equally, regardless of source.</p>
<p>There is a reason we don&#8217;t allow people to pay politicians to ask leading questions or enact legislation (let&#8217;s leave aside the iniquities of the extremes of lobbying for now).  We expect our politicians to behave in a manner that is good for the people they were elected to represent, and we recognise that allowing them to take money for favours colours their judgement.  The analogy holds for ISPs.  If we allow them to take money from content providers, they are going to prioritise those providers&#8217; needs first, above other providers, above subscribers&#8217; needs and above the general good.  </p>
<p>Free markets are not perfect and are not a universal panacea.  See the current state of US healthcare for a cautionary tale.</p>
<p>Expecting market forces to manage the fallout is naive.  Rest assured, the ISPs will all take the opportunity to extract more money, if only because they have a fiduciary duty to act in the best interests of their shareholders, and, sadly, that is wholly equated with profit.  New ISPs offering net neutral services will not magically pop into existence.  For a start, many consumers won&#8217;t even know what&#8217;s going on.  The Internet is a utility, like water, gas and electricity.  You turn on a tap and water comes out.  You plug in a toaster and start making toast.  You connect that funny little cable into the wall and Google appears.  How many people actually think about how that all works?  It&#8217;s a service, it&#8217;s there and it works.  Do people complain when their lightbulbs flicker?  Issues with the Internet are even more subtle.  If you can&#8217;t get to Twitter, the default response is &#8220;Twitter is down&#8221;, not &#8220;My ISP is broken&#8221;.  Expecting a mass-revolt from the non-technosavvy people due to poor access is credulous.</p>
<p>Even assuming there was the demand for a Net Neutral ISP, starting such a business is an expensive and complex proposition.  With low margins, the only way to survive is to have a large user base.  The market approaches saturation in the UK and the costs and hassle for users involved in switching providers are prohibitively high.  </p>
<p>Large amounts of startup capital are needed to start an ISP, and they won&#8217;t even be playing on a level playing field because the other ISPs will be working from a larger revenue base with the additional dues they are extracting from the content providers.</p>
<p>Once non-neutral ISPs are here, they&#8217;re here to stay.  Denying a revenue stream from forming is one thing, but ISPs and shareholders will cry foul when you try to take it away again and &#8220;lower shareholder value&#8221;.</p>
<p>The only solution is Net Neutrality, and it needs to be enshrined in law now.  Ed Vaizey must be convinced that he is on the wrong track and that his current thinking represents a clear and present danger to the future of the Internet.</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2010/11/17/ed-vaizey-a-danger-to-the-internet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Object Oriented jQuery Plugins Mk 2</title>
		<link>http://jamietalbot.com/2010/08/26/object-oriented-jquery-plugins-mk-2/</link>
		<comments>http://jamietalbot.com/2010/08/26/object-oriented-jquery-plugins-mk-2/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 23:02:40 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Object Oriented Design]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=98</guid>
		<description><![CDATA[Update: This code is now on GitHub and has had some substantial improvements made. You should look at the latest code here and submit a pull request if you make any improvements! In a recent post, I outlined a method to abstract away the complexity of creating an encapsulated jQuery plugin. However, as was pointed [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update:</strong> This code is now on GitHub and has had some substantial improvements made.  You should look at the latest code <a href="https://github.com/majelbstoat/Celsus/blob/master/js/plugins/encapsulatedPlugin.js">here</a> and submit a pull request if you make any improvements!</p>
<hr />
<p>In a <a href="http://jamietalbot.com/2010/08/22/object-oriented-jquery-plugins/">recent post</a>, I outlined a method to abstract away the complexity of creating an encapsulated jQuery plugin.  However, as was pointed out in the comments, there was a missing piece that didn&#8217;t allow for arguments to be passed through.  More seriously, there was an issue with the binding of the facade function, which meant that only the last defined public function in the class could be called.</p>
<p>As an aside, if you need to bind a variable at the time that it is defined, it isn&#8217;t enough to define an anonymous function with a reference to the closure, as that can change by the time the function is called.  The bug in my code was in the piece that bound the facade function to the set member functions.</p>
<pre class="brush: jscript; title: ; notranslate">
	for ( var i in template) {
		if (typeof (template[i]) == 'function') {
			result[i] = function() {
				this.each(function() {
					this[i]();
				});
			};
		}
	}
</pre>
<p>By the time the inner function is called, &#8220;i&#8221; has already been re-bound to the final function name in the template.  The solution is to bind the inner function name to the outer function name at the time of definition, which we can do by wrapping it in (yet another!) function.</p>
<pre class="brush: jscript; title: ; notranslate">
	// Iterates through the set calling the specified function.
 	function makeIteratorFunction(f, set) {
		return function() {
			for ( var i = 0; i &lt; set.length; i++) {
				set[i][f].apply(set[i][f], arguments);
			}
		};
	}
</pre>
<p>and then calling that function:</p>
<pre class="brush: jscript; title: ; notranslate">
	if (template) {
		for ( var i in template) {
			if (typeof (template[i]) == 'function') {
				result[i] = makeIteratorFunction(i, result);
			}
		}
	}
</pre>
<p>At this point, although &#8220;i&#8221; will continue to change as the loop continues, the function call is bound through the closure on &#8220;f&#8221; in the auxiliary function, which remains fixed.  Google Chrome&#8217;s developer tools certainly make following all that a lot simpler!  I&#8217;ve updated the plugin with these improvements, which also enables us to pass arguments through, finally allowing:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#foo').myplugin().publicMethodWithArguments('hello');
</pre>
<p>You can get the updated plugin <a href="/projects/js/jquery/encapsulatedPlugin.js.txt" title="jQuery encapsulated plugin generating plugin">here</a>.  Feedback welcomed!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2010/08/26/object-oriented-jquery-plugins-mk-2/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Object Oriented jQuery Plugins</title>
		<link>http://jamietalbot.com/2010/08/22/object-oriented-jquery-plugins/</link>
		<comments>http://jamietalbot.com/2010/08/22/object-oriented-jquery-plugins/#comments</comments>
		<pubDate>Sun, 22 Aug 2010 17:36:48 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[Object Oriented Design]]></category>
		<category><![CDATA[Plugin]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=91</guid>
		<description><![CDATA[Object oriented jQuery plugins have typically been hard to create in an elegant way.  Here, we demonstrate how to design a clean jQuery plugin which allows for full encapsulation of data, and allows access to public methods without using the data object as a obvious proxy.]]></description>
			<content:encoded><![CDATA[<p><strong>Update 2:</strong> This code is now on GitHub and has had some substantial improvements made.  You should look at the latest code <a href="https://github.com/majelbstoat/Celsus/blob/master/js/plugins/encapsulatedPlugin.js">here</a> and submit a pull request if you make any improvements!</p>
<hr />
<p><strong>Update:</strong> As pointed out in the comments, the first version of this code didn&#8217;t allow for methods with parameters.  Although the code in the main post below is unchanged, the code linked at the bottom of the page and <a href="/projects/js/jquery/encapsulatedPlugin.js.txt" title="jQuery encapsulated plugin generating plugin">here</a> has been updated to reflect some improvements, that now allow this and some other niceties.  The main body of the post should still be worth reading for the derivation though!</p>
<hr />
<p>I&#8217;ve recently begun the process of porting some javascript library code from Prototype to jQuery, and on the whole it hasn&#8217;t been too problematic.  I really like the element-centric nature of jQuery, whereas Prototype is more like a excellent set of useful static methods.  There were only a couple of things I found myself really missing, and they were enumerables, and elegant plugin encapsulation.  The first problem was solved with Xavier Shay&#8217;s nice <a href="http://rhnh.net/2008/12/28/inject-and-collect-with-jquery" title="Enumerables for jQuery">enumerables plugin</a>.  The second one was more of a challenge.</p>
<p>The lack of encapsulation for jQuery plugins seems to be a common frustration, and there are lots of queries on the web along the lines of &#8220;how do I add public methods to a jQuery plugin&#8221;.  The best solution I found came from <a href="http://www.virgentech.com/blog/2009/10/building-object-oriented-jquery-plugin.html">Hector Virgen</a>, which allows you to do something like this:</p>
<pre class="brush: jscript; title: ; notranslate">
var pluginInstance = $('#foo').data('myplugin');
pluginInstance.publicMethod();
</pre>
<p>That&#8217;s pretty neat, but I didn&#8217;t really like the idea of having to go through the data object each time.  A couple of other people in the comments felt the same way, but there didn&#8217;t seem to be any solutions forthcoming, so I had a crack.  What follows is largely based on Hector&#8217;s code, so you should go and read that first before you go through this.</p>
<p>We start off with a basic plugin shell, slightly modified from Hector&#8217;s, per my taste:</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {
	var Celsus = Celsus || {};
	Celsus.MyPlugin = function(element, options) {

		// Private members
		var elem = $(element);

		var settings = $.extend({}, options || {});

		// Private methods
		function _privateMethod() {
			console.log(&quot;This is a private method!&quot;);
		}

		return {
			publicMethod: function() {
				console.log(elem);
				_privateMethod();
				return true;
			}
		};
	};

	$.fn.myplugin = function(options) {
		return this.each(function() {
			var element = $(this);
			if (element.data('myplugin')) {
				return;
			}
			var myplugin = new Celsus.MyPlugin(this, options);

			// Store the new plugin definition in a data object.
			element.data('myplugin', myplugin);
		});
	};
})(jQuery);
</pre>
<p>This is a pretty good start.  However, as Hector points out, the main issue is that the plugin returns a jQuery object to enable chaining.  In many complex instances, chaining isn&#8217;t necessarily something you&#8217;re going to want to do, so we make a small sacrifice and forego that convenience.  Instead, we are going to return a set of plugin instance objects:</p>
<pre class="brush: jscript; title: ; notranslate">
$.fn.myplugin = function(options) {
	var result = [];
	this.each(function() {
		var element = $(this);

		if (!element.data('myplugin')) {
			// Initialise
			var myplugin = new Celsus.MyPlugin(this, options);

			// Store the new functions in a validation data object.
			element.data('myplugin', myplugin);
		}
		result.push(element.data('myplugin'));
	});
};
</pre>
<p>At this point, it&#8217;s not looking too great.  We&#8217;ve broken chaining because we no longer return a jQuery object, but if you try and call</p>
<pre class="brush: jscript; title: ; notranslate">
$('#foo').myplugin().publicMethod();
</pre>
<p>it still doesn&#8217;t work.  This is because, although each plugin instance has the publicMethod() function, they are contained inside a bare array.  At this point we could actually do:</p>
<pre class="brush: jscript; title: ; notranslate">
($('#foo').myplugin()[0]).publicMethod();
($('#foo').myplugin()[1]).publicMethod();
</pre>
<p>Or something similar with each(), but this is very messy.  We need a bit of syntactic sugar.  To achieve this, the next step is to take that array, turn it into something we can work with, and add a facade, so that every public function we&#8217;ve just mixed in is presented as an option on the plugin instance set.  We do that by adding the following to the plugin definition:</p>
<pre class="brush: jscript; title: ; notranslate">
result = $(result);
var template = result[0];
if (template) {
	for ( var i in template) {
		if (typeof (template[i]) == 'function') {
			result[i] = function() {
				this.each(function() {
					this[i]();
				});
			};
		}
	}
}
</pre>
<p>Firstly, we convert the array to a jQuery object.  Then, we look at the first instance in the set and use that as a template.  It should contain all the public functions we&#8217;ve defined in our definition class, and all the instances are of the same type, so we can safely use the first entry&#8217;s template for all of them.  We then enumerate through all the public functions and create a proxy or facade function on the set, which simply calls the closure of that function for each element in the set.  This ensures that when you call</p>
<pre class="brush: jscript; title: ; notranslate">
$('#foo').myplugin().publicMethod();
</pre>
<p>it is functionally equivalent to:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#foo').myplugin().each(function(instance) {
	instance.publicMethod();
});
</pre>
<p>So that&#8217;s pretty cool.  We&#8217;ve avoided namespace pollution, we can mix in any number of public methods, and private members and methods behave as you&#8217;d expect them to.  It isn&#8217;t possible to access public variables in this manner of course, but that is easily remedied by using public getters and setters.  We can even add in a reference back to the jQuery object, so we can get chaining back in in some form:</p>
<pre class="brush: jscript; title: ; notranslate">
result.$ = this;
</pre>
<p>Which lets us do:</p>
<pre class="brush: jscript; title: ; notranslate">
$('#foo').myplugin().$.addClass('bar');
</pre>
<p>This is useful when you&#8217;re doing plugin initialisation, but thereafter it&#8217;s a bit redundant as the actual plugin call simply returns an object which you then ignore.  The only final point is that there&#8217;s quite a lot of boilerplate going on here just to get set up.  In actual fact, the actions are pretty generic, so we can extract all that code and put it in its own plugin.  A plugin to generate a plugin!</p>
<pre class="brush: jscript; title: ; notranslate">
(function($) {
	$.fn.encapsulatedPlugin = function(plugin, definition, objects, options) {
		var result = [];
		objects.each(function() {
			var element = $(this);

			if (!element.data(plugin)) {
				// Initialise
				var instance = new definition(this, options);

				// Store the new functions in a validation data object.
				element.data(plugin, instance);
			}
			result.push(element.data(plugin));
		});

		// We now have a set of plugin instances.
		result = $(result);

		// Take the public functions from the definition and make them available across the set.
		var template = result[0];
		if (template) {
			for ( var i in template) {
				if (typeof (template[i]) == 'function') {
					result[i] = function() {
						this.each(function() {
							this[i]();
						});
					};
				}
			}
		}

		// Finally mix-in a convenient reference back to the objects, to allow for chaining.
		result.$ = objects;

		return result;
	};

})(jQuery);
</pre>
<p>With this little plugin, our plugin initialisation code is a lot lighter:</p>
<pre class="brush: jscript; title: ; notranslate">
	$.fn.myplugin = function(options) {
		return $.fn.encapsulatedPlugin('myplugin', Celsus.MyPlugin, this, options);
	};
</pre>
<p>Not too bad!  The actual code that specialises a plugin is tucked away in a neatly encapsulated object, we have access to all the public methods defined on it and multiple instances can happily live side by side and be invoked separately without trampling on each other.    You can grab a copy of the plugin generating plugin from <a href="/projects/js/jquery/encapsulatedPlugin.js.txt" title="jQuery encapsulated plugin generating plugin">here</a>.  This is still new cod and there might be the odd glitch, so if you spot any, or have other ideas, be sure to leave a comment!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2010/08/22/object-oriented-jquery-plugins/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Subtle Behaviour of The Static Keyword in PHP 5.3</title>
		<link>http://jamietalbot.com/2010/08/11/subtle-behaviour-of-the-static-keyword-in-php-5-3/</link>
		<comments>http://jamietalbot.com/2010/08/11/subtle-behaviour-of-the-static-keyword-in-php-5-3/#comments</comments>
		<pubDate>Wed, 11 Aug 2010 21:58:04 +0000</pubDate>
		<dc:creator>Jamie Talbot</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Inheritance]]></category>
		<category><![CDATA[Late-Static Binding]]></category>
		<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://jamietalbot.com/?p=86</guid>
		<description><![CDATA[Describing a slight inconsistency in PHP 5.3's use of the static keyword and how it can affect late-static binding.]]></description>
			<content:encoded><![CDATA[<p>Version 5.3 of PHP added a new, very useful and long-overdue feature allowing for late-static binding using the &#8216;static&#8217; keyword instead of the &#8216;self&#8217; keyword.  The PHP manual has a good explanation of the difference.  However, there is a subtle behaviour that I certainly hadn&#8217;t anticipated and might catch you out.</p>
<p>A typical use-case of the new syntax is to lazy-load static variables in inherited child classes, which offers you the choice of avoiding the overhead of object-instantiation to provide class differentiation.  Unfortunately, it is not quite as straightforward as you might think.  Consider the following piece of code:</p>
<pre class="brush: php; title: ; notranslate">
class BaseClass {

	static $_value = null;

	public static function getValue() {
		if (null === static::$_value) {
			static::$_value = get_called_class();
		}
		return static::$_value;
	}
}

class ChildAClass extends BaseClass {}

echo BaseClass::getValue() . &quot;\n&quot;;
echo ChildAClass::getValue() . &quot;\n&quot;;
</pre>
<p>What&#8217;s going on here then?  When I look at that piece of code, I expect the output to be:</p>
<pre class="brush: php; title: ; notranslate">
BaseClass
ChildAClass
</pre>
<p>Instead, it appears the call to ChildAClass::getValue() fails the conditional test and returns the static value of BaseClass, giving the following output:</p>
<pre class="brush: php; title: ; notranslate">
BaseClass
BaseClass
</pre>
<p>Not very helpful.  How can we work around this?  The answer is to ensure you declare the static variable in each of your child classes as well as the parent.  It&#8217;s straightforward enough, but a pain to remember every time.  The following example demonstrates:</p>
<pre class="brush: php; title: ; notranslate">
class ChildBClass extends BaseClass {

	static $_value = null;
}

echo BaseClass::getValue() . &quot;\n&quot;;
echo ChildBClass::getValue() . &quot;\n&quot;;
</pre>
<pre class="brush: php; title: ; notranslate">
BaseClass
ChildBClass
</pre>
<p>So it appears (at least for PHP 5.3.3 (OS X)), that static only really means static if you declare it yourself each time.  This might be expected behaviour, but I consider it a bug, and it can certainly lead to hard to debug situations.  It doesn&#8217;t seem to be documented clearly in any standard location that I could find.</p>
<p>Short story &#8211; if you are looking to lazily-populate static variables using the new syntax, be sure to declare the variables in all of the child classes you are going to use!</p>
]]></content:encoded>
			<wfw:commentRss>http://jamietalbot.com/2010/08/11/subtle-behaviour-of-the-static-keyword-in-php-5-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

