<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>The Irish Penguin</title>
 <link href="http://www.theirishpenguin.com/atom.xml" rel="self"/>
 <link href="http://www.theirishpenguin.com"/>
 <updated>2016-09-09T23:14:08+00:00</updated>
 <id>http://www.theirishpenguin.com</id>
 <author>
   <name>Declan McGrath</name>
   <email>declan@weuseopensource.com</email>
 </author>

 
 <entry>
   <title>My Embarrassing First Steps with the Javascript fetch() API</title>
   <link href="http://www.theirishpenguin.com/2016/09/09/my-embarrassing-first-steps-with-the-javascript-fetch-api.html"/>
   <updated>2016-09-09T23:57:12+00:00</updated>
   <id>http://www.theirishpenguin.com/2016/09/09/my-embarrassing-first-steps-with-the-javascript-fetch-api</id>
   <content type="html">&lt;p&gt;&lt;b&gt;Spoiler: If you are more interested in the destination than the journey
then skip to the last code example in this article.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;So after a decade of the dollar, the great $ symbol that is ubiquitously
associated with jQuery (and mostly AJAX), we&#39;re finally moving on. Moving
on to what promises to be a leaner, more modern
API in the shape of fetch(). My motivation came from
&lt;a href=&quot;https://github.com/reactjs/redux/issues/723#issuecomment-139927639&quot;&gt;this post&lt;/a&gt;
about waiting for multiple async calls in Redux. I&#39;d been using jQuery (or a layer on top
of jQuery such as Backbone) to talk to remote servers since
James Blunt hit the charts with &quot;You&#39;re Beautiful&quot;. And since moving
to React it didn&#39;t seem to make much sense to pull in all of jQuery just
to make a few simple remote calls - so trusting in Dan Abramov (has he
ever put a foot wrong?!) I decided to polyfill in fetch() and friends,
and embrace the simplicity of this new standard. Trouble is, it&#39;s not as
straightforward to get started as you might think it is.&lt;/p&gt;

&lt;p&gt;First up, my understanding of promises is fairly
rudimentary - basically they are a fancy way of returning a function
that will be called at some point in the future, and can handle a happy
code path and a sad code path. I&#39;d read that jQuery&#39;s way of doing promises
(deferreds) &quot;are a bit… unhelpful&quot;. And that you should &lt;a href=&quot;http://www.html5rocks.com/en/tutorials/es6/promises/&quot;&gt;cast them to
standard promises, which is worth doing as soon as possible&lt;/a&gt;,
. So I had an immediate
distrust of jQuery&#39;s deferreds from what I had read and was ready to go
all in on the shiny new fetch() API to ensure that I was using the most
standard version of promises that bitcoins can buy. By this point
we&#39;re really up for doing the fetch() thing correctly.&lt;/p&gt;

&lt;p&gt;The first hit on Google for &quot;fetch javascipt&quot; is the
Mozilla Development Network&#39;s article on the Fetch API and from here it
is a short hop to the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch&quot;&gt;Using Fetch
article&lt;/a&gt;.
So I rushed to the first example, which is&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var myImage = document.querySelector(&#39;img&#39;);

fetch(&#39;flowers.jpg&#39;)
.then(function(response) {
  return response.blob();
})
.then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and wrote the equivalent code (slightly ES6-ified) that I needed which was...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fetch(&#39;my-json-serving-url&#39;)
.then(response =&amp;gt; {
  debugger
  //return response.blob();
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I got rid of the second then() because I figured my use case is simpler than
theirs. And I figured that if I could drop myself into the Chrome
debugger I could work out the appropriate method on the response
object to get whatever I needed out. It was all looking familiar and
simple, just like it said on the tin.&lt;/p&gt;

&lt;p&gt;So I got to my breakpoint and I saw a friendly &lt;code&gt;text()&lt;/code&gt; method available
as well as a &lt;code&gt;json()&lt;/code&gt; method. And indeed I called them - and
frustratingly got the following back in my JS console...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[[PromiseStatus]] : &quot;resolved&quot;
[[PromiseValue]] : undefined
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So I googled around for &quot;pending status fetch promise&quot; and the first hit
was &lt;a href=&quot;http://stackoverflow.com/questions/30329485/why-is-the-promise-still-pending&quot;&gt;StackOverflow&lt;/a&gt; -
trusting in StackOverflow (have they ever put a foot wrong?!) I
clicked through to question but saw the answer didn&#39;t look quite as relevant to me
as I&#39;d hoped. So I moved along - along to lots of articles like
&lt;a href=&quot;https://github.com/w3c/ServiceWorker/issues/625&quot;&gt;this&lt;/a&gt;, which sounded
very complicated for the &quot;Hello World!&quot; of the fetch() world that I was
trying to piece together, so I gave up. I knew that there was
new-fangled streaming stuff in the new fetch() and I must be tripping up
on that - might be best to read about that on my aging Nexus phone on
the commute home.&lt;/p&gt;

&lt;p&gt;As I was closing down the hundreds of tabs I had opened about fetch() - one by one - like a
roadie taking down marquees at the end of a music festival, I paused
before X-ing
the tab where it had all
&lt;a href=&quot;https://github.com/reactjs/redux/issues/723#issuecomment-139927639&quot;&gt;started&lt;/a&gt;.
It occurred to me that instead of going for the cheapest item in the
shop, I should probably try the second cheapest. I&#39;ll
try two then() calls one after the other.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fetch(&#39;my-json-serving-url&#39;)
.then(response =&amp;gt; {
  return response.json();
})
.then(responseBody =&amp;gt; {
  debugger
  // oh responseBody, just please have something in you that isn&#39;t pending!
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Boom! Like a green light at the end of a unit test there was finally
something tangible in the responseBody argument. Encouraged by this I
could now make sense of more of the original Mozilla Developer Network
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch&quot;&gt;page&lt;/a&gt;,
in particular their Checking For Success example...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fetch(&#39;flowers.jpg&#39;).then(function(response) {
  if(response.ok) {
    response.blob().then(function(myBlob) {
      var objectURL = URL.createObjectURL(myBlob);
      myImage.src = objectURL;
    });
  } else {
    console.log(&#39;Network response was not ok.&#39;);
  }
})
.catch(function(error) {
  console.log(&#39;There has been a problem with your fetch operation: &#39; +
error.message);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I didn&#39;t give a monkey&#39;s for checking for success in my embryonic
attempt at calling fetch() earlier. But now I could see that I could do
the chaining all in one...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fetch(&#39;my-json-serving-url&#39;)
.then(response =&amp;gt; {
  response.json().then(responseBody =&amp;gt; {
    debugger
    console.log(responseBody)
    // Go&#39;on the responseBody, ya beauty!
  })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The ES5 equivalent is something like...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;fetch(&#39;my-json-serving-url&#39;)
.then(function(response){
  response.json().then(function(responseBody){
    console.log(responseBody)
  })
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Call it perceptual narrowing when my initial attempt went pear-shaped,
or call it laziness, or stupidity. Whatever it was, that was one long journey towards
calling fetch(). Anyway, I hope someone else finds this useful and
doesn&#39;t have to travel around the Internet a dozen times to ditch the
dollar and fire off a fetch().&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>I've Got 409 Problems but the Status Header Ain't One</title>
   <link href="http://www.theirishpenguin.com/2015/03/20/ive-got-409-problems-but-the-status-header-aint-one.html"/>
   <updated>2015-03-20T10:50:16+00:00</updated>
   <id>http://www.theirishpenguin.com/2015/03/20/ive-got-409-problems-but-the-status-header-aint-one</id>
   <content type="html">&lt;p&gt;A correction...&lt;/p&gt;

&lt;p&gt;&lt;figure style=&quot;float: right; margin:20px;&quot;&gt;&lt;img src=&quot;/assets/images/409image.png&quot; alt=&quot;409 Image&quot; /&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;During last night&#39;s talk on the &lt;a href=&quot;https://github.com/theirishpenguin/js_application_reloader&quot;&gt;JS Application Reloader gem&lt;/a&gt;, I mentioned that when the gem&#39;s back end code detects a reload of the application is required it sends a HTTP 409 to the client. But to use the &lt;a href=&quot;https://www.youtube.com/watch?v=xwdba9C2G14&quot;&gt;Chewbacca defence&lt;/a&gt;, &quot;That does not make sense!&quot; A 409 indicates a conflict.&lt;/p&gt;

&lt;p&gt;Rather, the gem never sent back a 409 and never will. Instead, it returns a HTTP header to indicate an expired status (by default this header is called &quot;X-Js-Application-Reloader-Status&quot;). It is this that indicates to the client that the application needs to be reloaded. Incidentally, the gem does allow you to configure a HTTP status code to send back in this situation if you want to (currently the default is 200, which should probably be changed).&lt;/p&gt;

&lt;p&gt;So where did the pesky 409 come from? Well, it became ingrained in my brain as I&#39;m working on another project to handle optimistic locking - which does indeed send back a 409 when a conflict in records is detected. Nothing to do with JS Application Reloader at all :-) It&#39;s like comparing Apples and Androids.&lt;/p&gt;

&lt;p&gt;For now, I&#39;m making 409 my new lucky number!&lt;/p&gt;

&lt;p&gt;Great meetup last night. Thanks to everyone for making it such fun!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Purity of the Potato</title>
   <link href="http://www.theirishpenguin.com/2014/10/03/the-purity-of-the-potato.html"/>
   <updated>2014-10-03T07:23:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2014/10/03/the-purity-of-the-potato</id>
   <content type="html">&lt;p&gt;&lt;figure style=&quot;float: right; margin:20px;&quot;&gt;&lt;img src=&quot;/assets/images/512px-Potato_123.jpg&quot; alt=&quot;Potato&quot; width=&quot;360px&quot; /&gt;&lt;figcaption style=&quot;font-style: italic; margin-top: 5px; width:360px&quot;&gt;&lt;a href=&quot;http://commons.wikimedia.org/wiki/File:Potato_123.jpg&quot;&gt;Photo&lt;/a&gt; by &lt;a href=&quot;http://commons.wikimedia.org/wiki/User:Tahir_mq&quot;&gt;Tahir mq&lt;/a&gt; under the &lt;a href=&quot;http://en.wikipedia.org/wiki/en:Creative_Commons&quot;&gt;CC&lt;/a&gt; &lt;a href=&quot;http://creativecommons.org/licenses/by-sa/3.0/deed.en&quot;&gt;Attribution-Share Alike 3.0 Unported&lt;/a&gt; licence&lt;/figcaption&gt;&lt;/figure&gt;&lt;/p&gt;

&lt;p&gt;Pity the potato. It&#39;s &lt;a href=&quot;http://www.potato.ie/national-potato-day/&quot;&gt;National Potato Day&lt;/a&gt;, yet our once budding superstar’s been trending downwards ever since huntergathers began dragging their knuckles to the dining table. A carb allergy has infected the nation leaving the humble potato about as popular as a water tax at a car wash. How did the potato turn from staple diet of the people to an episode of Man v Spud? It just wanted to be your spuddy buddy. Leave aside the fact that this vegetable can conjure up more pun potential than Buzzfeed can whip up kitten stories...&lt;/p&gt;

&lt;p&gt;To understand what happened, we need to understand how this noble vegetable starved then conquered a nation. According to popular legend, it all started with another noble - Sir Walter Raleigh. Back then, a good chipper was just a twinkle in Leo Burdock&#39;s eye. In a field in East Cork, Sir Walter declared &quot;What&#39;s up Youghal? Here&#39;s some potatoes!&quot; And the rest is (slightly made up) history. Once we&#39;d a taste for it, our beloved tuber easily out-muscled other foods. Apparently the choice at the time was somewhat limited.&lt;/p&gt;

&lt;p&gt;Other accounts say that the first spud washed up on the shores of Cork, like some glorious cuisine in a bottle from God, just after the Spanish Armada came a cropper. It has also been written that the potato&#39;s introduction into England did not go well, taking flak in newspaper editorials and preachers&#39; sermons at the time. The man on the street wouldn&#39;t touch it with yours, and rumour had it that potatoes would leave the soil as sterile as a mule convention. Oh, and they made you sick and could cause death. Even Mr Tayto couldn&#39;t talk you into taking a trip to Tayto Park in those days.&lt;/p&gt;

&lt;p&gt;That was then and this is now. Chippies have been ever popular in the best little country in the world. We love our spuds! But the downward spiral here began once Irish restaurants and avid cooks convinced diners to accept things like polenta and couscous. Polenta, a miserable lump which has the texture of damp sawdust, and tastes slightly worse, makes the starting lineup on many a menu. Couscous&#39; only useful contribution to society is perhaps in the debate over how exactly to pronounce it. Do you go with the lawdy daw Dublin 4 &quot;Koous koous&quot; or the more friendly cat-herding &quot;Kus kus&quot;.&lt;/p&gt;

&lt;p&gt;Here kus kus...&lt;/p&gt;

&lt;p&gt;In Jamie Oliver&#39;s Italian, which does a fine burger, you have to plead your case to ensure your chippies are not doused in garlic, parsley and truffle oil. Whatever happened to the purity of the potato? No nonsense, just a bit of complex carbohydrate and a sprinkle of salt. Hipster eateries offer no respite. In Crackbird you won&#39;t even find a chip on the menu - where&#39;s the craic in that? And don&#39;t start on about sweet potatoes. They&#39;re the kind of thing you should only hear from Robin, pre-Dark Knight, excitedly muttering &quot;Sweet potatoes, Batman!&quot; as the Penguin makes off with the bag of chips that fell from his utility belt.&lt;/p&gt;

&lt;p&gt;Official health guidelines are just as scathing. The &quot;5 A Day&quot; police won&#39;t even count a Maris Piper towards your total, just a big fat potato-shaped zero. But it would be unwise to back against the tenacious potato making a comeback. The current crop of diets will ultimately fall out of flavour. Yes, technically on its own the potato will send your blood sugar levels into orbit with Richard Branson and his partying, &lt;a href=&quot;http://www.thejournal.ie/richard-branson-holiday-time-1688143-Sep2014/&quot;&gt;unlimited-holiday time employees&lt;/a&gt;. But what your gym instructor didn&#39;t tell you is that if you eat your Roosters with a side of meat, its GI drops quicker than Arjen Robben on an ice rink. So no your blood won&#39;t turn to custard. Just sit back, relax, peel a spud and simply enjoy. Of course that doesn&#39;t help us resist all those glorious damn potato flavoured puns that we could drop in here.&lt;/p&gt;

&lt;p&gt;Must... not... mention... going viral on youtuber...  It&#39;s... Golden... Wonder... we... got.. this... far... Dammit!&lt;/p&gt;

&lt;p&gt;Happy National Potato Day, Youghal!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Batshift Crazy - Basic Binary Number Representation in Javascript</title>
   <link href="http://www.theirishpenguin.com/2013/08/02/batshift-crazy-basic-binary-number-representation-in-javascript.html"/>
   <updated>2013-08-02T11:08:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2013/08/02/batshift-crazy-basic-binary-number-representation-in-javascript</id>
   <content type="html">&lt;p&gt;In today&#39;s &lt;a href=&quot;http://www.meetup.com/dublin-code-kata/&quot;&gt;Dublin Code Kata&lt;/a&gt;, we revisited a bit of classic Comp Sci - integer vs binary representation of numbers! And I learned that converting integers to binary numbers isn&#39;t all that hard in Javascript :)&lt;/p&gt;

&lt;p&gt;For example, to convert the integer 4 to the binary number 100 you use...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(4 &amp;gt;&amp;gt; 0).toString(2) # gives &quot;100&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And if you want to do chopping of right most digits change the 0 to the number of digits you want to chop off...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(4 &amp;gt;&amp;gt; 1).toString(2) // gives &quot;10&quot;
(4 &amp;gt;&amp;gt; 2).toString(2) // gives &quot;1&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Or if you want to append zeros, use the opposite...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(4 &amp;lt;&amp;lt; 0).toString(2) // still gives &quot;100&quot;
(4 &amp;lt;&amp;lt; 1).toString(2) // still gives &quot;1000&quot;
(4 &amp;lt;&amp;lt; 2).toString(2) // still gives &quot;10000&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These are called right shift (&gt;&gt;) and left shift operators (&amp;lt;&amp;lt;) and there is a variation on the right shift called a zero-fill right shift (&gt;&gt;&gt;), as opposed to a sign-propagating right shift (good old &gt;&gt;). The difference becomes interesting when you deal with numbers that don&#39;t fit into a 32 bit integer (the upper bound being the magical &lt;a href=&quot;http://en.wikipedia.org/wiki/2147483647&quot;&gt;2147483647&lt;/a&gt; ).&lt;/p&gt;

&lt;p&gt;So if we take a cool two and a half billion we see&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(2500000000 &amp;gt;&amp;gt; 0).toString(2) // gives &quot;-1101010111111010000011100000000&quot;
(2500000000 &amp;gt;&amp;gt;&amp;gt; 0).toString(2) // gives &quot;10010101000000101111100100000000&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And that all stemmed from today&#39;s enjoyable challenge &lt;a href=&quot;http://codekata.pragprog.com/2007/01/code_kata_fifte.html&quot;&gt;A Diversion&lt;/a&gt;. Thanks to &lt;a href=&quot;https://twitter.com/pragdave&quot;&gt;Prag Dave&lt;/a&gt; for sharing! And thanks to &lt;a href=&quot;https://twitter.com/_minuteman3&quot;&gt;Miles McGuire&lt;/a&gt; for bringing the bitshift brains and explaining the more esoteric cases!&lt;/p&gt;

&lt;p&gt;Here&#39;s some more on &lt;a href=&quot;http://en.wikipedia.org/wiki/Bitwise_operation&quot;&gt;bitwise operators&lt;/a&gt; and more on &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators&quot;&gt;bitwise operators in Javascript&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Rails Girls Revolution</title>
   <link href="http://www.theirishpenguin.com/2013/02/11/rails-girls-revolution.html"/>
   <updated>2013-02-11T13:58:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2013/02/11/rails-girls-revolution</id>
   <content type="html">&lt;p&gt;&lt;img src=&quot;https://pbs.twimg.com/media/BCqzUecCEAMj4OO.jpg:large&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Your first day programming is always going to be a challenging one. It&#39;s hard enough to learn a new language to speak to another human, never mind trying to unravel the mother tongue of a machine. Probably the best way to tackle this challenge is with a sense of mischief, fun and divilment, and a raft of like-minded people. These ingredients made for the perfect recipe that was &lt;a href=&quot;http://railsgirls.com/dublin&quot;&gt;Rails Girls Dublin&lt;/a&gt;, an informal mini-conference like event, that took place at the &lt;a href=&quot;http://www.ndrc.ie/&quot;&gt;NDRC&lt;/a&gt; in Digital Hub on Friday and Saturday.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The usually male-dominated field of software development was turned on it&#39;s head for a weekend as an attendee list of 50 girls and women set out to learn web programming and art of glueing the cloud together. This was done through &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Ruby on Rails&lt;/a&gt; - a programming language and toolbox for building web applications in a clear and easy to understand way. This also makes it suitable for newcomers to programming to start off coding and having fun straight away. Ruby is the programming language and Rails is a set of extras that make it particularly useful for the web. Rails Girls is a global organisation that helps make this happen.&lt;/p&gt;

&lt;p&gt;The weekend started off after work on Friday with an installation fest with the simple goal of getting Ruby on Rails onto everyone&#39;s computer - regardless of whether it tasted like an Apple or was some flavour of Windows or Linux. This was a good chance for everyone to get to know each other, break the ice and get a sense of the fantastic atmosphere that was going to engulf the weekend. Afterwards there was a sponsored meal for the coaches, where one impressive fact became apparent - there was a 50/50 male/female ratio within the coaching group. Something that wasn&#39;t expected when Rails Girls Dublin was starting out.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://pbs.twimg.com/media/BCqKNj0CcAAN7Z7.jpg:large&quot; alt=&quot;Diamonds are a girls best friend but gems are even better&quot; style=&quot;width:50%;margin-left:10px&quot; align=&quot;right&quot; border=&quot;0&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Saturday began at a relaxing pace with some breakfast and two batches of awesome cupcakes, one by &lt;a href=&quot;http://monacocupcakes.ie&quot;&gt;Monaco Cupcakes&lt;/a&gt; and another by Rails Girl &lt;a href=&quot;http://twitter.com/caitrionadwyer&quot;&gt;Caitriona Dwyer&lt;/a&gt;. Then, after a word from the generous sponsors (checkout the list at the end of this post), there was an introductory session on design by &lt;a href=&quot;https://twitter.com/simonrand&quot;&gt;Simon Rand&lt;/a&gt; who had a few tips in there that even old hands could take onboard. Then, despite the best efforts of the Internet trying to work against me, I did a quick session introducing Ruby and the basics of programming. It was really fun going through Ruby with such an interested and engaged audience; and incredible to think that everyone there could call themselves a programmer - in one way or another - by the end of the day.&lt;/p&gt;

&lt;p&gt;One final bit of preparation was a &quot;Bento Box&quot; session with &lt;a href=&quot;http://twitter.com/emcastles&quot;&gt;Emily Castles&lt;/a&gt;, the unstoppable driving force behind Rails Girls Dublin. This got everyone to categorize some of the techie jargon that crops up in web development into different compartments - hence just like a Bento Box! If you missed out on those talks the good news is that you can catch up on Simon&#39;s &lt;a href=&quot;https://speakerdeck.com/simonrand/designing-your-app&quot;&gt;slides&lt;/a&gt; online and go through the basics of Ruby at &lt;a href=&quot;http://www.tryruby.org&quot;&gt;tryruby.org&lt;/a&gt; in your own time.&lt;/p&gt;

&lt;p&gt; Then the main event started, where attendees flipped open their laptops and started hacking on their own Rails application, following a set of guides put together by the fantastic international Rails Girls organisation. Over the course of the day, their applications evolved from a skeleton Rails program, through to one that could handle the uploading and publishing of pictures, before finally being deployed live to a website running online. Here&#39;s a selection of tweets that sum up some of the experiences on this journey,&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://s1307.beta.photobucket.com/user/theirishpenguin/media/self_learn_zps6f731a02.png.html&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://i1307.photobucket.com/albums/s584/theirishpenguin/self_learn_zps6f731a02.png&quot; border=&quot;0&quot; alt=&quot; photo self_learn_zps6f731a02.png&quot;/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div style=&quot;clear: both;&quot;&gt;&amp;nbsp;&lt;/div&gt;


&lt;p&gt;&lt;a href=&quot;http://s1307.beta.photobucket.com/user/theirishpenguin/media/rails_easy_install_zps86d8f2c7.png.html&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://i1307.photobucket.com/albums/s584/theirishpenguin/rails_easy_install_zps86d8f2c7.png&quot; border=&quot;0&quot; alt=&quot; photo rails_easy_install_zps86d8f2c7.png&quot;  align=&quot;right&quot;/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div style=&quot;clear: both;&quot;&gt;&amp;nbsp;&lt;/div&gt;


&lt;p&gt;&lt;a href=&quot;http://s1307.beta.photobucket.com/user/theirishpenguin/media/awesome_job_zps916b0fe1.png.html&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://i1307.photobucket.com/albums/s584/theirishpenguin/awesome_job_zps916b0fe1.png&quot; border=&quot;0&quot; alt=&quot; photo awesome_job_zps916b0fe1.png&quot;/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div style=&quot;clear: both;&quot;&gt;&amp;nbsp;&lt;/div&gt;


&lt;p&gt;&lt;a href=&quot;http://s1307.beta.photobucket.com/user/theirishpenguin/media/sarah_great_day_zps820b8e72.png.html&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://i1307.photobucket.com/albums/s584/theirishpenguin/sarah_great_day_zps820b8e72.png&quot; border=&quot;0&quot; alt=&quot; photo sarah_great_day_zps820b8e72.png&quot; align=&quot;right&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;div style=&quot;clear: both;&quot;&gt;&amp;nbsp;&lt;/div&gt;


&lt;p&gt;Finally, there was a set of great lightning talks before &lt;a href=&quot;http://twitter.com/kategoodbody&quot;&gt;Kate Goodbody&lt;/a&gt; brought the curtain down on Rails Girls Dublin - live coding a Ruby on Rails blog in under 10 minutes as stirring music boomed over the speakers. There wasn&#39;t as much as a single misguided keystroke and it was a wonderful end to a tremendous day of code.&lt;/p&gt;

&lt;p&gt;More generous sponsorship meant that was no fighting over the bill at Arthur&#39;s pub around the corner, where most of us had the chance to go afterwards. Like at many events, the evening was a real highlight as everyone shared their ideas for projects (some of which are already underway) and ways to keep the fire lit this weekend burning.&lt;/p&gt;

&lt;p&gt;The future will be written in code. Google will possibly be one of the biggest car companies in 10 years time; they have a &lt;a href=&quot;http://www.youtube.com/watch?v=cdgQpa1pUUE&quot;&gt;self driving car&lt;/a&gt;. Wearable technology will be woven into the clothing we buy. Every inanimate object we currently see around us will, over time, be transformed into something that reacts to us with software smarts. Whether all this is a good thing or a bad thing is up for debate. What is certain is that it&#39;s crucial that girls and women are represented in the next wave of technology in a way they previously weren&#39;t.&lt;/p&gt;

&lt;p&gt;The next challenge for Rails Girls Dublin will be around how to build on the great start that was made this weekend. With so many attendees, coaches and organisers interested and passionate about making this work, it&#39;s a vision that has every chance of succeeding and surpassing its original goals!&lt;/p&gt;

&lt;p&gt;Sponsors
* &lt;a href=&quot;http://www.inventorium.org/&quot;&gt;Inventorium&lt;/a&gt;
* &lt;a href=&quot;http://www.redhills.ie/&quot;&gt;Red Hills Software&lt;/a&gt;
* &lt;a href=&quot;http://www.paddypower.ie/&quot;&gt;Paddy Power&lt;/a&gt;
* &lt;a href=&quot;http://www.engineyard.com/&quot;&gt;Engine Yard&lt;/a&gt;
* &lt;a href=&quot;http://www.kablingy.ie/&quot;&gt;Kablingy&lt;/a&gt;
* &lt;a href=&quot;http://www.bizimply.com/&quot;&gt;Bizimply&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Resources:&lt;br/&gt;
&lt;a href=&quot;http://railsgirls.com/dublin&quot;&gt;Dublin section of the Rails Girls website&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://www.tryruby.org&quot;&gt;Tryruby.org - a simple and fun interactive tutorial to get started with Ruby&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://guides.railsgirls.com/app/&quot;&gt;The Rails Girls App we build on Saturday (tutorial)&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;https://speakerdeck.com/simonrand/designing-your-app&quot;&gt;Designing your app (slides form Simon&#39;s talk)&lt;/a&gt;&lt;br/&gt;
&lt;a href=&quot;http://blog.intercom.io/wireframing-for-web-apps/&quot;&gt;Wireframing for web apps (from the Intercom blog)&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Geekslam 1 - NoSQL vs RDBMS</title>
   <link href="http://www.theirishpenguin.com/2012/12/10/geekslam_1_nosql_vs_rdbms.html"/>
   <updated>2012-12-10T10:00:00+00:00</updated>
   <id>http://www.theirishpenguin.com/2012/12/10/geekslam_1_nosql_vs_rdbms</id>
   <content type="html">&lt;p&gt;Geeks are ending 2012 with a serious bang, after a year that has been so jam packed with tech events that it&#39;s bloody hard to unearth an evening not already occuppied by some tech occasion. Following hot on the heels of the usual post summer conference season, you&#39;d think that Javascripters, Pythonistas, PHPers, Rubyists, .NETers, Nodies, Erlangers (a title that would make for an awesome Cork meetup!) and Objective-C types would waving the white flag and catching up on some zzz&#39;s ahead of Christmas. But no! They&#39;re still kicking ass. Two examples from just this week were &lt;a href=&quot;https://tito.io/league-of-facepalm/dublin-geek-slam&quot;&gt;Geekslam&lt;/a&gt; and the &lt;a href=&quot;http://codingday.org&quot;&gt;Global Day of Code Retreat&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Geekslam saw two teams of geeks from various user groups face off on a topic chosen by those who attended. After coming up with a short list, including things like Native vs Web Apps and iOS vs Android, the night was going to be won or lost on the basis of that dinner time conversation classic - &quot;Relational DBs vs NoSQL&quot;. First up though there were talks on a set of subjects as varied as the audience.&lt;/p&gt;

&lt;p&gt;Simon Rand from Dublin JS presented on Appcelerator Titanium, with some of the big takeway points being that it can save you a bunch of time across platforms and give good code reuse as well as being pretty fast, unless you need bleeding raw perfromance for something like gaming. Vinny Glennon from Ruby Ireland talked about some cracking gems he uses to make him a more productive day to day. Not only did this help inform Rubyists about handy tools and libraries they may be missing out on, it also paved the way later for discussion on how other languages/platforms solved similar problems. Next up was Andrew Smith from Dublin ALT.NET who talked about RX.js - a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators. And completing the talks featuring Javascript love was Richard Rodger, presenting on NodeJS, before taking a breather to sharpen his NodeJS duelling pistol. Ulrich Dangel from Python Ireland gave a great overview of a topic of interest to many devs - GIS Development. And finally, Valdimar Kristjansson explained to us, &quot;Why I love Erlang.&quot;&lt;/p&gt;

&lt;p&gt;Before the ultimate event started there was even time for a mini-battle between NodeJS and Erlang. After both trading blows and scoring impressive points the bout was edged by Erlang, showing that there&#39;s life in the old dog yet, though the Node team did unveil a snazzy NodeCopter later on - so perhaps the Erlang User group is going to be subjected to drone attacks until the next showdown!&lt;/p&gt;

&lt;p&gt;Then onto the main course - the Geekslam - where the audience tweeted some pretty zany situations for NoSQL and RDBMS&#39;s to duke it out (to give you a flavour, consider &quot;AI for global thermonuclear war targetting system from satellite, submarine &amp;amp; silo launch platforms&quot;).&lt;/p&gt;

&lt;p&gt;There were rules. There were marks deducted for below the belt hits. There were double points for &quot;sophisticated trolling&quot;. There was a team of judges who at times appeared to struggle to stay out of the debate. And there was a winner - the unaminous decision went to NoSQL. So keep an eye out for that global thermonuclear war targetting system running on MongoDB!&lt;/p&gt;

&lt;p&gt;It was all good natured fun. The debates rumbled on. Once EngineYard had locked its doors there were still geeks slammin in the Schoolhouse Hotel, then down the canal and finally in the Portobello. Though by that stage there was probably less sophisticated trolling going on!&lt;/p&gt;

&lt;p&gt;Hats off to the EngineYard - the host venue for the evening, the providers of pizza and the contributors of craft beer. And a big hand for the sponsors, &lt;a href=&quot;http://www.nearform.com&quot;&gt;NearForm&lt;/a&gt; who contributed a NodeCopter to the prize list, and &lt;a href=&quot;http://www.demonware.net&quot;&gt;Demonware&lt;/a&gt; who put up a Special edition copy of Black Ops II. And thanks to Paul Campbell and &lt;a href=&quot;http://tito.io&quot;&gt;Tito&lt;/a&gt; for making ticketing enjoyable! EngineYard&#39;s Eamon Leonard did a fantastic job managing the fray - perhaps a career as a boxing referee beckons, maybe even &lt;a href=&quot;http://t.co/X7i5haNm&quot;&gt;chess boxing&lt;/a&gt;. Talk of another Geekslam in January is already underway. Doesn&#39;t look like it&#39;s going to get any easier to find spare evenings for new tech meetups in 2013 either...&lt;/p&gt;

&lt;p&gt;Phew! To save your scrolling thumbs, the Global Day of Code Retreat will be handled in a separate posting :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Search Engine Friendly Redirects for Custom Domains on OpenShift using a .htaccess file</title>
   <link href="http://www.theirishpenguin.com/2012/09/11/search-engine-friendly-redirects-for-custom-domains-on-openshift-using-a-htaccess-file.html"/>
   <updated>2012-09-11T22:58:10+00:00</updated>
   <id>http://www.theirishpenguin.com/2012/09/11/search-engine-friendly-redirects-for-custom-domains-on-openshift-using-a-htaccess-file</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;https://openshift.redhat.com&quot;&gt;OpenShift&lt;/a&gt; provides an easy way to
host your Ruby based blogs (built on
Sinatra or Jekyll) or Wordpress site, without incurring expense. Being
content heavy, these kind of apps should really not have
&lt;a href=&quot;http://en.wikipedia.org/wiki/Duplicate_content&quot;&gt;duplicate content&lt;/a&gt; on different domains out there on that crazy ass Internet. Them spiders just won&#39;t like you as much!&lt;/p&gt;

&lt;p&gt;So what do you do when you have your app at
&lt;code&gt;http://foo-example.rhcloud.com&lt;/code&gt; and &lt;code&gt;http://www.example.com&lt;/code&gt; because
you&#39;ve set up a &lt;a href=&quot;https://openshift.redhat.com/community/blogs/custom-url-names-for-your-paas-applications-host-forwarding-and-cnames-the-openshift-way&quot;&gt;custom
domain&lt;/a&gt; - will that split your SEO Google juice?&lt;/p&gt;

&lt;p&gt;The solution is to use a bit of
&lt;a href=&quot;http://httpd.apache.org/docs/current/mod/mod_rewrite.html&quot;&gt;.htaccess&lt;/a&gt; magic in order to use
permanent 301 redirects to shepherd on traffic arriving at
http://foo-example.rhcloud.com to http://www.example.com&lt;/p&gt;

&lt;h3&gt;Solution for Ruby&lt;/h3&gt;

&lt;p&gt;Here&#39;s a example .htaccess file for a Jekyll/Sinatra hybrid app. It can
be dropped under your example_app/public directory.&lt;/p&gt;

&lt;p&gt;(Note: public can be used instead of a _site directory
for convenience on OpenShift)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;IfModule mod_rewrite.c&amp;gt;
RewriteEngine On
&amp;lt;/IfModule&amp;gt;

RewriteCond %{HTTP_HOST} ^foo-example.rhcloud.com$
RewriteRule (.*)$ http://www.example.com/$1 [R=301,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But if you rebuild a Jekyll site locally it will blow away the .htaccess
file if you put it under your example_app/public directory. So I leave
it in the root directory. Then you can use a &lt;code&gt;action hook&lt;/code&gt; to move it
from the root directory of your app to under the example_app/public
directory. Here it is and you can put it in the file &lt;code&gt;example_app/.openshift/action_hooks/deploy&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Move .htaccess from root folder to public folder on every deploy
mv $HOME/app-root/repo/.htaccess $HOME/app-root/repo/public/.htaccess

# Paranoidly ensuring sane permissions (in case we check in dodgy perms)
chmod 644 $HOME/app-root/repo/public/.htaccess
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The last line ensures that the .htaccess file has the correct
permissions. If you have a Wordpress site instead you should still carry
&lt;code&gt;chmod 644 example_app/php/.htaccess&lt;/code&gt; before you check it into git the
first time - just to be on the safe side.&lt;/p&gt;

&lt;h3&gt;Solution for Wordpress&lt;/h3&gt;

&lt;p&gt;Here&#39;s a example .htaccess file for a Wordpress site, which you can drop
under your example_app/php directory. Just replace
foo-example.rhcloud.com with your app URL and http://www.example.com
with your custom domain URL.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# BEGIN WordPress
&amp;lt;IfModule mod_rewrite.c&amp;gt;
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
&amp;lt;/IfModule&amp;gt;
# END WordPress

RewriteCond %{HTTP_HOST} ^foo-example.rhcloud.com$
RewriteRule (.*)$ http://www.example.com/$1 [R=301,L]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Again, remember to do a chmod 644 on the .htaccess file like above in the
Ruby section to ensure it has the correct permissions.&lt;/p&gt;

&lt;h3&gt;Testing&lt;/h3&gt;

&lt;p&gt;With all the above in place, your next &lt;code&gt;git push&lt;/code&gt; should
deliver you the redirecting experience you are looking for! Just visit
your app URL at http://foo-example.rhcloud.com and hopefully you are
whisked away to your custom domain URL. Thanks to the guys on the OpenShift
forums, especially kpendic and statikip for taking the time to help out with this.&lt;/p&gt;

&lt;p&gt;Till the next time, keep it Shifty!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>SpreeConf 2012 Day 1 with an Incredible Ecommerce Community</title>
   <link href="http://www.theirishpenguin.com/2012/08/29/spreeconf-2012-day-1-with-an-incredible-ecommerce-community.html"/>
   <updated>2012-08-29T13:58:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2012/08/29/spreeconf-2012-day-1-with-an-incredible-ecommerce-community</id>
   <content type="html">&lt;p&gt;It&#39;s great to hear a conference open with the quote&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Open Source projects are partly about technology and massively about community [David Brady, Ruby Rogues #51]&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This was how Chris Mar introduced &lt;a href=&quot;http://spreecommerce.com/&quot;&gt;Spree Commerce&lt;/a&gt; to us, setting the tone for the two days of E-commerce, Ruby and Javascript related action at the Guinness Storehouse in Dublin. It went down as an event which showed the best of Spree, the hospitality of the Irish and the folly of missing this event!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://p.twimg.com/A05ESuDCAAA2ki2.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Unfortuntely, due to work commitments I missed half of the talks, so this is an incomplete account. There were also a few gaps in memory due to a whiskey surprise (more on that later) and the occasional pint of Guinness, but that was to be expected :)&lt;/p&gt;

&lt;h3&gt;The Night Before&lt;/h3&gt;

&lt;p&gt;But first there was the small matter of pre-conference drinks to get out of the way. Tuesday was the night and Kehoe&#39;s was the venue; doubling as a pre-conf party and a RubyIreland meetup to get the mix going. It served it&#39;s main aim pretty well - introducing the jet-lagged attendees to a tasty pint of Guinness or two and each other. There was a very nice vibe about the place and some even turned it up a notch or two by heading down to a local improv comedy gig.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/47513359@N03/7882885746/&quot; title=&quot;Kehoes by theirishpenguin, on Flickr&quot;&gt;&lt;img src=&quot;http://farm8.staticflickr.com/7258/7882885746_fc839b7fe9.jpg&quot; width=&quot;375&quot; height=&quot;500&quot; alt=&quot;Kehoes&quot; style=&quot;width:50%;padding-right:10px&quot; align=&quot;left&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;Day 1&lt;/h3&gt;

&lt;p&gt;The smell of hops always engulfs the Guinness Storehouse building where SpreeConf was being held. It&#39;s a pretty unique experience and a pleasant assault on the senses. Once the lanyards were dished out, the coffee-infused developers sat down to @cmar&#39;s intro to Spree Commerce and the community.&lt;/p&gt;

&lt;p&gt;Next up, Gregg Pollack walked us all through one of his interactive &lt;a href=&quot;http://www.codeschool.com/&quot;&gt;Code School&lt;/a&gt; video/codecasts, &quot;A Sip of CoffeeScript&quot;. His incredibly soothing hypnotic voice is good for videocasts - as well as being easy on the ears for hangovers. After the talk, it was in a discussion with Benoit Curdy (@bcurdy) on Twitter that it finally hit me that CoffeeScript has shifted from &quot;nice to have&quot; to &quot;must have&quot; territory; as it makes classic Class-based Object Oriented development possible (or at least the appearance of it).&lt;/p&gt;

&lt;p&gt;Unfortunately, that was my day 1 talks over. But for everyone else there was Testing Spree Stores and Extensions by M. Scott Ford and Intro to Backbone.js by Nick Gauthier to look forward to before a Group Tour of the Guinness Storehouse.&lt;/p&gt;

&lt;h3&gt;Night 1&lt;/h3&gt;

&lt;p&gt;&lt;img src=&quot;https://p.twimg.com/A1QTpZ8CMAE9_gj.jpg&quot; alt=&quot;99 Ice Cream&quot; style=&quot;width:50%;padding-left:10px&quot; align=&quot;right&quot;&gt;&lt;/p&gt;

&lt;p&gt;On the plus side I did make it back apres work - just in time for dinner. Two distinct groups emerged.&lt;/p&gt;

&lt;p&gt;Group 1: the classy, wine-sipping, Indian-lovin gourmands who went straight to Jaipur on George&#39;s St, which served up some incredible dishes. The crown jewel had to be the Lamb Chilli Fry - lamb cubes doused in tounge curling dry spices. Yum!&lt;/p&gt;

&lt;p&gt;Group 2: the &quot;keepin it real crew&quot;, out on a hunt for Beshoffs Fish&#39;n&#39;Chips. Some got 99&#39;s, some didn&#39;t. But everyone made it back for the Github sponsored Lightening Talks that evening... and the SpreeConf whiskey...&lt;/p&gt;

&lt;h3&gt;The What?&lt;/h3&gt;

&lt;p&gt;That&#39;s right - the Spree team had a specially customised Yellow Spot whiskey just for event. And it was smooth as Greg Pollocks voice! There must be one or two budding distillers in the Spree team. Maybe one day we&#39;ll see the Spree Distillery make its debut! But in the meantime, the razorsharp Nick Gauthier had to navigate his way through a suprise desk of unseen slides for a &#39;blind&#39; presentation. And navigate it he did!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/47513359@N03/7879956332/&quot; title=&quot;The SpreeConf 2012 Dublin Whiskey by theirishpenguin, on Flickr&quot;&gt;&lt;img src=&quot;http://farm8.staticflickr.com/7268/7879956332_ba230919e2.jpg&quot; width=&quot;375&quot; height=&quot;500&quot; alt=&quot;The SpreeConf 2012 Dublin Whiskey&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Phew... and that was just day 1... huzzah!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Where Ruby leads, others follow...</title>
   <link href="http://www.theirishpenguin.com/2011/06/24/where-ruby-leads-others-follow.html"/>
   <updated>2011-06-24T01:13:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2011/06/24/where-ruby-leads-others-follow</id>
   <content type="html">&lt;p&gt;In response to the question and comments on a recent linked in post discussing the suitability of various web platforms, including Ruby on Rails...&lt;/p&gt;

&lt;h3&gt;The first big decision&lt;/h3&gt;

&lt;p&gt;Firstly, whatever you choose, I would suggest using a platform that is Open Source. This means that the stack is effectively commoditised - giving access to a high quality platform that keeps your costs low today and into the future as you scale out and avoid being locked into the release cycle of one particular vendor. A big plus is that anytime you hit a problem, your engineers can drill right down into platform to diagnose and resolve it. This is a formula that&#39;s worked for for Google, Groupon, Amazon, Twitter and Facebook to mention a few.&lt;/p&gt;

&lt;h3&gt;Enter Ruby&lt;/h3&gt;

&lt;p&gt;I am of the opinion that Ruby and Rails is the likely the best web framework to use to build the vast majority of web applications out there. Since it&#39;s release, Rails has lead the way in terms of web development - promoting the Model-View-Controller pattern in a simple, easy-to-use manner as a way of creating web applications. Whilst that pattern has been around for a while Rails really put it on the radar for web apps. Along with it came a shift from unpopular SOAP webservices to a RESTful service architecture. And so too did easy to use AJAX techniques for building richer UI&#39;s because Rails bundled the Prototype library with it from an early stage. Rails has since continued to lead by incorporating the latest Javascript technologies into its ecosystem - such as node.js.&lt;/p&gt;

&lt;h3&gt;Dynamic Language = Dynamic Business&lt;/h3&gt;

&lt;p&gt;Because of the dynamic nature of the language, its strong use of conventions and the style of Ruby developers, you end up having much less code in your application. This win in terms of a smaller codebase is also true of projects developed using other dynamic languages such as Python. A smaller codebase has the usual touted benefits in terms of rapid development times and a more easily managed codebase. In particular, less boilerplate code.&lt;/p&gt;

&lt;p&gt;Using dynamic over static typing means that you have to have to write automated tests to cover your code. Some developers disagree with dynamic typing and say that the compile time checking of a static language is important. In my experience, this is not so. By writing automated tests to cover business cases I&#39;ve found that I catch a much more important class over of errors - business logic issues - while also covering the code paths for the edge cases that the static compiler would have checked. One of the ways static languages try to provide some of the flexibility of dynamic languages is through generics. This quickly leads to a type of complexity which I have found is much better, and more clearly handled, using a dynamic language. The clarity of the code, the ease of testing and the expressiveness and power of a language like Ruby has firmed up my thinking on this area. As a platform which has baked testing right into the core of its ethos, Ruby and Rails has lead the way in terms of integrating automated test frameworks into the developer&#39;s workflow. And a higher level, it has made it possible to bring business stakeholders and development teams together by introducing tools that allow one to express business features in terms that can easily be discussed with, implemented and tested by a developer. Cucumber is probably the best example of this, which like many other Ruby projects has caused a massive stir in the web community.&lt;/p&gt;

&lt;h3&gt;And the bad news...&lt;/h3&gt;

&lt;p&gt;So what are the pitfalls. I&#39;d agree that it is harder to find Ruby developers. Whilst many top tech locations have a massive amount of Ruby developers - such as San Fran or London - Ireland doesn&#39;t have those numbers. This is partially because we have lagged behind the technology curve a little in the past. But I&#39;m happy to say that this is something that has changed immeasurably over the last couple of years. There is a lot more developer meetings and grassroots activity, predominantly in those with an Open Source slant. This is a good news story not just for Ruby, but for the whole Irish tech sector. And I&#39;m sure that strong confident Irish companies will emerge as a result.&lt;/p&gt;

&lt;p&gt;Some companies do decide that certain parts of their solution are best written in a different language. There are some well tried paths to doing this with Ruby. For example, you can use JRuby to easily farm out some parts of your codebase to Java while retaining development agility for the rest of your codebase by keeping it in Ruby. However, needing to do this is very much the exception rather than the norm.&lt;/p&gt;

&lt;h3&gt;Building services and deployment&lt;/h3&gt;

&lt;p&gt;You indicated that you will be writing a service rather than a full fledged web application - another option you could consider is using the Ruby-based Sinatra as your web framework instead of Rails - which is a thinner layer, which some people prefer for building services such as github. That said, I would still personally go with Rails as there are more tutorials and guides available - particularly if it is your companies first time working with Ruby.&lt;/p&gt;

&lt;p&gt;For deployment, Heroku makes developing and deploying Ruby apps a breeze. It really is an exceptional platform which sits on top of Amazon&#39;s AWS. I would recommend taking a serious look at it at http://www.heroku.com before making a decision on which platform to choose.&lt;/p&gt;

&lt;p&gt;So, all in all, my long standing impression of Ruby and Rails is that it is web development done right. It has been the leader in pushing forward how developers and businesses develop websites and consigned the sprawling mess that existed before it to history. In the meantime other platforms have tried to copy some of its features, often less elegantly. As the same time Rails has accelerated the rate at which it pushes forward the web - the next release Rails 3.1 is breathtaking in its feature list.&lt;/p&gt;

&lt;p&gt;For these reasons I think Ruby is &#39;the&#39; web development language of the next decade. Whatever you decide, all the best with your venture. There are plenty of excellent platforms out there to choose from so it&#39;s a great time to be building the kind of high-scale web applications and services.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bundler installing gems into the wrong directory - mea culpa</title>
   <link href="http://www.theirishpenguin.com/2011/03/05/bundler-installing-gems-into-the-wrong-directory-mea-culpa.html"/>
   <updated>2011-03-05T22:44:15+00:00</updated>
   <id>http://www.theirishpenguin.com/2011/03/05/bundler-installing-gems-into-the-wrong-directory-mea-culpa</id>
   <content type="html">&lt;p&gt;So I spent an hour and a half last night unfairly swearing at the spork gem; and blaming it for everything from world hunger to banking crises! This is because somehow when installing spork I had managed to change the location that bundler installs gems into - strangely enough into a directory called ./spork under my project directory. And I figured the blame landed at the door of the spork gem. Here&#39;s what happened just so that you don&#39;t get caught out.&lt;/p&gt;

&lt;p&gt;Once installed, here&#39;s how you start up spork: bundle exec spork&lt;/p&gt;

&lt;p&gt;But, at some point, here&#39;s what I did by accident: bundle &lt;strong&gt;install&lt;/strong&gt; spork&lt;/p&gt;

&lt;p&gt;Fool! Fool! Fool! For those of you that aren&#39;t familiar with the &#39;path&#39; argument to bundler, well, what it does is permanently change your path to the value you specify. So for an hour and a half last night, I had ./spork set as my gem directory. Meaning that my furious efforts to correct the problem were in vain - such as clearing out all the gems and reinstalling, grepping for a config file that could be pointing at ./spork in my project and rvm directories.&lt;/p&gt;

&lt;p&gt;What I should have done to fix this problem immediately, was to tell bundler to use my standard rvm directory for gems again&lt;/p&gt;

&lt;p&gt;&lt;code&gt;bundle install --system&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ta da!&lt;/p&gt;

&lt;p&gt;It&#39;s pretty confusing that specifying a path argument &lt;em&gt;once off&lt;/em&gt; should cause bundler to change it behaviour on a &lt;strong&gt;permanent&lt;/strong&gt; basis but at least I notice that in the docs it says&lt;/p&gt;

&lt;p&gt;&lt;code&gt;The path argument to &#39;bundle install&#39; is deprecated. It will be removed in version 1.1. Please use &#39;bundle install --path spork&#39; instead.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So I guess I&#39;m not the only one who&#39;s hit this confusing behaviour. Long live the &lt;code&gt;--path&lt;/code&gt; option!&lt;/p&gt;

&lt;p&gt;Sorry spork, I&#39;m a dork...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Machinist 2 and the undefined method for Sham:Module error</title>
   <link href="http://www.theirishpenguin.com/2011/02/16/machinist-2-and-the-undefined-method-foo-for-shammodule-error.html"/>
   <updated>2011-02-16T00:56:59+00:00</updated>
   <id>http://www.theirishpenguin.com/2011/02/16/machinist-2-and-the-undefined-method-foo-for-shammodule-error</id>
   <content type="html">&lt;p&gt;This ain&#39;t no Sham marriage! Machinist 2 has done away with the Sham module. But, at time of writing, this isn&#39;t immediately obvious from the &lt;a href=&quot;https://github.com/notahat/machinist/wiki/Installation&quot;&gt;installation guide&lt;/a&gt;. So if you try to horseshoe your Machinist 1 (Sham-based) tests into Machinist 2 then you&#39;ll find you get an error like&lt;/p&gt;

&lt;p&gt;/home/you/dev/rails/my_project/spec/support/blueprints.rb:5:in &lt;code&gt;&#39;: undefined method&lt;/code&gt;name&#39; for Sham:Module (NoMethodError)&lt;/p&gt;

&lt;p&gt;The solution is to use the new serial_number() method technique instead. For more info on what&#39;s in Machinist 2 check out the &lt;a href=&quot;https://github.com/notahat/machinist/wiki/machinist-2&quot;&gt;What&#39;s new in Machinist 2&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;A short post but hopefully it helps someone. Mock on!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Push and pull data between your local MongoDB and Heroku or MongoHQ</title>
   <link href="http://www.theirishpenguin.com/2011/01/20/push-and-pull-data-between-your-local-mongodb-and-heroku-or-mongohq.html"/>
   <updated>2011-01-20T08:18:46+00:00</updated>
   <id>http://www.theirishpenguin.com/2011/01/20/push-and-pull-data-between-your-local-mongodb-and-heroku-or-mongohq</id>
   <content type="html">&lt;p&gt;Heroku do a great job of providing a free way to host MongoDB. The only slight issue I had was syncing data between my machine and my Heroku apps - in the way I was used to with their Taps plugin which works for Postgres databases. But here&#39;s how to do it for MongoDB. Note, I was using it with a Rails 3 and Ruby 1.9.2 app.&lt;/p&gt;

&lt;p&gt;Firstly you need to get Pedro Belo&#39;s super plugin &lt;a href=&quot;https://github.com/pedro/heroku-mongo-sync&quot;&gt;heroku-mongo-sync&lt;/a&gt; . The docs say that the default way to use it is just to do a &#39;heroku mongo:push&#39; or &#39;heroku mongo:pull&#39; from inside your app directory on your machine. But this takes the name of your app exactly and assumes that this is the name of your mongo database. Unfortunately, many people like to call their database something else - and even the default is yourappname_development which won&#39;t work (it must be &#39;yourappname&#39; exactly).&lt;/p&gt;

&lt;p&gt;A feature allowing you to specify a MONGO_URL shell variable that will let you override this is in the README. Sadly it didn&#39;t work for me. But help is at hand - we can just create a new enviroment for syncing and then specify the database we need as the default. Of course you don&#39;t have to do this if your database is actually exactly the same as your app already; though the following approach may still serve you well as a workflow&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pre-requiste, you must have an account setup on &lt;a href=&quot;https://mongohq.com&quot;&gt;MongoHQ&lt;/a&gt; for this to work. And see &lt;a href=&quot;http://docs.heroku.com/mongohq&quot;&gt;here&lt;/a&gt; for how to setup MongoDB on Heroku&lt;/li&gt;
&lt;li&gt;Copy your config/development.rb to config/sync.rb&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ok, I&#39;m using Mongoid. Here&#39;s how I define my db connection to be exactly the same as my app&#39;s name in my config/mongoid.yml file&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sync:
&amp;lt;&amp;lt;: *defaults
database: yourappname
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whenver you want to push or pull to Heroku just change the default Rails environment at the top of your config/application.rb file to be &#39;sync&#39;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;require File.expand_path(&#39;../boot&#39;, __FILE__)
ENV[&#39;RAILS_ENV&#39;] = &#39;sync&#39;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now from the command line, you should find &#39;heroku mongo:push&#39; and &#39;heroku mongo:pull&#39; work like a dream. Ahoy, me mongols!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Getting Pyzeemote running on MeeGo</title>
   <link href="http://www.theirishpenguin.com/2010/11/22/getting-pyzeemote-running-on-meego.html"/>
   <updated>2010-11-22T11:47:53+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/11/22/getting-pyzeemote-running-on-meego</id>
   <content type="html">&lt;p&gt;Pyzeemote allows a Zeemote controller to communicate with a running application over D-Bus. We&#39;re going to get it running on MeeGo today. All in all, getting this working will involve the following components&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python drivers for the Zeemote device (provided by Pyzeemote)&lt;/li&gt;
&lt;li&gt;A daemon which listens for Pyzeemote events and shepherds them onto the application over D-Bus (provided by Pyzeemote)&lt;/li&gt;
&lt;li&gt;A test suite which tells you if everything is working correctly (provided by Pyzeemote)&lt;/li&gt;
&lt;li&gt;Bluetooth python bindings (provided by 3rd party library PyBluez)&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;PRE-REQUISITES&lt;/h3&gt;

&lt;p&gt;The MeeGo machine these steps were carried out on was a Leveno IdeaPad, which had the MeeGo core repository disabled and the MeeGo test and devel repos enabled - as outlined at our earlier guide &lt;a href=&quot;http://www.theirishpenguin.com/2010/11/18/installing-ruby-and-rubygems-on-meego&quot;&gt;Installing Ruby and Rubygems on MeeGo&lt;/a&gt;. You may need to do this as well, as these repositories are likely the source of some of the libraries used in this guide. Furthermore you will need to install packages for building python bluezy bindings&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo zypper install gcc make python-devel bluez-libs-devel
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;PYZEEMOTE INSTALLATION STEPS&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a directory pyzee in your home directory&lt;/p&gt;

&lt;p&gt;   mkdir pyzee&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download &lt;a href=&quot;http://code.google.com/p/pyzeemote&quot;&gt;pyzeemote source on Google Code&lt;/a&gt; using svn&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you don&#39;t have svn you can just use the Browse functionality of Google Code and download (the raw version) of the following files manually:&lt;/p&gt;

&lt;p&gt;   pyzeemote-test.py, zeemote_listener.py, README&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whether you use svn or Browse simply ensure that you have the above 3 files at the top level of your pyzee directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download bluezy python bindings (PyBluez-0.18.tar.gz) which will work on MeeGo from &lt;a href=&quot;http://code.google.com/p/pybluez&quot;&gt;PyBluez on Google Code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Move the PyBluez-0.18.tar.gz to the top level of your pyzee directory&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change directory to the pyzee directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ~/pyzee
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extract the PyBluez-0.18 contents&lt;/p&gt;

&lt;p&gt;   tar -zxvf PyBluez-0.18.tar.gz&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change directory to the PyBluez-0.18 directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd PyBluez-0.18
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Build the python bluetooth bindings by running&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python setup.py build
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change directory back up one level so that you&#39;re inside the top level of the pyzee directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ..
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a symlink to the freshly built bluetooth python bindings, so that they&#39;ll be found when we run pyzeemote&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ln -s PyBluez-0.18/build/lib.linux-i686-2.6/bluetooth
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fire up the pyzeemote daemon (you shouldn&#39;t see any output) using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python zeemote_listener.py
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;You shouldn&#39;t see any output if things went correctly. If you get the following then there is a problem with the bluetooth python bindings built in the last steps&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;---------------------------------------------------
Traceback (most recent call last):
File &quot;zeemote_listener.py&quot;, line 39, in &amp;lt;module&amp;gt;
from bluetooth import *
ImportError: No module named bluetooth
---------------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You&#39;ll have to figure out why this is. Perhaps the symlink wasn&#39;t created correctly or it was created in the wrong place?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Run the pyzeemote test suite&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;python pyzeemote-test.py
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should see it say&lt;/p&gt;

&lt;p&gt;Trying to find a Zeemote device...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to click some buttons on your zeemote device. If successful, you should see output at the command line as you do so. Congrats, it&#39;s working!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 <entry>
   <title>Installing Ruby on Rails on MeeGo with SQLite</title>
   <link href="http://www.theirishpenguin.com/2010/11/20/installing-ruby-on-rails-on-meego-with-sqlite.html"/>
   <updated>2010-11-20T01:14:50+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/11/20/installing-ruby-on-rails-on-meego-with-sqlite</id>
   <content type="html">&lt;p&gt;This post will go through installing Ruby on Rails 2.3.2 on MeeGo - though it should likely work for any version of Rails, including Rails 3 (though the actual Rails commands at the end of this guide will be a little different). Firstly go through the &lt;a href=&quot;http://www.theirishpenguin.com/2010/11/18/installing-ruby-and-rubygems-on-meego/&quot;&gt;Installing Ruby and Rubygems on MeeGo&lt;/a&gt; guide to get at least Ruby 1.8.7 on your system and then carry out the following steps.&lt;/p&gt;

&lt;p&gt;PRE-REQUISITES&lt;/p&gt;

&lt;p&gt;The above guide requires you to disable the core repository and then enable the devel and testing repositories. I found that when following the below steps, I would get an error trying to install sqlite3 gem itself - saying that the sqlite3.h header could not be found. I had to run the following commands first&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  # Update all packages on the system

  sudo zypper update

  # Then the chrome browser would not work saying

  [declan@declan-desktop grr]$ chromium-browser

  /usr/lib/chromium-browser/chromium-browser: error while loading
  shared libraries: libicuuc.so.42: cannot open shared object file: No 
  such file or directory

  # To fix this, I had to update chromium-browser separately

  sudo zypper update chromium
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok, so onto the actual install steps for Rails and SQLite3...&lt;/p&gt;

&lt;p&gt;RAILS INSTALLATION&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  #Install ruby and sqlite development headers (as we&#39;ll be using
  sqlite as our backend)

  sudo zypper install ruby-devel

  sudo zypper install sqlite-devel

  # Install tools for building C-based gems

  sudo zypper install make # Not 100% sure that make is needed

  sudo zypper install gcc

  # Install sqlite3 gem for ruby

  sudo zypper install sqlite3-ruby

  # Install Rails

  sudo gem install rails -v 2.3.2

  # Create a new Rails application
  rails grr

  # Create a thing (ok, more correctly called a resource) in Rails

  cd grr

  ./script/generate Animal name:string

  # Create the database

  rake db:migrate

  # Fire up the Rails web server

  ./script/server

  # And then browse to your site in the web browser - http://localhost:3000/animals
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hurrah! Everything works! (At least I hope it did!). Happy Rails development!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Installing Ruby and Rubygems on Meego</title>
   <link href="http://www.theirishpenguin.com/2010/11/18/installing-ruby-and-rubygems-on-meego.html"/>
   <updated>2010-11-18T02:11:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/11/18/installing-ruby-and-rubygems-on-meego</id>
   <content type="html">&lt;p&gt;Thanks to some great people on the Meego mailing lists I can happily show you how to get recent versions of Ruby and Rubygems running on your beloved MeeGo. The steps I present here are simply extracted from the guide at&lt;a href=&quot;http://wiki.meego.com/Quality/QA-tools/TDriver&quot;&gt; http://wiki.meego.com/Quality/QA-tools/TDriver&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the more recent Ruby releases (1.8.7 and higher) gain more traction in MeeGo they will likely move into the core repository. So, be sure to see if they are there before changing adding/removing repositories as it outlined here.&lt;/p&gt;

&lt;p&gt;Warning: You need to disable the MeeGo core repository and enable the testing and development repositories so be sure that you&#39;re happy to do this before continuing.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#Remove the MeeGo core repo
sudo zypper rr core

# Enable the testing repo
sudo zypper ar http://download.meego.com/live/Trunk:/Testing/standard/Trunk:Testing.repo

# Enable the dev repo
sudo zypper ar http://download.meego.com/live/devel:/quality/testing/devel:quality.repo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you run into trouble remove this last repo with the command. If you do so you will be able to go no further.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo zypper rr devel_quality

# Install Ruby 1.8.7
sudo zypper install ruby

# Install rubygems
sudo zypper install rubygems
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yay! You&#39;re done! This guide would likely not have happened unless the MeeGo conference and its sponsors had not given away free MeeGo netbooks to the smiling attendees. Well done guys! And thank you!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Supressing hrefs in image hyperlinks when deleting resources using jquery</title>
   <link href="http://www.theirishpenguin.com/2010/10/29/supressing-hrefs-in-image-hyperlinks-when-deleting-resources-using-jquery.html"/>
   <updated>2010-10-29T11:55:58+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/10/29/supressing-hrefs-in-image-hyperlinks-when-deleting-resources-using-jquery</id>
   <content type="html">&lt;p&gt;This week we&#39;re trying to delete a resource using jquery within a Rails 2.3 app. First thing to note when using Rails is that if you set :method =&gt; :delete like below you will get a whole bunch of obtrusive prototype library javascript injected into the hyperlinks onclick() event. This can clash with your jquery code so you can&#39;t use :method =&gt; :delete alongside jquery. And it doesn&#39;t make any sense to do it this way. The number one reason that someone  (err... yes, me!) will get into this mess is that they&#39;ve been using the image_tag and link_to helper&#39;s and just forgotten that all this extra prototype code will be generated. So this is not so good for what we want...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= link_to image_tag(&#39;/images/delete.png&#39;, :title =&amp;gt; &#39;Delete the thing&#39;, :class =&amp;gt; &#39;clearPrintQueueOnClick&#39;), &#39;/things/3&#39;, :method =&amp;gt; :delete %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But this is better...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%= link_to image_tag(&#39;/images/delete.png&#39;, :title =&amp;gt; &#39;Delete the thing&#39;, :class =&amp;gt; &#39;deleteThingOnClick&#39;), &#39;/please_enable_javascript.html&#39; %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: That we have jquery code set up against anything that has the class deleteThingOnClick.&lt;/p&gt;

&lt;p&gt;Ok, if the user&#39;s browser does not have javascript enabled it will take them to the &lt;code&gt;please_enable_javascript.html&lt;/code&gt; which you can drop in your public html. If you want to support non-javascript browsers you can create a page with a form for doing delete requests - an example is shown in this blog &lt;a href=&quot;http://gaskell.org/unobtrusive-deleting-with-rails-and-jquery/&quot;&gt;entry&lt;/a&gt; by Andy Gaskell.&lt;/p&gt;

&lt;p&gt;With those pitfalls out of the way, all that remains to do to supress the href is to add event.preventDefault(); to the start of your deleteThingOnClick handler&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$(&quot;a&quot;).click(function(event) {
    event.preventDefault();
    // rest of your deletion code goes here..
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&#39;s it really! Exit stage left...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Will there be a red carpet for Nokia at The Appys?</title>
   <link href="http://www.theirishpenguin.com/2010/10/09/will-there-be-a-red-carpet-for-nokia-at-the-appys.html"/>
   <updated>2010-10-09T00:19:38+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/10/09/will-there-be-a-red-carpet-for-nokia-at-the-appys</id>
   <content type="html">&lt;p&gt;Just heard about this new awards ceremony &lt;a href=&quot;http://www.theappys.ie/&quot;&gt;The Appys&lt;/a&gt;! It will hand out the accolades to what it judges to be best mobile applications out there for a range of devices. As a long time Maemo fan and now MeeGo fan I&#39;ll be interested to see many apps are submitted for Nokia and its &lt;a href=&quot;http://store.ovi.com&quot;&gt;Ovi&lt;/a&gt; store.&lt;/p&gt;

&lt;p&gt;Alas, my own humble efforts developing &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/qt-on-rails-v0-1-released-but-is-this-ruby-based-qt-and-kde-app-framework-doomed/&quot;&gt;Qt on Rails&lt;/a&gt; apps aren&#39;t quite ready for entry. If you want to send in your own or vote on an app then today&#39;s deadline day! I just hope there&#39;s not too much in the way of gushing winners doing emotional acceptance speeches when the curtains come down on this one!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to localize model names in ActiveRecord associations via config locales with Ruby on Rails</title>
   <link href="http://www.theirishpenguin.com/2010/10/08/how-to-localize-model-names-in-activerecord-associations-via-config-locales-with-ruby-on-rails.html"/>
   <updated>2010-10-08T11:18:33+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/10/08/how-to-localize-model-names-in-activerecord-associations-via-config-locales-with-ruby-on-rails</id>
   <content type="html">&lt;p&gt;Argghhh!!! I went bananas for a little while getting my head around this. What are we trying to achieve? Well, say let&#39;s we have a model called Consultant which has a many-to-many relationship with Company though a Contract association. The Contract model is basically sitting on topic of a simple join in the database which has consultant_id and and company_id fields.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Consultant &amp;lt; ActiveRecord::Base
  has_many :contracts
  has_many :companies, :through =&amp;gt; :contracts

  accepts_nested_attributes_for :contracts
end

class Company &amp;lt; ActiveRecord::Base
  has_many :contracts
  has_many :consultants :through =&amp;gt; :contracts
end

class Contract &amp;lt; ActiveRecord::Base
  belongs_to :consultant
  belongs_to :company

  validates_uniqueness_of :consultant_id, :scope =&amp;gt; :company_id,
    :message =&amp;gt; &quot;cannot have a contract with the same company more than once&quot;

end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We have a New Consultant page which allows us to associate existing Companies with a Consultant by adding/removing Contracts. A Consultant cannot have a contract with a Company more than once, hence we need a validate_uniqueness_of validation on the Contract association.&lt;/p&gt;

&lt;p&gt;But hey, business is booming! We end up needing to reuse the code base for another Rails project. The new project is in the construction domain but it has been decided that the database schema and domain model should remain unchanged. However we are told that as far as the user is concerned they should never see the term Consultant, rather they should see the term Builder. Enter translations!&lt;/p&gt;

&lt;p&gt;Though you&#39;re not going to put your shoddy Spanish to the test and you failed French before you left school, translations are a handy way to work around this problem. Simply translate the word Consultant into Builder via the config/locales/en.yml file in your Rails project. At the same time we&#39;ll also change&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The validation error header that is present when the user submits an invalid record&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The displayed version of the consultant_name to be Builder Name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The displayed version of the consultant model name to be Builder when arising from errors on the Contract association. The way to do this is not immediately obvious - you have to translate the foreign key field (consultant_id) to Builder for the association&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here&#39;s the complete config/locales/en.yml file. Note: Whitespace and indentation is very important.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;en:
  activerecord:
    errors:
      messages:
      template:
        header:
          one: &quot;This Builder has just one error but still you gotta fix it...&quot;
          other: &quot;This Builder has lots of errors, get your act together...&quot;
    attributes:
      consultant:
        consultant_name: Builder Name # Handles the work of translating this attribute
      contract:
        consultant_id: Builder # NNB: This the big one! Notice how must translate the foreign key field to Builder for the association!!!
    models:
      consultant: Builder # This causes the consultant model to be referred to as Builder on the UI
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So there you have it. The foreign key is the key, so to speak!&lt;/p&gt;

&lt;p&gt;The best guide I encountered on translation was this one by Ian Hecker on &lt;a href=&quot;http://iain.nl/2008/09/translating-activerecord&quot;&gt;Translating ActiveRecord&lt;/a&gt; which is a great way to get started. There is also a somewhat overwhelming guide to translations at &lt;a href=&quot;http://guides.rubyonrails.org/i18n.html&quot;&gt;Rails Internationalization (I18n) API&lt;/a&gt; but is comprehensive nonetheless. Also, do look at the &lt;a href=&quot;http://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/en-GB.yml&quot;&gt;en-GB.yml&lt;/a&gt; example at &lt;a href=&quot;http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale&quot;&gt;Sven Fuchs Locale Examples&lt;/a&gt; on GitHub.com which is where I first saw how you can define you locale file as an .rb file or yaml as above. Finally, I came across this entry on how to remove &lt;a href=&quot;http://blog.geekq.net/2009/04/09/i18n-remove-validation-message-prefix/&quot;&gt;Rails Validation Message Prefixes&lt;/a&gt; which I didn&#39;t try but I just mention here in case I need it in future.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Getting readline to work with Ruby Version Manager (RVM) on Linux Mint KDE</title>
   <link href="http://www.theirishpenguin.com/2010/10/03/getting-readline-to-work-with-ruby-version-manager-rvm-on-linux-mint-kde.html"/>
   <updated>2010-10-03T05:17:02+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/10/03/getting-readline-to-work-with-ruby-version-manager-rvm-on-linux-mint-kde</id>
   <content type="html">&lt;p&gt;I couldn&#39;t get readline to be picked up using the &#39;rvm package install readline&#39; command. So instead I had to install the readline development headers as a Debian package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo aptitude install libreadline6-dev&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then tell rvm about the /usr directory when installing ruby&lt;/p&gt;

&lt;p&gt;(Note: I had run &#39;rvm package install zlib&#39; and &#39;rvm package install openssl&#39; before running this next command)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rvm install 1.8.7 -C --with-zlib-dir=$HOME/.rvm/usr --with-openssl-dir=$HOME/.rvm/usr --with-readline-dir=/usr&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This solution should also work for Ubuntu.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Accessing your encrypted home directory in Ubuntu</title>
   <link href="http://www.theirishpenguin.com/2010/09/26/accessing-your-encrypted-home-directory-in-ubuntu.html"/>
   <updated>2010-09-26T21:02:14+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/09/26/accessing-your-encrypted-home-directory-in-ubuntu</id>
   <content type="html">&lt;p&gt;This process details accessing an home directory, which was encrypted using the &quot;encrypted ~/Private directory&quot; technique, that has been with us since Ubuntu 8.10 (Intrepid Ibex) and available as an install option.&lt;/p&gt;

&lt;p&gt;This took a lot longer than expected in terms of sifting through information. Here I detailed what worked for me. I used the guide on &lt;a href=&quot;https://help.ubuntu.com/community/EncryptedPrivateDirectory#Recovering%20Your%20Data%20Manually&quot;&gt;Recovering your Data Manually&lt;/a&gt; as the foundation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: I tried to carry out this process using OpenSuse 11.2 but was unsuccessful.&lt;/strong&gt; Here&#39;s some notes regarding my OpenSuse attempt&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The package name of the encryption utility is the same on OpenSuse 11.2, so you can use &lt;code&gt;zypper install ecryptfs-utils&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The syntax of the &lt;code&gt;ecryptfs-add-passphrase&lt;/code&gt; seemed to be different as it didn&#39;t have a &lt;code&gt;--fnek&lt;/code&gt; option&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I suspect the problem is that the ecryptfs utility that comes with OpenSuse 11.2 doesn&#39;t support file name encryption. I found that I could decrypt the files and directories, view their contents but the file and directory names were all mangled&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Ok, meanwhile back at the ranch, we&#39;re trying to access an encrypted Ubuntu home directory from another partition, in my case a Kubuntu installation. When reading this guide be aware that there are two passphrases mentioned - a login passphrase (the usual password you use to login to your computer) and a mount passphrase (a big long jumble of characters that is vital to decrypting your partition). Later in the guide we also mention the sudo password - this is the password you type to get full superuser privileges on your machine. Here we go...&lt;/p&gt;

&lt;h3&gt;Step 1: Getting the all-important mount passphrase&lt;/h3&gt;

&lt;p&gt;First, we need the &lt;strong&gt;mount passphrase&lt;/strong&gt; that was generated when you first installed Ubuntu with the directory encrypted (or whenever you manually encrypted the directory, if you didn&#39;t do so during installation). If you were diligent at time of encryption you have written this down somewhere. For the rest of us :-), log into the Ubuntu containing the encrypted home directory and run the command,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ecryptfs-unwrap-passphrase /home/.ecryptfs/ubuntu_user/.ecryptfs/wrapped-passphrase&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then type in your login passphrase (it&#39;s the one that you usually type to login into your computer) when prompted in order to reveal the mount passphrase (the big jumble of characters). Record the mount passphrase somewhere as you&#39;ll need it later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I can&#39;t help you if you don&#39;t have your the mount passphrase or are unable to log into the Ubuntu containing the encrypted home directory which you are trying to access.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;Step 2: Accessing the encrypted home directory from another O.S.&lt;/h3&gt;

&lt;p&gt;Log into the other O.S., as I said, in my case a Kubuntu installation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ensure that you have the encryption utilities installed&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install ecryptfs-utils
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browse to the encrypted home directory on the other partition using your file manager in order to mount it. I used Dolphin on Kubuntu to browse to &lt;code&gt;/media/disk-3/home&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If you have found the correct directory you should see 2 files &lt;code&gt;Access-Your-Private-Data.desktop&lt;/code&gt; and &lt;code&gt;README.txt&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will need this directory later&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the command line, navigate to your normal home directory on Kubuntu&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd /home/kubuntu_user
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a directory in which we can mount the encrypted home directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir OtherHome
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need to get a special signature that will be used later for decrypting filenames (you can skip this step if you are trying to access Ubuntu 8.10 or less I think)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ecryptfs-add-passphrase --fnek
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: first you will need to enter your sudo password and then the mount passphrase&lt;/p&gt;

&lt;p&gt;Pay attention to the second &lt;code&gt;&quot;Inserted auth tok with sig&quot;&lt;/code&gt; line and note down the value in square brackets (eg. 66a9f67af69a86aa) as we will need this signature later&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Here&#39;s the real magic, which decrypts the home directory on Ubuntu and accesses it via the OtherHome directory on Kubuntu.
Note: Carefully look at the command and change the &lt;code&gt;/media/disk-3/home/.ecryptfs/ubuntu_user/.Private/&lt;/code&gt; bit to whatever is correct for you&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo mount -t ecryptfs /media/disk-3/home/.ecryptfs/ubuntu_user/.Private/ /home/kubuntu_user/OtherHome
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You will be asked a series of questions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select passphrase as the key type&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the mount phrase when asked for the passphrase&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select aes as the ecryption cipher&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select 16 bytes as the key length&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter n for enabling of plaintext passthrough&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter y for filename encryption (if you obtained the special signature in the earlier step)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the special signature from earlier when you are prompted for the Filename Encryption Key (FNEK) Signature&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note: You will get the following warning but there is no need to worry about it&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;WARNING: Based on the contents of [/root/.ecryptfs/sig-cache.txt],
it looks like you have never mounted with this key
before. This could mean that you have typed your
passphrase wrong
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it worked then the very last line will be &lt;code&gt;Mounted eCryptfs&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;You should now be able to navigate into &lt;code&gt;OtherHome&lt;/code&gt; and access the files there. Hurrah!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Beginning Optimization in MySQL</title>
   <link href="http://www.theirishpenguin.com/2010/09/22/beginning-optimization-in-mysql.html"/>
   <updated>2010-09-22T09:13:59+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/09/22/beginning-optimization-in-mysql</id>
   <content type="html">&lt;p&gt;The first place to start be to run your query using EXPLAIN in order to see what MySQL execution plan. Simply put EXPLAIN in front of your SELECT statement and check the output. Initially, you might think that its output doesn&#39;t give hard figures and as a result is pretty awkward to understand. But you&#39;ll soon see that it really helps you understand your queries and how they interact with things like indexes. The first page of &lt;a href=&quot;http://www.databasejournal.com/features/mysql/article.php/1382791/Optimizing-MySQL-Queries-and-Indexes.htm&quot;&gt;this article&lt;/a&gt; by Ian Gilfillan is a great explanation of explain (bit of a mouthful that!).&lt;/p&gt;

&lt;p&gt;The other good starting point is to known how does MySQL do joins? Well, the short answer is the single-sweep multi-join method and if you didn&#39;t know that then check out &lt;a href=&quot;http://www.fiftyfoureleven.com/weblog/web-development/programming-and-scripts/mysql-optimization-tip&quot;&gt;this post&lt;/a&gt; by Mike Papageorge.&lt;/p&gt;

&lt;h2&gt;Cache rich, time poor...&lt;/h2&gt;

&lt;p&gt;Of course, as you use EXPLAIN you&#39;ll try different things in your query and re-run queries to see the difference in performance. You&#39;ll want to some hard figures. Each time you run a MySQL query from the MySQL command line, or MySQL Query Browser, it will give you a query execution time. Unfortunately, the second time you run a query the execution time will be drastically shorter - because the results from the previous execution will be in MySQL&#39;s Query Cache. The only reliable way I&#39;ve found to minimise the effect of the cache is to restart the MySQL server after every query (eg. /etc/init.d/mysql restart). It won&#39;t give you the exact same metric as, for example, after a reboot of your machine but it&#39;s a good line in the sand nonetheless.&lt;/p&gt;

&lt;h2&gt;Ok, a quick checklist...&lt;/h2&gt;

&lt;p&gt;The thing is someone else has always done the hard work for you on topics like this. A great place to start is with this &lt;a href=&quot;http://blog.sven.co.za/2010/03/23/mysql-database-optimization/&quot;&gt;checklist&lt;/a&gt; by Sevn Welzel. Here&#39;s my favourite from that checklist, which I&#39;m listing here more as a memo-to-self than anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: That MySQL 5.0 introduced a lot of changes so certain optimizations pre-5.0, such as converting OR statements to UNIONs are no longer needed.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Derived tables (subqueries in the FROM clause) can be useful for retrieving BLOBs without sorting them. (Self-join can speed up a query if 1st part finds the IDs and uses then to fetch the rest)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid using IN(…) when selecting on indexed fields&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;InnoDB ALWAYS keeps the primary key as part of each index, so do not make the primary key very large&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This list of &lt;a href=&quot;http://docs.cellblue.nl/2007/03/17/easy-mysql-performance-tweaks/&quot;&gt;Easy MySQL Performance Tweaks&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sven also lists a bundle of tips by Alexander Skakunov at &lt;a href=&quot;http://www.ajaxline.com/32-tips-to-speed-up-your-mysql-queries&quot;&gt;AjaxLine&lt;/a&gt; the most useful one for me being the way the MySQL Query Optimizer can use the leftmost index prefix - this mean you can define index on several columns so that left part of that index can be used a separate one so that you need less indices (though remember that your index will be bigger overall and hence not a fast to search as a smaller index)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Handpicking Indexes&lt;/h2&gt;

&lt;p&gt;A big part of optimizing in MySQL is experimenting with different indexes on your database but you don&#39;t want to have to keep adding and removing them - as this can take a long time on big tables. Consider using IGNORE INDEX(some_index) if you&#39;d like to see how your query would perform in the absence of an index or FORCE INDEX(some_index) if you&#39;d like make sure MySQL to use&#39;s a particular index. By looking a the output of EXPLAIN you can see which indexes are being used. Sometimes, if you know your data well, you can outsmart the MySQL query optimizer. Though be careful when doing so as if the shape of your data changes your optimization might work against you. More details at &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/index-hints.html&quot;&gt;MySQL Manual Index-hints&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Top optimization picks from the MySQL Documentation&lt;/h2&gt;

&lt;p&gt;The MySQL docs really are great at explaining a lot of this stuff and the optimization sections are well worth a read. Here I&#39;ve just selected the bits that were the most useful as I worked through this area and expanded on them in one or two cases.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;From &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/select.html&quot;&gt;MySQL SELECT Documentation&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed in the FROM clause.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Irish Penguin says: &quot;This can be really really handy. For example, if you have a GROUP BY clause that references a column in a large table in a query featuring some JOINS, you probably will want to the table containing this column to be the first hit in the query - even if it produces a much higher number of &lt;em&gt;rows examined&lt;/em&gt; figure in the EXPLAIN output. My understanding is that the way MySQL decides on its query plan is to put the table that is likely to yield the fewest rows first. But this can be at loggerheads with GROUP BY clauses. It does a similar behaviour when choosing indexes as this &lt;a href=&quot;http://www.mysqlperformanceblog.com/2007/02/16/using-index-for-order-by-vs-restricting-number-of-rows/&quot;&gt;MySQL Performance Blog article&lt;/a&gt; states&quot;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html&quot;&gt;MySQL INDEX &lt;/a&gt; and &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html&quot;&gt;MULTIPLE-COLUMN INDEX&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to find rows. For example, if you have a three-column index on (col1, col2, col3), you have indexed search capabilities on (col1), (col1, col2), and (col1, col2, col3).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If a multiple-column index exists on col1 and col2, the appropriate rows can be fetched directly. If separate single-column indexes exist on col1 and col2, the optimizer will attempt to use the Index Merge optimization (see Section 7.3.1.4, “Index Merge Optimization”), or attempt to find the most restrictive index by deciding which index finds fewer rows and using that index to fetch the rows.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/index-merge-optimization.html&quot;&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a range scan is possible on some key, the optimizer will not consider using Index Merge Union or Index Merge Sort-Union algorithms&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Consider running &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/optimize-table.html&quot;&gt;OPTIMIZE TABLE&lt;/a&gt; if you have deleted a large part of a table or if you have made many changes to a table with variable-length rows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/optimizer-issues.html&quot;&gt;MySQL Optimizer Issues&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use ANALYZE TABLE tbl_name to update the key distributions for the scanned table. See &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/analyze-table.html&quot;&gt;ANALYZE TABLE Syntax&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html&quot;&gt;InnoDB restrictions&lt;/a&gt; and &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/innodb-tuning.html&quot;&gt;InnoDB turning&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An InnoDB table cannot contain more than 1000 columns&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SHOW TABLE STATUS does not give accurate statistics on InnoDB tables, except for the physical size reserved by the table. The row count is only a rough estimate used in SQL optimization&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Cascaded foreign key actions to not activate triggers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;InnoDB does not store an index cardinality value in its tables. Instead, InnoDB computes a cardinality for a table the first time it accesses it after startup. With a large number of tables, this might take significant time. It is the initial table open operation that is important, so to “warm up” a table for later use, access it immediately after startup by issuing a statement such as SELECT 1 FROM tbl_name LIMIT 1.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Relating to the &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/group-by-optimization.html&quot;&gt;Group By Optimization&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Usually a &lt;code&gt;GROUP BY&lt;/code&gt; clause causes a scan of the whole table and the creation of a new temporary           table where all rows from each group are consecutive. This temporary table is then used to establish groups and apply           aggregate functions. MySQL can sometimes use indexes that avoid temporary table creation if the query is written in a certain way -  all &lt;code&gt;GROUP           BY&lt;/code&gt; columns must reference attributes from the same index. Also           the index must stores its keys in order (for example, this           is a &lt;code&gt;BTREE&lt;/code&gt; index and not a           &lt;code&gt;HASH&lt;/code&gt; index). See this &lt;a href=&quot;http://www.informit.com/articles/article.aspx?p=377652&quot;&gt;InformIT article&lt;/a&gt; for the difference between BTEE and HASH indexes and more information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Very importantly, make sure that the column(s) involved in the GROUP BY clause are from the lead table in your query. If MySQL&#39;s Optimizer is choosing a different table as the lead table try using STRAIGHT_JOIN to force MySQL to first hit the table containing the columns that appear in the GROUP BY when executing the query. Why doesn&#39;t MySQL always do this by default? MySQL&#39;s Query Optimizer prefers to using indexes for restriction (WHERE clause) rather than sorting (GROUP BY or ORDER BY) that&#39;s why you sometimes need to give it this hint&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Relating to the &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.0/en/limit-optimization.html&quot;&gt;Limit Optimization&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The LIMIT clause can speed up things even when applied after an ORDER BY clause. &lt;strong&gt;MySQL does not always need to finish the sorting before it can apply the limit. &lt;/strong&gt;In some cases, you can think of LIMIT as a buffer that MySQL fills up as it sorts the results - MySQL stops as soon as the buffer is filled. For example, if you use LIMIT 10 with ORDER BY, MySQL ends the sorting as soon as it has found the first 10 rows of the sorted result, rather than sorting the entire result. Here&#39;s some caveats&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Avoid using a HAVING clause as this will prevent the optimizations&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You really want the ordering to use an index. Otherwise if a filesort must be done, all rows that match the query without the LIMIT clause must be selected, and most or all of them must be sorted, before it can be ascertained that the first 10 rows have been found&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Some other random musings&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Interesting &lt;a href=&quot;http://dev.mysql.com/tech-resources/articles/debunking-group-by-myths.html&quot;&gt;debunking of the myth that MySQL violates the SQL standard&lt;/a&gt; when it comes to specifying (or omitting) columns referenced in the SELECT list of a query to also appear in the GROUP BY clause&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another &lt;a href=&quot;http://www.mysqlperformanceblog.com/2006/09/06/wrong-group-by-makes-your-queries-fragile/&quot;&gt;post&lt;/a&gt; shows how GROUP BY can get you into a whole world of trouble on this score&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And as if that wasn&#39;t enough, there&#39;ll be a few more updates to this article at a later date. Coffee permitting!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Ruby Bindings for Qt: Building QtRuby on MeeGo and creating an RPM</title>
   <link href="http://www.theirishpenguin.com/2010/08/10/ruby-bindings-for-qt-building-qtruby-on-meego-and-creating-an-rpm.html"/>
   <updated>2010-08-10T11:29:49+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/08/10/ruby-bindings-for-qt-building-qtruby-on-meego-and-creating-an-rpm</id>
   <content type="html">&lt;p&gt;MeeGo is great. What could make it even better? More Ruby :-) So what better way to achieve this than by getting the Ruby bindings for Qt up and running on MeeGo. So here&#39;s a Work In Progress guide...&lt;/p&gt;

&lt;h3&gt;Pre-requisites&lt;/h3&gt;

&lt;p&gt;Get the MeeGo SDK running on your machine under Xephyr &lt;a href=&quot;http://wiki.meego.com/MeeGo_SDK_with_Xephyr&quot;&gt;http://wiki.meego.com/MeeGo_SDK_with_Xephyr&lt;/a&gt;
I&#39;ll assume that you can successfully run the &lt;code&gt;meego-sdk-chroot&lt;/code&gt; command and are now at a MeeGo console. Here&#39;s what we need to do to build QtRuby...&lt;/p&gt;

&lt;h3&gt;The Guide&lt;/h3&gt;

&lt;p&gt;Install cmake:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;zypper in cmake
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Pull down the kdebindings source code from svn:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;svn checkout -N svn://anonsvn.kde.org/home/kde/trunk
cd trunk
svn up -N KDE
cd KDE
svn up kdelibs kdebindings
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above should be all you need to do but if you have problems then maybe try reading http://en.opensuse.org/openSUSE:KDE_developers_guide&lt;/p&gt;

&lt;p&gt;Copy the &lt;code&gt;kdebindings/qtruby&lt;/code&gt; directory to your meego home directory in the &lt;code&gt;&amp;lt;meego_sdk_directory&amp;gt;&lt;/code&gt;, the latter will be something like &lt;code&gt;/home/yourusername/meego-sdk-0524/home/meego/&lt;/code&gt; depending on where you installed the MeeGo SDK earlier.&lt;/p&gt;

&lt;p&gt;Copy the file &lt;code&gt;kdebindings/CMakeLists.txt.qtruby&lt;/code&gt; to &lt;code&gt;/home/meego/qtruby/CMakeLists.txt&lt;/code&gt; (yes, this will overwrite the old file. This is ok, we don&#39;t want to build all of kdebindings, just qtruby)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd &amp;lt;meego_sdk_directory&amp;gt;/home/meego/qtruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit the new CMakeLists.txt, underneath the line &lt;code&gt;include (MacroOptionalFindPackage)&lt;/code&gt; add the lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;include (MacroOptionalAddBindings)
include (MacroLogFeature)
include (CheckCXXSourceCompiles)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also, just before the line &lt;code&gt;add_subdirectory(smoke)&lt;/code&gt; add the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;add_subdirectory(generator)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, if you want to be able to build an RPM (or any other package type supported by the &lt;a href=&quot;http://www.cmake.org/Wiki/CMake:CPackPackageGenerators&quot;&gt;CPack&lt;/a&gt; tool), add the following line as the very last line in the &lt;code&gt;CMakeLists.txt&lt;/code&gt; file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;include(CPack)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok now we need to create a &lt;code&gt;cmake/modules&lt;/code&gt; directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir -p qtruby/cmake/modules
cd qtruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As the &lt;code&gt;CMakeLists.txt&lt;/code&gt; file says in the commented section, we need to copy some files we need from the KDE related directories (this is because we are building QtRuby standalone instead of as part of the all-encompasing kdebindings module). Note, you need to change the location of kdelibs in the next command to wherever you pulled down the subversion directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cp kdelibs/cmake/modules/FindQt4.cmake ./cmake/modules/
cp kdelibs/cmake/modules/FindRUBY.cmake ./cmake/modules/
cp kdelibs/cmake/modules/MacroOptionalFindPackage.cmake ./cmake/modules/
cp kdelibs/cmake/modules/MacroPushRequiredVars.cmake ./cmake/modules/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Additionally you will need to copy the following files&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cp kdelibs/cmake/modules/Qt4Macros.cmake ./cmake/modules/
cp kdelibs/cmake/modules/Qt4ConfigDependentSettings.cmake ./cmake/modules/
cp kdelibs/cmake/modules/HandleImportedTargetsInCMakeRequiredLibraries.cmake ./cmake/modules/
cp kdelibs/cmake/modules/MacroLogFeature.cmake ./cmake/modules/
cp kdelibs/cmake/modules/CheckCXXSourceCompiles.cmake ./cmake/modules/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And also copy these from kdebindings&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cp kdebindings/cmake/modules/MacroOptionalAddBindings.cmake ./cmake/modules/
cp -r kdebindings/ruby .
cp -r kdebindings/smoke .
cp -r kdebindings/generator .
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we are going to create a &lt;code&gt;qtruby_build&lt;/code&gt; directory so that we can do an out-of-source build of qtruby. If you don&#39;t know what an out-of-source build is, don&#39;t worry!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd ..
mkdir qtruby_build
cd qtruby_build
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create a file called &lt;code&gt;cmake_qtruby&lt;/code&gt;. Copy and paste the long commented cmake command in &lt;code&gt;CMakeLists.txt&lt;/code&gt; to this file (you can exclude the make and make install commands)&lt;/p&gt;

&lt;p&gt;At the end of the last line of this command add a backslash (so that you can continue the command on the next line) and then add the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;../qtruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then change the cmake command options&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;-DRUBY_EXECUTABLE=/usr/bin/ruby
-DRUBY_INCLUDE_PATH=/usr/lib/ruby/1.8/i386-linux/ 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At the end of this step the file should look something like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cmake                                                         \
  -DCMAKE_INSTALL_PREFIX=/usr/local                           \
  -DRUBY_EXECUTABLE=/usr/bin/ruby                             \
  -DRUBY_INCLUDE_PATH=/usr/lib/ruby/1.8/i386-linux/           \
  -Wno-dev                                                    \
  -DENABLE_SMOKE=on                                           \
  -DENABLE_QTRUBY=on                                          \
  -DENABLE_QTWEBKIT_SMOKE=off                                 \
  -DENABLE_QTSCRIPT_SMOKE=off                                 \
  -DENABLE_QTUITOOLS_SMOKE=off                                \
  -DENABLE_QTTEST_SMOKE=off                                   \
  -DENABLE_PHONON_SMOKE=off                                   \
  -DENABLE_QSCI_SMOKE=off                                     \
  -DENABLE_QWT_SMOKE=off                                      \
  -DENABLE_KDE_SMOKE=off                                      \
  -DENABLE_KDEVPLATFORM_SMOKE=off                             \
  -DENABLE_KHTML_SMOKE=off                                    \
  -DENABLE_KTEXTEDITOR_SMOKE=off                              \
  -DENABLE_SOLID_SMOKE=off                                    \
  -DENABLE_PLASMA_SMOKE=off                                   \
  -DENABLE_QTWEBKIT_RUBY=off                                  \
  -DENABLE_QTUITOOLS_RUBY=off                                 \
  -DENABLE_QTSCRIPT=off                                       \
  -DENABLE_QTTEST=off                                         \
  -DENABLE_PHONON_RUBY=off                                    \
  -DENABLE_QSCINTILLA_RUBY=off                                \
  -DENABLE_QWT_RUBY=off                                       \
  -DENABLE_SOPRANO_RUBY=off                                   \
  -DENABLE_KDEVPLATFORM_RUBY=off                              \
  -DENABLE_KORUNDUM_RUBY=off                                  \
  -DENABLE_KHTML_RUBY=off                                     \
  -DENABLE_KTEXTEDITOR_RUBY=off                               \
  -DENABLE_SOLID_RUBY=off                                     \
  -DENABLE_KROSSRUBY=off                                      \
  -DENABLE_PLASMA_RUBY=off                                    \
  -DENABLE_QIMAGEBLITZ_SMOKE=off                              \
../qtruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Make this command executable and run it&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chmod u+x cmake_qtruby
./cmake_qtruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This should go off prepare your &lt;code&gt;qtruby_build&lt;/code&gt; directory for compiling. Once it is finished, you should be able to install by any one of the following methods&lt;/p&gt;

&lt;h3&gt;RPM-based Install&lt;/h3&gt;

&lt;p&gt;You will need to have added the &lt;code&gt;include(CPack)&lt;/code&gt; to the &lt;code&gt;CMakeLists.txt&lt;/code&gt; file as outlined earlier before running cmake. You also now need to install the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;zypper install rpm-build
zypper install meego-rpm-config # Maybe you dont need this but I installed it anyway
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now all you need to do is run &lt;code&gt;make package&lt;/code&gt; and then &lt;code&gt;cpack -G RPM&lt;/code&gt; to build the RPM. You will find that the generated RPM install is called &lt;code&gt;kdebindings-0.1.1-Linux.rpm&lt;/code&gt;. That&#39;s because we were originally pulled all our qtruby code out of the kdebindings codebase - you can customize the package name, version and much much more by passing parameters to the cpack command when generating the rpm. You can check what values were used to build the package by viewing the &lt;code&gt;CPackSourceConfig.cmake&lt;/code&gt; file. As I was just building this rpm for personal use, I didn&#39;t bother changing any package details. Tut! Tut! Anyway, once you have an rpm you are happy with, simply install the QtRuby bindings on your system via:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rpm -i &amp;lt;your_generated_rpm_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: If you want to see the RPM spec file generated, have a look at &lt;code&gt;_CPack_Packages/Linux/RPM/SPECS/kdebindings.spec&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Deb-based Install (and other package types)&lt;/h3&gt;

&lt;p&gt;This is pretty much identical to the RPM-based Install. The difference is to use &lt;code&gt;cpack -G DEB&lt;/code&gt; instead of &lt;code&gt;cpack -G RPM&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;Source-based Install&lt;/h3&gt;

&lt;p&gt;All need to do &lt;code&gt;make&lt;/code&gt; and &lt;code&gt;make install&lt;/code&gt; to get the QtRuby bindings installed onto your system. Not quite as easy to undo as an package based installation though!&lt;/p&gt;

&lt;h3&gt;Testing that everything works&lt;/h3&gt;

&lt;p&gt;I only tested the RPM package installation method. I found that when running the &lt;code&gt;rbqtapi&lt;/code&gt; command I got the following error&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/lib/ruby/site_ruby/1.8/i386-linux/qtruby4.so: libsmokeqtcore.so.3: cannot open shared object file: No such file or directory - /usr/lib/ruby/site_ruby/1.8/i386-linux/qtruby4.so (LoadError)
from /usr/lib/ruby/site_ruby/1.8/Qt4.rb:5
from /usr/local/bin/rbqtapi:6:in `require&#39;
from /usr/local/bin/rbqtapi:6
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This was because some of the qtruby libraries installed into &lt;code&gt;/usr/local/lib&lt;/code&gt; which my MeeGo system does not check for libraries by default. I changed this by adding the file &lt;code&gt;/etc/ld.so.conf.d/qtruby-i386.conf&lt;/code&gt; which simply contained the line:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/local/lib
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then running the &lt;code&gt;ldconfig&lt;/code&gt; command. Then the &lt;code&gt;rbqtapi&lt;/code&gt; command worked happily!&lt;/p&gt;

&lt;p&gt;This guide still needs some polish. We&#39;ll get to that eventually, but hopefully it may be of some use in getting the Ruby and Qt playing real nice together on MeeGo!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Enabling mod rewrite on Apache</title>
   <link href="http://www.theirishpenguin.com/2010/07/26/enabling-mod-rewrite-on-apache.html"/>
   <updated>2010-07-26T02:44:21+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/07/26/enabling-mod-rewrite-on-apache</id>
   <content type="html">&lt;p&gt;To see if mod rewrite is enabled just create a simple php page with the following content&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php
echo phpinfo();
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you browse to this page you should see mod_rewrite listed as a loaded module.&lt;/p&gt;

&lt;p&gt;If not, then you gotta enable mod_rewrite for Apache&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo a2enmod rewrite
sudo /etc/init.d/apache2 restart
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can create a .htaccess file into the root of your site and start adding rewrite rules. Here&#39;s a simple example to make sure rewrites are working&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;RewriteEngine On
RewriteRule (.*) http://www.google.com/
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When you browse to your site, you should now be redirected to Google - if not, don&#39;t fret! There&#39;s one other gotcha you should know about! Look in the configuration file for your site under Apache (eg. &lt;code&gt;/etc/apache2/sites-available/default&lt;/code&gt;) and you will see a element for your site (careful, there could be a few different elements floating around, be sure to pick the right one). This will have an &lt;code&gt;AllowOverride&lt;/code&gt; attribute which is likely set to None. This is the problem - if you want rewrite rules to take effect then &lt;code&gt;AllowOverride&lt;/code&gt; should not be set to None. Try changing it to All. And hey presto, you should be good to go!&lt;/p&gt;

&lt;p&gt;This &lt;a href=&quot;http://ubuntuforums.org/showthread.php?t=255556&quot;&gt;thread&lt;/a&gt; on Ubuntu&#39;s forums proved invaluable in explaining this.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Awesome Linux Media Center using XBMC</title>
   <link href="http://www.theirishpenguin.com/2010/07/25/awesome-linux-media-center-using-xbmc.html"/>
   <updated>2010-07-25T06:01:35+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/07/25/awesome-linux-media-center-using-xbmc</id>
   <content type="html">&lt;p&gt;One of things I have been doing lately is rediscovering my music - inspired by talking to the some of the &lt;a href=&quot;http://amarok.kde.org/&quot;&gt;Amarok&lt;/a&gt; guys at Akademy this year! So I decided to go on a search for an Open Source Media Center solution and up popped &lt;a href=&quot;http://xbmc.org/&quot;&gt;XBMC&lt;/a&gt;. Now this project isn&#39;t related to Amarok but that doesn&#39;t stop it being way too cool for school! I&#39;ve being tinkering with it for just a few days and it just works like a dream.&lt;/p&gt;

&lt;h3&gt;Installation on Kubuntu is simple&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I just following the &lt;a href=&quot;http://wiki.xbmc.org/index.php?title=HOW-TO_install_XBMC_for_Linux_on_Ubuntu,_a_Step-by-Step_Guide&quot;&gt;Install XBMC on Ubuntu HOWTO&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In (KDE&#39;s) System Settings -&gt; Autostart, added XBMC Media Center to startup automatically on computer startup&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From within XBMC itself, went to System -&gt; Settings -&gt; System -&gt; Video Output and set the Resolution to be Windowed (as I usually want to be able to access my KDE desktop at any time)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Initially you will have no music library. Instead you will add a directory location containing your music via Add Source. Then you can browse the added location and choose to &lt;em&gt;Scan Item to Library&lt;/em&gt; to build up your music library&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;By visiting System -&gt; Settings -&gt; Network -&gt; Services you can &lt;em&gt;Allow control of XBMC via HTTP&lt;/em&gt; by setting Port, Username and Password. If you know the IP address of the machine you are running XBMC on then you can simply browse to http://YOUR_MACHINE_IP_ADDRESS:PORT from any web browser enabled device to control your media center (for example http://192.168.1.7:6666). Note: XBMC must be running on the machine for this to work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you have your music library set up, you will notice that you cannot access it through the web interface. To enable this, simply edit &lt;code&gt;~/.xbmc/userdata/sources.xml&lt;/code&gt; by adding the following to the &lt;code&gt;&amp;lt;music&amp;gt;&lt;/code&gt; element&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;source&amp;gt;
&amp;lt;name&amp;gt;Library&amp;lt;/name&amp;gt;
&amp;lt;path&amp;gt;musicdb://&amp;lt;/path&amp;gt;
&amp;lt;/source&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Of course, when I don&#39;t need to a complete Media Center solution and just want to rediscover my music I fire up my beloved Amarok :-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Simply adding a Linux Partition via fstab</title>
   <link href="http://www.theirishpenguin.com/2010/07/25/simply-adding-a-linux-partition-via-fstab.html"/>
   <updated>2010-07-25T05:41:01+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/07/25/simply-adding-a-linux-partition-via-fstab</id>
   <content type="html">&lt;p&gt;Just add something like the following to /etc/fstab...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;UUID=1208c5dc-d4a6-a7a2-8352-ab12ecd64412 /media/disk-1  ext4    relatime,errors=remount-ro 0 2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... where&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;UUID uniquely identifies the partition you wish to add (you can get the UUID for you drive using &lt;code&gt;ls -l /dev/disk/by-uuid&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;/media/disk-1/ can be changed to be location on your system - it&#39;s where the partition will be added&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I don&#39;t really have a monkeys of what the other settings do, but I think they are more or less the usual defaults. Works for me!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Bang! Short blog post! Goodnight!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hello Planet KDE! Ruby makes an appearance in Grantlee</title>
   <link href="http://www.theirishpenguin.com/2010/07/08/hello-planet-kde-ruby-makes-an-appearance-in-grantlee.html"/>
   <updated>2010-07-08T06:37:45+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/07/08/hello-planet-kde-ruby-makes-an-appearance-in-grantlee</id>
   <content type="html">&lt;p&gt;So this will be the first time theirishpenguin makes it onto Planet KDE! And no better time - blogging straight from the KDE community feast that is Akademy! It&#39;s been a superb week, in the stunning city of Tampere in Finland. It&#39;s Day 6 of the event, a day which has been quite a Ruby-tinted one. First up, I had the pleasure of hacking on Grantlee, a Django-inspired string templating engine in Qt, with Stephen Kelly; adding Ruby support to the code generator example it ships with. Also, after talking to Cornelius Schumacher from OpenSUSE I learned that Ruby&#39;s splashed all over the place - even helping power the &lt;a href=&quot;http://wiki.opensuse.org/openSUSE:Build_Service&quot;&gt;OpenSUSE Build Service&lt;/a&gt; which allows packages to be easily built for any distro. Cool, eh?&lt;/p&gt;

&lt;p&gt;Grantlee&#39;s an interesting project already in use in Akonadi integration and KJots, providing an elegant templating solution. It&#39;s available on gitorious.org in the &lt;a href=&quot;http://grantlee.org&quot;&gt;Grantlee repo&lt;/a&gt;. It was good fun hacking on it, particularly useful picking up on some of Stephen&#39;s Ninja skills with git! At least it gives a couple of Irish lads something to do while all the Germans and Spaniards are talking about the World Cup!&lt;/p&gt;

&lt;p&gt;The organisation of Akademy 2010 has been top notch, from the welcome packs with all the details you need to get oriented - to the big screen for the footie in the hacker room. This was matched by the friendliness of everyone who turned up to the event and the local Finnish. Even these two fellows had a great time coding...&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://farm5.static.flickr.com/4136/4770353269_e6414d2fb4.jpg&quot; alt=&quot;Duck typing at Akademy&quot; /&gt;
&lt;strong&gt;I feel a duck typing joke coming on. Me too!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There&#39;s been some interesting BoF (Birds of a Feather) sessions, in particular the KDE Bioinformatics session with Luca Beltrame and KDE for Scientists session, again with Luca and also Stuart Jarvis. Some of the ideas raised pushed me to start working on getting ActiveResource support into &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/qt-on-rails-v0-1-released-but-is-this-ruby-based-qt-and-kde-app-framework-doomed/&quot;&gt;Qt on Rails&lt;/a&gt;, to make hitting remote APIs possible from a Qt client app.&lt;/p&gt;

&lt;p&gt;Well it&#39;s 15 minutes to kick off in tonight&#39;s semi-final. If anyone out there wants to talk about anything Ruby, or get a quick demo of Qt on Rails, then feel free to ping me. You can comment to this post or find me on twitter (theirishpenguin).&lt;/p&gt;

&lt;p&gt;Last night we went Dutch... Tonight who knows...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Developing a simple Match Schedule N900 App for the group stage of World Cup 2010 via Qt on Rails</title>
   <link href="http://www.theirishpenguin.com/2010/06/24/developing-a-simple-match-schedule-n900-app-for-the-group-stage-of-world-cup-2010-via-qt-on-rails.html"/>
   <updated>2010-06-24T20:13:10+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/06/24/developing-a-simple-match-schedule-n900-app-for-the-group-stage-of-world-cup-2010-via-qt-on-rails</id>
   <content type="html">&lt;p&gt;Today we&#39;re going to take a quick look at how to create a N900 app by taking a simple existing Ruby on Rails application and turning it into a Maemo app using Qt on Rails. The main thrust of this blog post is to show how you would tweak the skeleton app generated by the Qt on Rails framework into something that might be useful in the real world. The Match Schedule app is very basic and only shows the upcoming fixtures for the day. But most iPhone apps are simple thin wrappers around a data layer anyway; and this is really only a proof of concept app, so I&#39;d don&#39;t feel to guilty about my humble achievement.&lt;/p&gt;

&lt;p&gt;When the World Cup kicked off, I really wanted to have a schedule app on my N900 and couldn&#39;t find one so hence the motivation. Bear in mind that in 2 days this app will be completely useless as the group stage will be over! Warning:  it currently requires a level of technical ability to install this app on N900 as it has no installer. You should check out this related blog post on &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/deploying-your-qt-on-rails-apps-on-the-n900-maemo/&quot;&gt;deploying your Qt on Rails apps on the n900 (Maemo)&lt;/a&gt; before tackling this one.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The application (source code) is available for &lt;a href=&quot;http://github.com/downloads/theirishpenguin/qtonrails/WorldCup2010-GroupStage-MaemoViewer.tar.gz&quot;&gt;download&lt;/a&gt;. Note: I haven&#39;t stripped out unnecessary skeleton code from the application, which would exist immediately after generating the Qt application off the Rails codebase. The unnecessary code is related to Create/Edit/Delete functionality which we won&#39;t need in our simple Match Schedule viewer. I left it in to show the minimum amount of work needed to tweak the generated app into a useful real world program. All in all (blog posts and stuff aside), it took about an hour to do. If I had to do it again I&#39;d imagine it would take less than half that time.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;All the following steps are done on your dev machine. At the end of the guide you&#39;ll see how to deploy to your N900.&lt;/p&gt;

&lt;p&gt;First we create a Rails app.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rails WorldCup
cd WorldCup
./script/generate scaffold Fixture when:string group:string match:string
rake db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then I fired up the web server &lt;code&gt;./script/server&lt;/code&gt; and manually entered the fixtures (stupido! I know!). The &#39;When&#39; field has the date formatted as &#39;24/6 - 15:00&#39;.&lt;/p&gt;

&lt;p&gt;Next up, we turn the Rails app into a Qt app using Qt on Rails. We are still in the WorldCup directory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./script/plugin install git://github.com/theirishpenguin/qtonrails.git
./script/generate qtify Fixture
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This generates the skeleton Qt app. Now let&#39;s bend it into shape, starting with the UI. From now on we&#39;ll be working in the qtonrails/ plugin directory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cd vendor/plugins/qtonrails
designer-qt4 app/qdesigns/qmainwindow.ui
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once Qt Designer appears, remove the File menu, Commandlink navigation buttons and Action buttons (by more or less right-clicking on those widgets and deleting)&lt;/p&gt;

&lt;p&gt;Then regenerate a Ruby code version of the ui files (every time you change the .ui file using Qt Designer you need to do this)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rbuic4 app/qdesigns/qmainwindow.ui -x -o app/ui_proxies/qmainwindow.ui.rb

./run # or it that doesn&#39;t work try: ruby run
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then I got errors :-). Based on these errors, I changed the following...&lt;/p&gt;

&lt;p&gt;From app/qpresenters/main_window_presenter.rb I deleted&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;connect(@ui.viewButton, SIGNAL(&#39;clicked()&#39;), self, SLOT(&#39;view_clicked()&#39;))

connect(@ui.newButton, SIGNAL(&#39;clicked()&#39;), self, SLOT(&#39;new_clicked()&#39;))

connect(@ui.editButton, SIGNAL(&#39;clicked()&#39;), self, SLOT(&#39;edit_clicked()&#39;))

connect(@ui.deleteButton, SIGNAL(&#39;clicked()&#39;), self, SLOT(&#39;delete_clicked()&#39;))

connect(@ui.fixturesNavLinkButton, SIGNAL(&#39;clicked()&#39;), self, SLOT(&#39;fixtures_nav_clicked()&#39;))

connect(@ui.actionQuit, SIGNAL(&#39;triggered()&#39;), self, SLOT(&#39;close()&#39;))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let&#39;s try again&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./run
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hey it worked! Cool! There&#39;s more stuff we could now delete but we won&#39;t as we&#39;re focusing on doing the bare minimum.&lt;/p&gt;

&lt;p&gt;In order to allow a column to be correctly resized and to provide row select behaviour (as opposed to having individual clickable cells), I added the following line just before the end of the initialize() method in app/qpresenters/main_window_presenter.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;@tableview.resizeColumnsToContents()
@tableview.setSelectionBehavior(Qt::AbstractItemView::SelectRows)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The resizing of columns to fit their contents will probably become the default in a future Qt on Rails release.&lt;/p&gt;

&lt;p&gt;Due to silly bug in Qt on Rails that tries to pull an unnecessary KDE library into generated applications (&lt;a href=&quot;http://github.com/theirishpenguin/qtonrails/issues#issue/2&quot;&gt;Issue 2 on the GitHub Tracker&lt;/a&gt;), we need to remove the line &lt;code&gt;require &#39;korundum4&#39;&lt;/code&gt; from
&lt;code&gt;vendor/plugins/qtonrails/app/ui_proxies/qmainwindow.ui.rb&lt;/code&gt;
&lt;code&gt;vendor/plugins/qtonrails/app/ui_proxies/fixture_qform.ui.rb&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In order to display just today&#39;s fixtures, we can change the index action in app/qcontrollers/fixtures_controller.rb (again under the qtonrails/ plugin directory)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def index
  accept_current_fixtures_from Fixture.all
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... and add the private method&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def accept_current_fixtures_from(fixtures)
  fixtures.reject do |fixture|
    dt = fixture.when.split(&#39; - &#39;)[0] # Get date from string
    date_args = (dt.split(&#39;/&#39;) + [&quot;2010&quot;]).reverse.map &amp;amp;:to_i
    Date.new(*date_args) &amp;lt; Date.today
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note: The application &lt;a href=&quot;http://github.com/downloads/theirishpenguin/qtonrails/WorldCup2010-GroupStage-MaemoViewer.tar.gz&quot;&gt;source code available&lt;/a&gt; has the accept_current_fixtures_from() call commented out. This is because once the World Cup group stage is over in a couple of days the list of fixtures would be empty. I have decided that the value of this app as a useful demo in future outweighs the needs of my users over the next two days :-). In the source code you can simply add the call back in yourself if you wish.&lt;/p&gt;

&lt;p&gt;Finally, we make the grid readonly. Because it was late when I did this, I skipped any fancy meta-programming and simply reopened the QtrTableModel to do so. Add this to config/environment.rb&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class QtrTableModel
  def flags(index)
    return Qt::ItemIsSelectable | super(index)
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Phew! Done! To deploy the app to your N900, read the instructions at &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/deploying-your-qt-on-rails-apps-on-the-n900-maemo/&quot;&gt;deploying your Qt on Rails apps on the n900 (Maemo)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Well, hopefully you&#39;ve gotten a flavour of how to use Qt on Rails in a simple real world N900 app. If you&#39;ve any feedback then please get in touch! Until the next time, enjoy the World Cup and I hope your country does well!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Deploying your Qt on Rails apps on the N900 (Maemo)</title>
   <link href="http://www.theirishpenguin.com/2010/06/21/deploying-your-qt-on-rails-apps-on-the-n900-maemo.html"/>
   <updated>2010-06-21T06:52:37+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/06/21/deploying-your-qt-on-rails-apps-on-the-n900-maemo</id>
   <content type="html">&lt;p&gt;Qt on Rails is a framework to let you turn your Rails sites in desktop applications and harness the power of Ruby! It&#39;s not at production level yet but it&#39;s certainly possible to have a good play with it and a bit of a hack! If you&#39;re not familiar with Qt on Rails then a good place to start is &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/qt-on-rails-v0-1-released-but-is-this-ruby-based-qt-and-kde-app-framework-doomed/&quot;&gt;this blog post&lt;/a&gt; covering the v0.1 release. Also, check out the &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails&quot;&gt;github repo&lt;/a&gt; for more info on installing Qt on Rails on your desktop and building an application with it.  Here we show you how to deploy Qt on Rails based apps on your N900. One of the goals of Qt on Rails is to provide an easy way for you to develop apps faster for Maemo and, down the road, hopefully MeeGo too!&lt;/p&gt;

&lt;p&gt;Note: This blog post may help you figure out how to install any QtRuby application on the N900, not just Qt on Rails apps. Also, this  &lt;a href=&quot;http://wiki.maemo.org/QtRuby&quot;&gt;QtRuby Maemo wiki article&lt;/a&gt; was particularly useful when I was stumbling along this path!&lt;/p&gt;

&lt;p&gt;One thing you will need to install as part of this guide is &lt;a href=&quot;http://wiki.maemo.org/Easy_Debian&quot;&gt;Easy Debian&lt;/a&gt;. Easy Debian greatly expands what you can do with your Maemo device. It basically sticks a full-featured version of Debian on your device. This means 2 things - firstly, for the uber-geeks out there it let&#39;s you fire up a Linux desktop on the N900; though it&#39;s important to note that your normal Maemo desktop isn&#39;t affected by Easy Debian. Secondly, having a full-on Debian available let&#39;s you run Linux apps such as Open Office! Sweet! And what rocks is that you can even run these programs without invoking the Easy Debian Linux desktop - in a seamless manner. It&#39;s important to note that the user interface to these Easy Debian-based apps behave a differently to a typical native Maemo program; rather they work like a traditional desktop application with a mouse pointer on screen.&lt;/p&gt;

&lt;h3&gt;Install Steps&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Note: For simplicity, this guide assumes you are installing an application which stores data using sqlite3. Also, the steps here have been tested against the N900 firmware update PR1.2. If you are using an older version of the firmware you may want to consider updating it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Firstly, install Easy Debian with the N900&#39;s Application Manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the Easy Debian image via the new Deb Img Install application added to your list of applications&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Note: This is a 1 gig download, but comes with cool stuff like OpenOffice and intergrates pretty seamlessly with your desktop&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Takes an hour or so to download and then extract itself&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the Debian Chroot terminal (not the usual N900 terminal), which should now be in your list of applications&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install rubygems, qtruby and  sqlite3 with ruby bindings&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install rubygems
sudo apt-get install libqt4-ruby
apt-get install libsqlite3-ruby
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install the bits we need need from Rails (without installing documentation)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo gem install activerecord activesupport activeresource --no-ri --no-rdoc
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Zip up your Qt on Rails application and copy to any directory on to the N900. Note that the Qt on Rails application consists of the entire Rails directory directory including the vendor/plugins/qtonrails directory intact and  a sqlite3 database already created under the db directory).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If you don&#39;t have your own Qt on Rails application to hand then you can create the RadRadio app discussed in the &quot;Make it so, Jim!&quot; section of the &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/qt-on-rails-v0-1-released-but-is-this-ruby-based-qt-and-kde-app-framework-doomed/&quot;&gt;v0.1 release blog post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the Qt on Rails v0.1 release there is a bug that accidentally introduces a dependency on a korundum library, which is not needed in this case. &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails/issues#issue/2&quot;&gt;An issue is logged&lt;/a&gt; against this in the &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails/issues&quot;&gt;Qt on Rails Issue Tracker&lt;/a&gt; As a workaround, find and remove any occurrences of &lt;code&gt;require &#39;korundum4&#39;&lt;/code&gt; in files under the &lt;code&gt;vendor/plugins/qtonrails/app&lt;/code&gt; directory&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Once transferred, simply unzip it on your device. Note: If you saved the zip to the Documents folder on your N900, this can be found under /home/user/MyDocs/.documents when poking around the filesystem&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, via the good ol&#39; Debian Chroot terminal, change directory to the vendor/plugins/qtonrails directory of your app and execute&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ruby1.8 run
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boom! You should see your Qt on Rails app in all it&#39;s glory!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Note there is a &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails/issues#issue/6&quot;&gt;bug&lt;/a&gt; where you cannot input into a text field when running a Qt on Rails app on the N900 using above technique (seamless mode). As a workaround, open the Qt on Rails app inside of the Debian LXDE desktop (rather than in seamless mode). You can find Debian LXDE in the list of applications on your device. Inside Debian LXDE, open a terminal and run the application as above. Just a quick heads up, sticky keys don&#39;t work like you&#39;d expect - you have to &lt;a href=&quot;http://wiki.maemo.org/Easy_Debian#sticky_keys_hack&quot;&gt;hold down the Shift and Fn keys&lt;/a&gt; to use them.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Qt on Rails v0.1 released. But is this Ruby-based Qt and KDE app framework doomed?</title>
   <link href="http://www.theirishpenguin.com/2010/06/21/qt-on-rails-v0-1-released-but-is-this-ruby-based-qt-and-kde-app-framework-doomed.html"/>
   <updated>2010-06-21T05:00:24+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/06/21/qt-on-rails-v0-1-released-but-is-this-ruby-based-qt-and-kde-app-framework-doomed</id>
   <content type="html">&lt;p&gt;Ruby has changed the way developers build web applications. Since popularised by the Rails framework, programmers no longer stumble around in the dark with disparate web forms; instead they are able to clearly focus on the business problem and expose a well-modelled domain in a easily testable manner. Traditionally used in data-heavy domains, today&#39;s web apps now encroach on the desktop&#39;s home turf of rich highly-functional applications - something years ago thought impossible. And most surprisingly, through clever use of patterns and conventions, they&#39;ve arguably become the easier of the two to develop. Given this, could desktop developers learn from the web app approach? This is in part the motivation behind Qt on Rails - let&#39;s use a conventions-based approach to building desktop applications and clients. Let&#39;s harness the ease and expressiveness of the Ruby language. And let&#39;s have a clean consistent domain model underneath the hood with a comprehensive suite of tests to boot. A grand idea; but right now, it&#39;s on course to fail...&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/disc_jockey_list.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Main window listing Disc Jockeys (Click the image to enlarge)&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;What does this framework look like?&lt;/h3&gt;

&lt;p&gt;What exactly is Qt on Rails? Well first, let me just make a little guilty admission. This blog post is aimed at Ruby and/or Rails developers first, then Qt/KDE developers second. This is not because I believe one camp is more important than the other. It is because I really want to bring Rails dev&#39;s on-board to KDE/Qt development and I see a real need to give them a first-class Qt toolkit; to make desktop apps as brilliant and easy to develop as their web apps. If Qt on Rails ever makes it as far as being a fully mature framework, I hope that a Rails developer using it for the first time will find it a very familiar experience. The directory structure, naming conventions and overall architecture (to date at least) has been chosen to that end. But I hope to do an article focusing on approaching this project from a more on Qt/KDE perspective. So what is Qt on Rails like?&lt;/p&gt;

&lt;p&gt;Well, imagine you just wrote a Rails web application. You&#39;re finished! Let&#39;s say we just built a web app for a fictional company called RAD Radio. We have two important things in our system - Disc Jockeys and Sponsors for the radio shows. So we have this really neat model layer sitting on top of our database. It handles all our business logic and things like validation of data being persisted - let&#39;s reuse this... verbatim! This is our line in the sand! Design choice 1, Qt on Rails literally reuses everything from the model layer down already within your Rails application!&lt;/p&gt;

&lt;p&gt;If we start from the front end of our proposed desktop application and work backwards, we want to have a Qt app which consists of various different screens, some of which may be on display simultaneously. This is a little different from the web, because generally on the web you can think of having just one screen and this gets blown away on each request (unless AJAX intervenes, but still you get the overall point). In a Qt desktop app we decide that our initial screen is to be &quot;main&quot; window for our application. Clicking on a button may cause a new window to launch, for example, a window to edit a Disc Jockey&#39;s details, but the main window will remain there, though not active. This kind of difference (from your typical web behaviour) presents a difficult challenge and will have a big effect on our architecture - for example, it has influenced my decision not to try and reuse anything for the controller layer generated in a Rail&#39;s application. Back to our story, we have a main window as our starting point, which you can see in the figure above. It should have a way to navigate between different parts of your application. This is achieved through the big command link buttons at the top of the window. In our web application, each part of our application is based on different sources of data (called resources when using RESTful terminology). Clicking on the Sponsors command link button would cause the grid to be refreshed with Sponsor records. And then clicking on the Disc Jockeys command link button refresh the grid with Disc Jockey records again.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;This sounds reasonable so far. A quick side note though; bear in mind this is still early days for Qt on Rails. I&#39;m sure many good KDE and Qt developers may be horrified at the UI decisions made above. I&#39;m not a Qt or KDE expert! This is another big challenge. One of the most crucial areas we need help on is getting feedback on how Qt and KDE applications are generally laid out, what widgets are used for what purposes and so on. In essence, what are the best practice guidelines for &lt;a href=&quot;http://en.wikipedia.org/wiki/Human%E2%80%93computer_interaction&quot;&gt;HCI&lt;/a&gt; in something like KDE and how can we incorporate that into the apps we generate with Qt on Rails.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So we are looking at the main window, which contains a list of Disc Jockeys in a grid - how does this work? Well, first we need to be aware of what Qt is giving us here. The list widget that you see on screen is a Qt widget called a QTableView. It is concerned only with displaying stuff. Underneath that we have a QAbstractTableModel. This holds the data, it does not care about how it will be displayed. Now it&#39;s worth pointing out that a QAbstractTableModel has nothing to do with the Rails concept of a model. You see, the Qt folks have used the MVC pattern in their architecture for &lt;a href=&quot;http://en.wiktionary.org/wiki/donkey%27s_years&quot;&gt;donkey&#39;s years&lt;/a&gt; now; and it&#39;s important to not confuse the two different uses of the same paradigm. The QAbstractTableModel is an object into which you stick a whole bunch of Rails records that you wish to display in a list. We then plug the QAbstractTableModel into the QTableView widget and that&#39;s how your records are displayed. It&#39;s also important to note that when a QTableView sees the QAbstractTableModel being plugged in - it has absolutely no idea that the underlying records are of type Disc Jockey. Think of the QAbstractTableModel as an adapter between a collection of records for a particular Rails model and the QTableView widget which will ultimately display them. Probably most importantly, remember that&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A Rail&#39;s model equates to one record&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Whereas a QAbstractTableModel equates to many records - it sits on top of a collection of Rails records and allows them to be displayed in something like a QTableView widget&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;blockquote&gt;&lt;p&gt;Note: The Qt API is incredible. It&#39;s extremely comprehensive! Check it out at &lt;a href=&quot;http://doc.qt.nokia.com&quot;&gt;http://doc.qt.nokia.com&lt;/a&gt; You will want to look at the &quot;C++ Application Development Framework&quot; for the version of Qt you develop with. One big tip to note down - where it talks about something like a QAbstractTableModel in the docs - is that it is referring to the C++ world. In your head just translate this to Qt::TableModel - now you can happily use all the documentation available. Also, in your code you will always write Qt::AbstractTableModel, never QAbstractTableModel.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So to edit a Disc Jockey record I select a row and click the Edit button near the bottom of the page. Hey presto! An Edit Disc Jockey form appears...&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/edit_disc_jockey_form.png&quot; alt=&quot;Edit Form - Disc Jockey&quot; /&gt;
&lt;strong&gt;Form for editing a Disc Jockey (Click the image to enlarge)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Nice! And when you click the Save button the Edit form is dismissed and the list of Disc Jockeys in our main window is refreshed!&lt;/p&gt;

&lt;p&gt;Cool! But where do all the Qt on Rails files live?&lt;/p&gt;

&lt;p&gt;Qt on Rails is installed in the vendor/plugins directory of your Rails app (see &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails&quot;&gt;http://github.com/theirishpenguin/qtonrails&lt;/a&gt; for more details on how to install). Under vendor/plugins/qtonrails/ there is a directory called app/ which holds the Qt application code. In turn, app/ is divided into the following subdirectories, with each subdirectory corresponding to a layer in our application framework, listed here from the highest level (like the HTML stuff in a web app) to the lowest (the controller in our case - as everything from models down to db is handled by vanilla Rails).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;qdesigns&lt;/strong&gt; - XML markup files (with a .ui extension) which are to Qt screens/widgets what HTML files are to HTML pages/elements&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ui_proxies&lt;/strong&gt; - A Ruby representation of .ui files - this is an autogenerated layer which you don&#39;t really need to worry about&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;qpresenters&lt;/strong&gt; - Where the presentation logic (not any business logic) for your screen lives&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;qhelpers&lt;/strong&gt; - A place to put logic that you wish to reuse across presenters&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;qviews&lt;/strong&gt; - Where we decide exactly how we will build a view for a particular controller action (I accept that the name &#39;qviews&#39; is confusing; maybe &#39;qviewbuilders&#39; would be better or something totally different)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;qcontrollers&lt;/strong&gt; - Where we decide what data to retrieve for a particular action (though we don&#39;t specify &#39;where to go&#39; in the way a Rails controller has render() or redirect_to() methods)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;I am the Executioner...&lt;/h3&gt;

&lt;p&gt;So here&#39;s the flow of control. In our vender/plugins/qtonrails directory we have a &#39;run&#39; command. When we execute it, the command...&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Fires up a Qt Application instance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Asks our (very primitive) Router to take a given route and instantiate a QView and a QController for it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The QController then fetches data depending on the action (just like a Rails action) and hands off the data to the QView&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The QView then decides what screen should be build (or whether to stay on the same screen and perhaps just refresh a list of records)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the appropriate Screen has been built, it is displayed with a show() call. At this point the user will then see something happen on-screen.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The above is pretty much like one request-response cycle in a Rails app. Now we play the waiting game&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The user does something like selects a row and clicks the Edit button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;At this point the QPresenter comes into play. The QPresenter &lt;strong&gt;is&lt;/strong&gt; your window widget. I didn&#39;t tell you then, but the QPresenter was created earlier in the QView layer when we call the constructor for the window (ie. the QPresenter) we wish to display). I&#39;m open to the fact that QPresenter may not be the best name for this! Anyway, the QPresenter contains your presentation logic. In our case, the user has just clicked the Edit button on the MainWindow presenter. This causes the handler for the event - the edit_clicked() slot to be called. Qt uses a brilliant concept called Signals and Slots to handle events in your application - a Signal is something that acts as a trigger (such as a button being clicked) for a Slot; a Slot simply being a function dedicated to doing something useful in response. A Signal is connected to a Slot using the aptly named connect() method. I neglected to bore you with this little detail earlier but this connection was carried out in the constructor for the QPresenter (ie. the window) which took place a few steps back when we mentioned that the QView layer decided what screen is to be built&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, the slot - edit_clicked() in this case - asks the Router to take a given route and now we&#39;re back to step 2 of the flow of control outlined earlier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Phew!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Make it so, Jim!&lt;/h3&gt;

&lt;p&gt;So that&#39;s it in a nutshell. How do get all this lovely goodness to turn your Rails web app into a skeleton desktop app? One command, mon ami! From the root of your Rails directory simply run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;./script/generate qtify DiscJockey Sponsor
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So let&#39;s say you have no Rails app right now. Here&#39;s how to get to a basic web app and skeleton desktop app in double quick time!&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Firstly, just a quick note on OS dependencies. Qt on Rails has mainly been developed to date on Kubuntu 9.04, Kubuntu 9.10 and the Ubuntu Netbook Remix 9.10. For these platforms, you can install the packages mentioned in the &quot;First Install the appropriate packages&quot; section of this &lt;a href=&quot;http://techbase.kde.org/Development/Tutorials/Developing_Qt4_Applications_using_Qt_Designer_and_Ruby_on_Kubuntu&quot;&gt;Developing Qt4 Applications using Qt Designer and Ruby on Kubuntu&lt;/a&gt; article, which also goes into more detail on QtRuby development if you&#39;re interested. This &lt;a href=&quot;http://techbase.kde.org/Development/Languages/Ruby&quot;&gt;QtRuby bindings article&lt;/a&gt; on the KDE TechBase also gives some useful info on the Ruby bindings for Qt.&lt;/p&gt;

&lt;p&gt;We&#39;ve not tried this yet on Windows or Mac, but here&#39;s a &lt;a href=&quot;http://vision.eng.shu.ac.uk/mmvlwiki/index.php/Qt4-QtRuby_installer_for_Microsoft_Windows&quot;&gt;Windows QtRuby install guide&lt;/a&gt; by Richard Dale and a &lt;a href=&quot;http://osake.wordpress.com/2009/08/21/qt4-qtruby-mac-os-x/&quot;&gt;QtRuby on the Mac install guide&lt;/a&gt;. So you are welcome to try and install QtRuby on one of these platforms but we can&#39;t promise anything!&lt;/p&gt;

&lt;p&gt;Perhaps, most excitingly of all, Qt on Rails apps can be deployed to Maemo devices such as the N900! Check out this related &lt;a href=&quot;http://www.theirishpenguin.com/2010/06/21/deploying-your-qt-on-rails-apps-on-the-n900-maemo/&quot;&gt;Deploying your Qt on Rails apps on the N900 (Maemo)&lt;/a&gt; article! And MeeGo support will surely follow sometime soon!&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Ok, let&#39;s cook you up a Rails app. Here we are using Rails 2.3.5 and assuming you are at a Linux command line (see &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails&quot;&gt;Qt on Rails github project&lt;/a&gt; page for more installation details of Qt on Rails itself)...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;rails RadRadio
cd RadRadio
./script/plugin install git://github.com/theirishpenguin/qtonrails.git
./script/generate scaffold DiscJockey name:string date_of_birth:date programme_name:string radio_slot:time max_num_guests:integer next_review:datetime
./script/generate scaffold Sponsors name:string signed_up_on:date
rake db:migrate
./script/generate qtify DiscJockey Sponsor
cd vendor/plugins/qtonrails
./run
# If ./run on it&#39;s own gave you a permission error you can try &#39;ruby ./run&#39; instead
# Oh yeah!
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;What you see is almost what you get...&lt;/h3&gt;

&lt;p&gt;Hopefully, you should be seeing an app around about now. Once you have some rows in the list of disc jockeys or sponsors (create some DJs using the New button), you will see that cells of the grid that make up the list can be edited in-place. This is quite a powerful feature to have out of the box. An Edit button is provided also, though if you plan to provide an Edit button to your users, which launches a form, then you should probably make the grid read-only so as not to confuse them by having two ways of editing. As this is a early prototype of the framework, I&#39;ve left the Edit button and in-place editing enabled, trusting you to tailor them to your app&#39;s needs. If you were going to switch off in-place editing you would probably also want to select the entire row (rather than just one cell) when you click on a cell in the row.&lt;/p&gt;

&lt;p&gt;Let&#39;s have a quick look at form validation in action. Add a validates_presence_of validator to your DiscJockey and Sponsor Rails models so that they look as follows&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#In app/models/disc_jockey.rb (under root of your Rails app, not under qtonrails)

class DiscJockey &amp;lt; ActiveRecord::Base
    validates_presence_of :name
end

#In app/models/sponsor.rb (under root of your Rails app, not under qtonrails)

class Sponsor &amp;lt; ActiveRecord::Base
    validates_presence_of :name
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Close and restart the RadRadio Qt on Rails app. When you hit the New button and try to create a new Disc Jockey or Sponsor without a name, you will see that the Rails model validation kicks in and you get a validation message telling you that you need to correct the name field. Validation also works if you are editing a record after clicking the Edit button, however validation messages don&#39;t appear if you edit a record in-place in the grid (just because I haven&#39;t had a chance to implement that yet).&lt;/p&gt;

&lt;p&gt;Again, as it&#39;s an early release there&#39;s also plenty of bugs in there, such as a crash if you try to click the Edit Button without selecting any row. A list of issues is maintained on the &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails/issues&quot;&gt;Qt on Rails Issue Tracker&lt;/a&gt;. Check it out to see what limitations currently exist and add to it if you spot a new problem!&lt;/p&gt;

&lt;h3&gt;Doomed?&lt;/h3&gt;

&lt;p&gt;As you can see, this codebase is being opened up quite early. A good start has been made - but the project is still very embryonic! Surely, it&#39;s a bit early to be talking about doom? Well, unless hacking on Qt on Rails appeals to some developers out there it will certainly die a merry death on the great scrapheap of nice projects that just didn&#39;t make it. Why? Not only is there a lot of work that needs to be done, but also it&#39;s more fun to work on the project when there&#39;s a crew involved, which also brings new ideas and energy to any project. Otherwise it&#39;s unsustainable.&lt;/p&gt;

&lt;p&gt;But life wouldn&#39;t be fun it it wasn&#39;t a bit of a challenge, &lt;strong&gt;right&lt;/strong&gt;? If you think this kind of project might interest you, if you&#39;re not put off by insurmountable odds, then &lt;strong&gt;know that your framework needs you!&lt;/strong&gt; Drop me an email at declan [[AT]] weuseopensource [[DOT]] com or twit a quick tweet on twitter (theirishpenguin). The &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails/issues&quot;&gt;Qt on Rails Issue Tracker&lt;/a&gt; is a good place to start looking for things to hack on. Or you&#39;re welcome to fork the project on github and develop that killer feature you&#39;d like to see in there!&lt;/p&gt;

&lt;p&gt;Qt on Rails, because it&#39;s at an early stage, is an easy place to start - there isn&#39;t lots of code to weigh you down. The framework itself is very thin, the majority of the code is actually Rails style generators to take the Rails model layer and build the Qt/KDE app on top of it. Because of the tiny codebase, it shouldn&#39;t be hard too get your head around what&#39;s going on.&lt;/p&gt;

&lt;h3&gt;Qt on Rails doesn&#39;t want to be doomed!&lt;/h3&gt;

&lt;p&gt;It&#39;s intended that Qt on Rails gives Ruby and/or Rails developers an outlet to develop first class desktop apps using the best available framework. Rails developers often ask, &quot;If I want to build a great cross-platform desktop app, what GUI toolkit would I use?&quot; The answer varies and there no one headline GUI toolkit/desktop framework that currently has mindshare amongst Ruby developers and works great across multiple platforms. Given that Qt is currently so strong across the Linux desktop, commercial Windows applications, Macs and mobile platforms such as Maemo and MeeGo why shouldn&#39;t it be the first thing you reach for when building a Ruby desktop app? Come help us build Qt on Rails! &lt;strong&gt;Stave off the doom!&lt;/strong&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Getting started with PostgreSQL when developing Rails applications </title>
   <link href="http://www.theirishpenguin.com/2010/05/07/getting-started-with-postgresql-when-developing-rails-applications.html"/>
   <updated>2010-05-07T06:24:31+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/05/07/getting-started-with-postgresql-when-developing-rails-applications</id>
   <content type="html">&lt;p&gt;If you&#39;re familiar with MySQL and trying out PostgreSQL for the first time while doing some Ruby on Rails development, things can initially seem quite unfamiliar. A great first article to look at is available on the OLM on Rails site at &lt;a href=&quot;http://olmonrails.wordpress.com/2008/08/12/switching-rails-to-postgresql/&quot;&gt;Switching Rails to PostgreSQL&lt;/a&gt;. Also at this early stage in your PG career you&#39;ll need to know how to change things like user passwords so check the Examples section of the &lt;a href=&quot;http://www.postgresql.org/docs/8.0/interactive/sql-alteruser.html&quot;&gt;PostgreSQL Alter User docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Ok, after that you should know how to create a database in PostgreSQL, hook up to a Rails app and run migrations. Once that&#39;s done, you&#39;ll need to be able to do the same things that you were able to do in MySQL in the psql shell. Here&#39;s the first commands you need...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;typing &#39;help&#39; displays help at any time&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\? displays help with psql commands&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\l lists databases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\c some_database connects to a database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\c with no argument tells you what database you&#39;re currently connected to&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\ds lists schemas within the currently selected database. A schema is simply a namespacing of tables within a given database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\dt lists tables in the currently selected database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;\du lists all postgres database user accounts (more detail &lt;a href=&quot;http://archives.postgresql.org/pgsql-admin/2005-07/msg00073.php&quot;&gt;here&lt;/a&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Here&#39;s  a list of good of stuff...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &#39;LIKE&#39; pattern matcher in Postgres is case sensitive (in MySQL it is case insensitive - to get this behaviour in Postgres use &#39;ILIKE&#39;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://sql-info.de/postgresql/schemas.html&quot;&gt;What are schemas in PostgreSQL?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you want to keep things simple, just forget about schemas and everything will end up in a &#39;public&#39; schema (but you should read about schemas briefly so that they don&#39;t drive you mad when administering your postgres database)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://sql-info.de/postgresql/postgres-gotchas.html&quot;&gt;Postgres Gotchas&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://stackoverflow.com/questions/772111/switching-from-mysql-to-postgresql-tips-tricks-and-gotchas&quot;&gt;Switching from MySQL to PostgreSQL - tips, tricks and gotchas?&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Doing Raw MongoDB Queries when using MongoMapper with Rails</title>
   <link href="http://www.theirishpenguin.com/2010/05/04/doing-raw-mongodb-queries-when-using-mongomapper-with-rails.html"/>
   <updated>2010-05-04T10:47:59+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/05/04/doing-raw-mongodb-queries-when-using-mongomapper-with-rails</id>
   <content type="html">&lt;p&gt;Even though, you&#39;re using MongoMapper with Ruby and Rails, you may sometimes want to do queries using the Mongo database itself. Here&#39;s how I do it (note: there may be a better way, please post a comment).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Getting at the mongodb instance
MongoMapper.database

# Listing its collections
MongoMapper.database.collections

# Get at any collection while within any model (note: returns a Mongo::Cursor)
coll = MongoMapper.database[&#39;questions&#39;].find({})

# Convert that collection to an array (useful!)
coll.to_a

# Display a collection (note: &#39;each&#39; does an implicit &#39;to_a()&#39;)
MongoMapper.database[&#39;questions&#39;].find({}).each {|x| puts x.inspect}

# In the Question model you can use this shortcut
# collection to get at the questions collection
collection.find({}).to_a
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>Using git-svn to connect to a Subversion repository via Git</title>
   <link href="http://www.theirishpenguin.com/2010/04/26/using-git-svn-to-connect-to-a-subversion-repository-via-git.html"/>
   <updated>2010-04-26T10:25:10+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/04/26/using-git-svn-to-connect-to-a-subversion-repository-via-git</id>
   <content type="html">&lt;p&gt;This is quite simple on Linux.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install git, subversion and git-svn (the latter can be installed on Ubuntu using &lt;code&gt;apt-get install git-svn&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Acquire a copy of an svn repository (or just a folder in the repository) as a git repository locally&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git svn clone https://yoursubversionserver.com/svn/trunk/some_folder&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note: You can choose to omit the &#39;some_folder&#39; at the end if you want everything in trunk. You can also be more specific about which folder you are interested in, eg.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git svn clone https://yoursubversionserver.com/svn/trunk/some_folder/wow/really/specifc/folder&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change a file in the repository and use the usual &lt;code&gt;git commit&lt;/code&gt; command to commit it to a local repository&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To push changes from your local git repo to the subversion repo use&lt;/p&gt;

&lt;p&gt; &lt;code&gt;git svn dcommit&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To pull down changes from the remote subversion repo to your local git repository use&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git svn rebase&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Just to be clear - in the last step we really did use the &lt;code&gt;git svn rebase&lt;/code&gt; command to get changes from the remote repository.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;blockquote&gt;&lt;p&gt;Do not use &lt;code&gt;git pull&lt;/code&gt;. See the REBASE VS. PULL/MERGE section of the &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-svn.html&quot;&gt;git-svn docs&lt;/a&gt; as to why&lt;/p&gt;

&lt;p&gt;Do not use &lt;code&gt;git clone/pull/merge/push&lt;/code&gt; on your local git repositories that are derived from a subversion repo. See the CAVEATS section of the &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-svn.html&quot;&gt;git-svn docs&lt;/a&gt; as to why&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;More basic examples are also list at the bottom of the &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/git-svn.html&quot;&gt;git-svn docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And if you want to see a great example of a git-svn workflow in action, check out Jérémie Laval&#39;s blog post - &lt;a href=&quot;http://blog.neteril.org/2010/03/02/working-on-mono-with-git-svn/&quot;&gt;Working on Mono with git-svn&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Lifting the lid on Open Jam!</title>
   <link href="http://www.theirishpenguin.com/2010/04/16/lifting-the-lid-on-open-jam.html"/>
   <updated>2010-04-16T01:48:14+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/04/16/lifting-the-lid-on-open-jam</id>
   <content type="html">&lt;p&gt;Open Jam was an Ubuntu Ireland lead event which invited all members of the Open Source community to come along to Enterprise Ireland&#39;s Dublin offices at East Point on Saturday the 27th of March. And come along they surely did, really show-casing the diversity of groups we have here in Ireland - users of Open Source software, developers, admins and advocates. The timing of Open Jam was to coincide with the Ubuntu Global Jam - where contributors to the Ubuntu project focus on finding, prioritising and fixing bugs as well improving documentation, artwork and more. The &#39;Open&#39; in Open Jam was to extend that spirit to everyone - independent of their area of interest or skillset - to collaborate, learn and share.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/P1000466.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After the welcoming talk, some people got straight down to business, while others took the opportunity to chat and chill out after a long week in the office. Thanks to the excellent organisation skills of David Scanlon of Enterprise Ireland the event sported two rooms - one main room where you could hack away on your favourite project and another where liked-minded folks could get together and have a BoF (Birds of a Feather) session on a particular topic. Tunes were supplied on the day, pumped through Enterprise Ireland&#39;s very tasty A/V system, by Luis Bethencourt - a.k.a. Mr Ubuntu Studio (&lt;a href=&quot;http://ubuntustudio.org&quot;&gt;Ubuntu Studio&lt;/a&gt; is a multimedia creation flavor of Ubuntu that Luis leads). In the BoF room, Rory Geoghegan kicked off the proceedings with a great intro to the &lt;a href=&quot;http://www.python.ie&quot;&gt;Python&lt;/a&gt; programming language. This was followed by Anton Krasovsky&#39;s highly popular talk on Erlang - which seemed to bring out the inner developer in everyone and sparked a meandering conversation through programming patterns, architectures and practices of every language under the sun. Anton is the author of &lt;a href=&quot;http://pavo.me&quot;&gt;pavo.me&lt;/a&gt; - a mulitmedia Twitter client for any pretty much phone that supports Java.&lt;/p&gt;

&lt;p&gt;After lunch, which was graciously sponsored by Microsoft, Rory McCann gave an insightful talk on Ubuntu&#39;s software collaboration platform &lt;a href=&quot;https://launchpad.net&quot;&gt;Launchpad&lt;/a&gt;. Laurent Coudeur, part of the GNOME translations team, presented on the theme of language translations. He&#39;s always on the lookout for people to help the translation effort (especially regarding Irish, so if you&#39;re interested in helping then get in touch with him on his &lt;a href=&quot;http://desinterets.wordpress.com/2010/03/28/ubuntu-globaljam&quot;&gt;blog&lt;/a&gt;, where he also has a write up and more photos of Open Jam). Away from the lightning talks, &lt;a href=&quot;http://halolabs.org&quot;&gt;Halo Labs&lt;/a&gt;, which is a community of Independent IT Service Providers, were beavering away on Linux appliances like Workgroup Server &amp;amp; Asterisk Box, with Patrick O&#39;Conner and Russell Davies probably scooping the award for being the most industrious attendees!&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/P1000468.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Musical talent was a feature of the day, with Harry van Haaren from U.L. providing a really interesting lightning talk on his work in progress &lt;a href=&quot;http://harryhaaren.org&quot;&gt;Luppp&lt;/a&gt; project; hooking up a MIDI board to his C++ based looping software - allowing part of a live instrument performance to be looped on the fly and built upon. UCD Open Source Labs (represented by Alexander Ufimtsev, Keith Byrne, Aidan Church, David Murphy and Chris Duffin) announced their availability to to support Open Source projects by providing facilities for collaboration, project planning and development of Open Source software - check out the &lt;a href=&quot;http://osl.ucd.ie&quot;&gt;UCD Open Source Labs website&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;The Open Source .NET scene had a strong presence with &lt;a href=&quot;http://dublinalt.net&quot;&gt;Dublin Alt.NET&lt;/a&gt; members on hand ready to participate in any conversation that had the mere mention of the words &#39;design pattern&#39; :-) Andrea Magnorsky introduced the audience to the .NET DLR (Dynamic Language Runtime), which allows languages such as Ruby and Python to run on the .NET framework. Mono hackers Alan McGovern and Jérémie Laval gave a lively talk on the Mono framework, MonoDevelop and related platforms such as MonoTouch for the iPhone and Moonlight. Qamir Hussain presented on A.I. &amp;amp; Distributed Agent frameworks which he&#39;s working with at the moment. Later in the day, Rory McCann was back on stage, this time with Larry O&#39;Neill, to give a talk on the facinating &lt;a href=&quot;http://www.openstreetmap.org&quot;&gt;Open Street Map&lt;/a&gt; project, which marches on mapping the world in an Open fashion. Oh and some random walked in off the street and chipped in with a quick talk on Qt, &lt;a href=&quot;http://www.rubyireland.com&quot;&gt;Ruby&lt;/a&gt; and Rails :-)&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/P1000471.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;To round off, again a big thanks to David at E.I. for being such a kind host and also Laura Czajkowski, Jeffrey Roe and Qamir Hussain for helping to organise the event. It&#39;s great to have Enterprise Ireland helping events like this, which really boost the Open Source community and innovation in Ireland. Most of all, thanks to you, everyone who showed up and helped make it a great event. The good news is that there&#39;s no let up in the flood of Open Source events in the next few weeks with &lt;a href=&quot;http://www.ossbarcamp.com&quot;&gt;OSSBarcamp&lt;/a&gt; on April 17th and &lt;a href=&quot;http://codingday.org&quot;&gt;Open Spaces Coding Day&lt;/a&gt; on April 24th. Phew! Being Open was never so easy!&lt;/p&gt;

&lt;p&gt;P.S. While the resulting projects need not be Open Source, a superb sounding collaborative event that&#39;s on the horizon and worth a mention is Dublin&#39;s Startup Weekend! This could be your chance to get that great idea in the back of your head implemented over a weekend sprint with other techies involved. It&#39;s being organised by Sean Murphy and if interested visit the &lt;a href=&quot;http://dublin.startupweekend.org&quot;&gt;Startup Weekend&lt;/a&gt; website for more details.&lt;/p&gt;

&lt;p&gt;P.S. If you want to leave your twitter handle to get in contact with others at the event then feel free to edit it into the &lt;a href=&quot;http://openevents.ie/doku.php?id=openjam-signup#attendees&quot;&gt;Open Jam Attendees List&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And finally, some more Open Jam pics...&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/P1000464.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/P1000465.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images/P1000463.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hooking up a laptop to a projector using Nvidia Twinview on Kubuntu</title>
   <link href="http://www.theirishpenguin.com/2010/03/29/hooking-up-a-laptop-to-a-projector-using-nvidia-twinview-on-kubuntu.html"/>
   <updated>2010-03-29T07:33:50+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/03/29/hooking-up-a-laptop-to-a-projector-using-nvidia-twinview-on-kubuntu</id>
   <content type="html">&lt;h3&gt;UPDATE 1&lt;/h3&gt;

&lt;p&gt;As far as it can be confusing as to whether Nvidia Twinview is changing the underlying resolution of your display. Here&#39;s some tips that may help&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Adjust the resolution &lt;strong&gt;&lt;em&gt;before&lt;/em&gt;&lt;/strong&gt; you hook up your laptop to a projector&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you adjust the resolution and it doesn&#39;t look like what you would expect (eg. the bottom half your display is missing) then logging out and back in may help&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;UPDATE 2&lt;/h3&gt;

&lt;p&gt;I found that adjusting the display settings using a tool other than Twinview helped (in KDE on OpenSuse 11.2 I found that searching for sax2, a part of YaST, let me change my screen resolution without problems - once I dropped the screen resolution to be the same as the resolution of the projector then I didn&#39;t need to mess around with Twinview at all).&lt;/p&gt;

&lt;p&gt;Here is the rest of the original article...&lt;/p&gt;

&lt;p&gt;The number of configuration options can be a bit daunting when you haven&#39;t used Nvidia Twinview before. Here&#39;s a quick simple recipe&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set both the laptop screen to be the same as the maximum supported resolution of the projector (you can use the &#39;Model&#39; dropdown list to choose between settings for the laptop and the projector). If you set the of the project to Auto and click apply the diagram should tell you the max supported resolution for the projector&lt;/li&gt;
&lt;li&gt;Ensure position is set to Absolute for both the laptop and the projector&lt;/li&gt;
&lt;li&gt;You can drag the actual boxes representing each screen in the diagram but the best thing to do is ensure they overlap as much as possible&lt;/li&gt;
&lt;li&gt;Finally click Apply and you should get a pretty good match. You may still need to resize the window you want to show in order to get the projector fully displaying it&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Getting Google Calendar to work with KDE's KOrganizer, Kontact and KMail (on Kubuntu 9.10 Karmic Koala)</title>
   <link href="http://www.theirishpenguin.com/2010/02/19/getting-google-calendar-to-work-with-kdes-korganizer-kontact-and-kmail-on-kubuntu-9-10-karmic-koala.html"/>
   <updated>2010-02-19T09:30:42+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/02/19/getting-google-calendar-to-work-with-kdes-korganizer-kontact-and-kmail-on-kubuntu-9-10-karmic-koala</id>
   <content type="html">&lt;p&gt;Woah! That&#39;s a lot of K&#39;s in the title! But it&#39;s all in the name of getting your calender talking to your desktop so it&#39;s for a good kause (sorry!)&lt;/p&gt;

&lt;p&gt;There&#39;s this great package in KDE that has a really cool name called Akonadi (pronounced Ahh-Kon-ahh-dee if you want to impress your friends!). But more than just a cool name it does cool things - particularly in the realm of syncing data on your desktop with a remote server. Ooo yeah, including Google&#39;s servers. Akonadi is one of the &#39;pillars&#39; of the KDE platform and here&#39;s how you can use that pillar to prop up your schedules and calendaring with KOrganizer-Google integration. It&#39;s easy on Kubuntu Karmic!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install the Google data package for Akonadi&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install akonadi-kde-resource-googledata
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure the Akonadi Tray Utility is running by performing the following steps&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for Akonadi in the search box of the Kickoff Launcher (KDE&#39;s &quot;Start&quot; menu). Click the Akonadi Tray Utility that is found&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the tray on the bottom right of your beautiful KDE desktop and click the small arrow, if necessary, to to expand all the tray icons&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should see an icon for Akonadi. Right click on it and select &#39;Start Akonadi&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This should start the Akonadi server. You can verify this by right clicking the icon again and checking to see that there is now a &#39;Stop Akonadi&#39; option&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Right click on the Akonadi icon yet again and select &#39;Configure&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under the Akonadi Resources configuration, click Add and elect to add a Google Calendar Data Resource&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter your login details for your google account&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next it&#39;s off to Kontact. Go to the Calendar in Kontact&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There should be a small Calendar pane on the bottom right to set up calendar resources. Click the Plus sign to add an &quot;Akonadi (Provides access to calendars stored in Akonadi calendar folders)&quot;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the resulting popup, choose the google resource in the list and ensure that Events is ticked to the right of it. (I didn&#39;t try to get Todos or Journals working because I don&#39;t use them)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hey presto! All your calendar details should now be pulled into KOrganizers calendar! Hurrah!!!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Just to note, at time of writing I found that I had to search and find the Akonadi Tray Utility on restarting the computer. Once it&#39;s in the System Tray elect to start Akonadi as we did above and you&#39;re back in the game! If you find a solution to this minor inconvenience on restarting your machine then please post below!&lt;/p&gt;

&lt;p&gt;Thanks to Christian Mangold for this &lt;a href=&quot;http://neversfelde.de/?p=5&quot;&gt;article&lt;/a&gt; which served as a great reference.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Ruby Module that mixes in Class Methods (static) and Instance Methods</title>
   <link href="http://www.theirishpenguin.com/2010/02/04/a-ruby-module-that-mixes-in-class-methods-static-and-instance-methods.html"/>
   <updated>2010-02-04T11:08:34+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/02/04/a-ruby-module-that-mixes-in-class-methods-static-and-instance-methods</id>
   <content type="html">&lt;p&gt;Ho ho, this one can catch you out more than once so it&#39;s high time to write a blog post to cover this off. Turns out it&#39;s a commonly used pattern to the rescue. Thanks to eoin on #ruby.ie for pointing to the solution on &lt;a href=&quot;http://railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/&quot;&gt;RailsTips.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here&#39;s quite a tasty diagram too for &lt;a href=&quot;http://smartbomb.com.au/2009/02/an-idiom&quot;&gt;easy reference&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;module Swingable

    def self.included(base)
        base.extend(ClassMethods)
    end


    def instance_swing
        puts &#39;Did an instance swing!&#39;
    end

    module ClassMethods
        def static_swing
            puts &#39;Did a static swing!&#39;
        end
    end
end

class BaseballBat
   include Swingable
end

BaseballBat.static_swing
BaseballBat.new.instance_swing
&lt;/code&gt;&lt;/pre&gt;
</content>
 </entry>
 
 <entry>
   <title>ossdev-ireland: A new Irish Open Source Developers Group</title>
   <link href="http://www.theirishpenguin.com/2010/01/18/ossdev-ireland-a-new-irish-open-source-developers-group.html"/>
   <updated>2010-01-18T09:23:35+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/01/18/ossdev-ireland-a-new-irish-open-source-developers-group</id>
   <content type="html">&lt;p&gt;ossdev-ireland is a group set up to act as a melting pot for the various different Open Source groups in Ireland.&lt;/p&gt;

&lt;p&gt;Many group mailing lists already exist in Ireland for individual technologies, development languages and frameworks. However, each community is sandboxed into its own world. As a result there is less chance for cross-pollination of ideas between FOSS technologies, communities and individuals. The ossdev-ireland mailing list is to augment the existing mailing lists as a place to share ideas across the entire Open Source development community in Ireland.&lt;/p&gt;

&lt;p&gt;In particular, it would be great to see the outcomes of code jams, bug triage sessions, or even links to slides that were presented at a group meetup, posted here. You never know who may be interested!&lt;/p&gt;

&lt;p&gt;So if you want to browse or join ossdev-ireland, please visit us at &lt;a href=&quot;http://groups.google.com/group/ossdev-ireland&quot;&gt;http://groups.google.com/group/ossdev-ireland&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Qt Programming Tips</title>
   <link href="http://www.theirishpenguin.com/2010/01/16/qt-programming-tips.html"/>
   <updated>2010-01-16T23:17:07+00:00</updated>
   <id>http://www.theirishpenguin.com/2010/01/16/qt-programming-tips</id>
   <content type="html">&lt;p&gt;This is a little more of an unusual blog post. It&#39;s going to simply house a slowly growing list of Qt tips over time. Here goes&lt;/p&gt;

&lt;h3&gt;Tip 1&lt;/h3&gt;

&lt;p&gt;Qt has the concept of models baked in. Usually you will only want to use them if you have a list of records involved. So let&#39;s say you have a list of contacts like in an address book then this could be encapsulated in a QAbstractTableModel. If you just want to display a record in one-off fashion you can just populate a bunch of form fields (such as QLineEdits).&lt;/p&gt;

&lt;p&gt;UPDATE: On revisiting this post 2 years later I can see I didn&#39;t have many tips to add :-)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Santa's got Gems baby! Ruby Ireland Christmas Meetup 2009</title>
   <link href="http://www.theirishpenguin.com/2009/12/18/santas-got-gems-baby-ruby-ireland-christmas-meetup-2009.html"/>
   <updated>2009-12-18T08:11:49+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/12/18/santas-got-gems-baby-ruby-ireland-christmas-meetup-2009</id>
   <content type="html">&lt;p&gt;Ho ho ho! The month&#39;s Ruby Ireland meetup sprag right out of the traps with early adopters showing up at 6pm in the lobby area of the Trinity Capital Hotel, Wed Dec 16th. Easing into the evening with a 4 euro pint and talk of Android phones - seemingly the top item of everyone&#39;s Christmas shopping list - the latest crop of gems in the Ruby world was in hot debate, &lt;a href=&quot;http://gemcutter.org/&quot;&gt;gemcutter&lt;/a&gt; in particular.&lt;/p&gt;

&lt;p&gt;A couple of folks had been playing around with &lt;a href=&quot;http://rubygame.org/&quot;&gt;RubyGame&lt;/a&gt; for visualising data as it changes on the fly - showing that this framework is for more than just gaming. The XML/HTML parser &lt;a href=&quot;http://nokogiri.org&quot;&gt;Nokogiri&lt;/a&gt; was also mentioned a few of times in passing, with the particularly eye-catching quote &quot;XML is like violence - if it doesn’t solve your problems, you are not using enough of it&quot; adorning the home page of its website. And the cracking little tool &lt;a href=&quot;http://www.gitready.com&quot;&gt;tig&lt;/a&gt; was also brought up, which has a dinky little ncurses interface into git repositories. Pretty cool; not least because it makes it easier for newbies to avoid being bitten when they start git&#39;tin.&lt;/p&gt;

&lt;p&gt;The downstairs lobby in the hotel worked out great for people to meet up and relax, with most people turning up at the scheduled 7 o clock for kick off. From there we took over the, what has to be said, pretty classy meeting room complete with old style couches and some Joan Miró paintings. Just in tune with the creative buzz we had going on. There wasn&#39;t too much talk of Ruby for a while as most people were in stunned admiration of the room. Then the food platter arrived. Impressively, this is when everyone showed off their good manners by looking shyly at the platter for a few minutes, with that kind of &quot;You first, sir&quot; glint in their eye, before taking the plunge and sinking into the pakoras and wedges! Pretty much undoing any good work in the gym from earlier in the day!&lt;/p&gt;

&lt;p&gt;One of the funnier moments of the night was when someone went to check the tweets against the (now settled upon) #rubyireland hashtag. Only to find lost rubyists tweeting from the hotel lobby as to where the meetup was on. After a quick runaround the lobby to herd anyone wielding a Macbook into the meeting room, the evening was back on track. We split up into a few smaller groups, with the main walk-through being on the &lt;a href=&quot;http://github.com/theirishpenguin/qtonrails&quot;&gt;qtonrails&lt;/a&gt; - a Rails plugin to simply developing applications on Linux and other platforms using Nokia&#39;s Qt framework atop Rails.&lt;/p&gt;

&lt;p&gt;To finish off we had a bit of improv comedy from everyone at different closing stages of the evening; in particular Paul O&#39;Malley with his faithful rendition of an emotion beekeeper. And yes now we&#39;re straying off topic so it&#39;s probably time to go. We&#39;ll leave you with Paul&#39;s &lt;a href=&quot;http://funnycan.be/?p=295&quot;&gt;write up&lt;/a&gt; of last night&#39;s shenanigans :-)&lt;/p&gt;

&lt;p&gt;Thanks to everyone who showed. Have a great Christmas and catch ye all in Jan 2010 - surely destined to be the decade of Ruby domination!&lt;/p&gt;

&lt;p&gt;Ciao,
Dec&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Generate Rails Migrations from your PostgreSQL or MySQL database</title>
   <link href="http://www.theirishpenguin.com/2009/11/26/generate-rails-migrations-from-your-postgresql-or-mysql-database.html"/>
   <updated>2009-11-26T09:33:59+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/11/26/generate-rails-migrations-from-your-postgresql-or-mysql-database</id>
   <content type="html">&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new empty Rails project called schemer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In your config/database.yml file, point at the database you wish to dump to a migrations file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the command &lt;code&gt;rake db:schema:dump&lt;/code&gt; This should create a db/schema.rb file. Amazingly this effectively is your migrations file!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To tidy up create a file called file &lt;code&gt;db/migrate/20091125205635_create_initial_schema.rb&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then copy the create_table statements from the schema.rb file into the new file &lt;code&gt;20091125205635_create_initial_schema.rb&lt;/code&gt; Here&#39;s a template&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class CreateInitialSchema &amp;lt; ActiveRecord::Migration

    def self.up
        # Put all create_table statements from schema.rb file here
        # Note: You don&#39;t need the &#39;ActiveRecord::Schema.define(:version&#39;
        # line or it&#39;s enclosing end statement
        # ...
        # ...
    end

    def self.down
        # Don&#39;t really need this
    end

end
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once you&#39;ve all this done you can just run &lt;code&gt;rake db:migrate&lt;/code&gt; and you should have a new sqlite db up and running under db/development.sqlite3&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Thanks to Justin Ball on this Nobody Listens Anyway blog at &lt;a href=&quot;http://www.justinball.com/2008/05/09/dump-an-existing-database-schema-into-a-ruby-on-rails-migration-ready-format/&quot;&gt;Dump an Existing Database Schema Into a Ruby On Rails Migration Ready Format&lt;/a&gt; for the basis of this tip. Sometimes somebody does...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Eight Useful Git Tips</title>
   <link href="http://www.theirishpenguin.com/2009/11/22/eight-useful-git-tips.html"/>
   <updated>2009-11-22T13:35:36+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/11/22/eight-useful-git-tips</id>
   <content type="html">&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You can check your config using &lt;code&gt;git config -l&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This tells you useful stuff like what remotes you&#39;re bound to, etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can blow away files listed as &#39;untracked&#39; (by the &lt;code&gt;git status&lt;/code&gt; command) using &lt;code&gt;git clean&lt;/code&gt; (be careful!).&lt;/p&gt;

&lt;p&gt;If you want any of those files to hang around (but not appear as &#39;untracked&#39;) then add them to your &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can re-enter your last commit using &lt;code&gt;git commit --amend&lt;/code&gt;. What&#39;s nifty is that you can change files (including file addition and deletion) as well as the commit message. Just do what you gotta do before running the amend command and enter a replacement commit message.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can undo your last commit completely using &lt;code&gt;git reset HEAD^&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note: This does not change the working tree.&lt;/p&gt;

&lt;p&gt;Alternatively, you can use the syntax &lt;code&gt;git HEAD~2&lt;/code&gt; instead of &lt;code&gt;HEAD^^&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Refer to the last revision by &lt;code&gt;HEAD&lt;/code&gt;, the second last as &lt;code&gt;HEAD^&lt;/code&gt; and the third last as &lt;code&gt;HEAD^^&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can keep adding carrets forever! Sounding like Bugs Bunny there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can see the contents of a file from a revision using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git show rev:path/to/file
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ok, this tip is a bit of a longer one. Use &lt;code&gt;git merge some_other_branch&lt;/code&gt; to merge another branch into the one your working on. (Note that &lt;code&gt;git pull&lt;/code&gt; does a merge automatically once it&#39;s completely - if you don&#39;t want this to happen use &lt;code&gt;git fetch&lt;/code&gt;). There are a few possible outcomes:&lt;/p&gt;

&lt;p&gt;Fast-forward merge : If changes were made on only one of the branches since the last merge, then the merge should happen without any need for you to act.&lt;/p&gt;

&lt;p&gt;Three-way merge: If changes were made on both branches, then git decides how to merge them using an algorithm. If any changes conflict with each other, then git will report them and let you resolve them. Once you&#39;ve fixed any conflicts then you can &lt;code&gt;git commit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If there were no conflicts, git automatically does a commit with a stock commit message for the log. If you don&#39;t like the idea of this then use &lt;code&gt;git merge --no-commit some_other_branch&lt;/code&gt; You need to manually do the commit afterwards. (This is more like how other distributed VCS&#39;s such as Mercurial. This was the tip that inspired this post!).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, one tip that I found useful is that you don&#39;t want to &lt;code&gt;git pull&lt;/code&gt; into your repository when you have uncommitted changes. Especially if you treasure your sanity. Instead &lt;code&gt;git stash&lt;/code&gt; is your friend. Here&#39;s how&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do a &lt;code&gt;git stash&lt;/code&gt; to move your uncommitted changes to a magical place in git temporarily&lt;/li&gt;
&lt;li&gt;Then do the &lt;code&gt;git pull&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;And finally do a &lt;code&gt;git stash apply&lt;/code&gt; This will now move your &#39;stashed&#39; uncommitted changes back (from the magical temporary place in git) into your working directory and take into account what what was changed by the pull. Neat!&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Tips 1-7 taken from:  &lt;a href=&quot;http://git.or.cz/course/svn.html&quot;&gt;Git - SVN Crash Course&lt;/a&gt;. Tip 8 taken from painful experience :-)&lt;/p&gt;

&lt;p&gt;If you want a good detailed yet friendly reference on a particular command search the &lt;a href=&quot;http://www.kernel.org/pub/software/scm/git/docs/user-manual.html&quot;&gt;Git User Manual&lt;/a&gt; on kernel.org.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</content>
 </entry>
 
 <entry>
   <title>Getting Contact Form Emailing working with CForms in Wordpress</title>
   <link href="http://www.theirishpenguin.com/2009/11/20/getting-contact-form-emailing-working-with-cforms-in-wordpress.html"/>
   <updated>2009-11-20T11:59:57+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/11/20/getting-contact-form-emailing-working-with-cforms-in-wordpress</id>
   <content type="html">&lt;p&gt;&quot;Oh thou horrid little hard-coded piece of Javascript.&quot; That&#39;s our take on the jumping through hoops required to get this little plugin emailing this week. Here&#39;s why...&lt;/p&gt;

&lt;p&gt;On uploading the wordpress site from a development machine (which had the cforms plugin installed locally) to a server online, we could not get a contact form created with CForms to send out an email. Instead, it would say &quot;One moment please&quot; but alas that moment would never end. We tried TLS settings and permission changes but nothing worked. Fortunately there was a solution which we came across at the plugin&#39;s somewhat squashed &lt;a href=&quot;http://www.deliciousdays.com/cforms-forum/troubleshooting/cforms-hangs-after-submit-one-moment-please/&quot;&gt;forum&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When we had developed the site locally, the plugin had hardcoded a variable &#39;sajax_uri&#39; into the /wp-content/plugins/cforms/js/cforms.js. This is what was causing the pesky problemo and a quick edit of that file to point the variable at a correct URL for our server fixed the issue.&lt;/p&gt;

&lt;p&gt;Hmm... I&#39;m sure there&#39;s a good reason is not a variable in a config somewhere. There&#39;s a few hours of my evening I&#39;ll never get back...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Installing Ruby On Rails on Windows</title>
   <link href="http://www.theirishpenguin.com/2009/11/19/installing-ruby-on-rails-on-windows.html"/>
   <updated>2009-11-19T12:19:39+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/11/19/installing-ruby-on-rails-on-windows</id>
   <content type="html">&lt;p&gt;There were a couple of great outcomes from the first Free Ruby Lesson we ran in the Havana cafe on Dublin&#39;s Georges St last Monday. The first was getting everyone hacking with the Rails stack and some practical examples in double quick time. The second was managing to get RoR installed on Windows Vista as the lesson rumbled on in the background. Here&#39;s how Rails conquered Vista.&lt;/p&gt;

&lt;p&gt;We kicked off by following the instructions on the rails wiki (link no longer available). It&#39;s worth paying careful attention to anywhere it says to set path variables. If you find that you are getting an error that says that you version of rubygems is not recent enough (and you can&#39;t get rubygems to update itself) then you can install an older version of Rails, for example 2.3.2, using the following from the command line&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install rails -v 2.3.2
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Note: If you have already installed a different version of rails you can uninstall it first by using &#39;gem uninstall rails&#39;).&lt;/p&gt;

&lt;p&gt;The big problem however was getting sqlite3 working. We did install the SQLite Command Line Tool and the SQLite DLL as the Rails Wiki instructions said to - but to no avail. We kept getting a popup error saying that the sqlite3 dll was not found and to please consider reinstalling. Fortunately, we gambled on one of the answers on &lt;a href=&quot;http://stackoverflow.com/questions/515639/ruby-cannot-find-sqlite3-driver-on-windows&quot;&gt;StackOverflow&lt;/a&gt;. Basically the solution was from the command line&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem uninstall sqlite3-ruby
gem install sqlite3-ruby --source http://gems.rubyinstaller.org
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And with that we were away! The final thing was to get a nice friendly IDE installed so we plumbed for Netbeans on the &lt;a href=&quot;http://netbeans.org/downloads&quot;&gt;Netbeans Downloads page&lt;/a&gt;. Look out for the special Ruby version of Netbeans which is one of the links around the middle of the downloads page.&lt;/p&gt;

&lt;p&gt;Anyway, that&#39;s all for this week. Happy Ruby hacking!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Offline Documentation for Rails (and other Ruby gems)</title>
   <link href="http://www.theirishpenguin.com/2009/11/12/offline-documentation-for-rails-and-other-ruby-gems.html"/>
   <updated>2009-11-12T01:08:37+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/11/12/offline-documentation-for-rails-and-other-ruby-gems</id>
   <content type="html">&lt;p&gt;I used to pretty much always install gems with the --no-ri --no-rdoc options to speed up installation. Recently however, I&#39;ve found myself needing to get access to documentation whilst on the move. So just in case you don&#39;t know how that works, here&#39;s the deal.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install your gems as per normal (ie. don&#39;t use --no-ri or --no-rdoc)&lt;/li&gt;
&lt;li&gt;Run the command &#39;gem server&#39; from the command line&lt;/li&gt;
&lt;li&gt;Browse to http://localhost:8808&lt;/li&gt;
&lt;li&gt;And voila! You should have all the docs you need available by clicking on the rdoc link for any given gem&lt;/li&gt;
&lt;li&gt;But if you really want to get fancy check out the searchable Rails documentation at http://railsapi.com - there&#39;s an online version as well as the downloadable (the links are at the top of the page and can easily be mistaken for an advert!)&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Understanding how Ruby stores objects in memory - the Ruby Heap</title>
   <link href="http://www.theirishpenguin.com/2009/10/29/understanding-how-ruby-stores-objects-in-memory-the-ruby-heap.html"/>
   <updated>2009-10-29T00:54:48+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/10/29/understanding-how-ruby-stores-objects-in-memory-the-ruby-heap</id>
   <content type="html">&lt;p&gt;Ruby has it&#39;s own heap management which actually consists of several &#39;Ruby Heaps&#39; to manage objects created during the execution of a Ruby program; this is separate from the System Heap for your Operating System. Each individual Ruby Heap contains Slots, with each Slot able to one reference one object.&lt;/p&gt;

&lt;p&gt;The entire space that an object takes up in memory &lt;strong&gt;&lt;em&gt;is not stored inside the Slot&lt;/em&gt;&lt;/strong&gt;. Rather each Slot is a small fixed size space which can be thought of as the Ruby interpreter&#39;s handle a location in memory. This location exists outside of the Ruby Heap itself and contains the real &#39;meat&#39; of the object. To be clear, if you have a 50MB string - the 50MB of data is stored outside of Ruby&#39;s Heap. If you really want to know the story of the 50MB, the space for it is actually allocated by something like the malloc command in C (as good ol&#39; Ruby is written in C) and then stored on the System Heap. The Slot in the Ruby Heap simply contains a reference to that memory location on the System Heap which contains the 50MB of data.&lt;/p&gt;

&lt;p&gt;Here&#39;s an example. Let&#39;s say that a Ruby program creates a single string of 50MB
* A single free Slot in a Ruby Heap becomes filled
* Memory to store the 50MB of data that makes up the string itself is allocated in memory and put on the System Heap (outside the Ruby Heap!) and a reference to this location is stored in the Filled Slot on the Ruby Heap
* There comes a point in time when this string is no longer needed. This slot is garbage collected on the next GC iteration
* The Filled Slot is turned into a free slot. The 50MB of data in memory referred to by the slot is also freed and returned to the Operating System&lt;/p&gt;

&lt;p&gt;Ruby starts of with a minimal set of Ruby Heaps. These are managed by by a Ruby Heap list. Ruby creates Ruby Heaps when needed and frees Ruby Heaps back to the OS when no longer needed (the latter is done in a sub-optimal manner - more on this later). Each Ruby Heap created will be 1.8 times the size of the previous heap. In other words, it will contain 1.8 times the number of slots of the previous heap. Ruby&#39;s Garbage Collector, periodically iterates through the Ruby Heaps and frees up any Slots as appropriate (and also the memory that an object really occupies which is referenced by the Slot - ie. the 50MB data of the String) back to the system. Once a GC iteration is complete, some of the Slots that were filled will now be empty - known as Free Slots. Remember that we said that Ruby&#39;s Heap management actually consists of many Ruby Heaps. Well if one of these Ruby Heaps consists of only Free Slots then the Ruby Heap itself will be freed back to the Operating System.&lt;/p&gt;

&lt;p&gt;There is a problem with this last statement however - if a Ruby Heap contains mostly Free Slots and one Filled Slot then it will not be freed. You could have many Ruby Heaps in this state. As long as a Ruby Heap contains even one Filled Slot it will not be returned to the Operating System. It just takes one bad apple to spoil everything! What would be nice is if some sort of Heap Compaction (kind of like disk fragmentation) took place where all Filled slots were pushed together into completed filled Ruby Heaps. This would leave you with completely filled Ruby Heaps, one semi-filled Ruby Heap and then a bunch of completely empty Ruby Heaps. The completely empty Ruby Heaps could then be freed, releasing precious memory back to the Operating System. Alas the current mainstream Ruby interpreter does not do this.&lt;/p&gt;

&lt;h3&gt;References&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://izumi.plan99.net/blog/index.php/2007/10/12/how-the-ruby-heap-is-implemented/&quot;&gt;How the Ruby Heap is Implemented&lt;/a&gt; Phusion Passenger&#39;s Hong Lai gives a great explanation of the Ruby Heap - the banner may not be quite suitable for work. Fortunately, there&#39;s a censor button :-)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://www.coffeepowered.net/2009/06/13/fine-tuning-your-garbage-collector/&quot;&gt;Fine tuning your garbage collector&lt;/a&gt; Chris Heald explains some of the settings around garbage collection&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://blog.pluron.com/2008/01/ruby-on-rails-i.html&quot;&gt;Ruby&#39;s Garbage Collections effect on Ruby on Rails&lt;/a&gt; Pluron Inc&#39;s blog discusses so of the knock-on effects of Ruby GC on Rails and importantly mentions the 8 MB memory allocation tigger for the garbage collector&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>Bleak House - A Tool for measuring Objects in Memory for a Ruby Program</title>
   <link href="http://www.theirishpenguin.com/2009/10/28/bleak-house-a-tool-for-measuring-objects-in-memory-for-a-ruby-program.html"/>
   <updated>2009-10-28T02:41:15+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/10/28/bleak-house-a-tool-for-measuring-objects-in-memory-for-a-ruby-program</id>
   <content type="html">&lt;p&gt;Bleak House is a tool that tells us
- How many Slots there are in total at a point in time in a Ruby program
- How many Slots in total are filled
- How many Slots in total are empty (free)
- How many Filled Slots can be attributed to a particular line of code&lt;/p&gt;

&lt;p&gt;Bleakhouse can be used to tell you if program is holding on to objects that it should be relinquishing. But it doesn&#39;t tell you how much data is stored in memory for the &#39;meat&#39; of the object (ie. that 50MB of data in a 50MB String). Just because you know there is a Filled Slot exists - you don&#39;t know if the data in memory that correlates back to that Slot is 1MB, 10MB or 100MB.&lt;/p&gt;

&lt;p&gt;However, if you repeat a series of a specific set of operations a small number of times, measuring with Bleakhouse, and then restart the server with Bleak house and repeat the operations a large number of times and see a big difference in the number of filled slots can tell that your program is holding onto objects (references) that it should not. Of course, if your program is supposed to keep hold of an increasing number of references (such as a global variable or a singleton that keeps accumulating references for the duration of your program) then this would be expected. Though you might want to double check your design. You will be able to see the cause of the problem from the detailed breakdown of which lines of code were the biggest offenders in terms of creating objects. If you see a large number of free slots (relative to the number of filled slots) then this means that at some point in your program a lot of objects existed (possibly due to a spike in application usage) but then reduced.&lt;/p&gt;

&lt;p&gt;Does the free slots count matter? Well, yes because there is an memory overhead due to each free slot that exists - how much depends on your particular system. If your system has a slot size of 20 bytes then every one million free slots costs you an additional 20MB that is not being utilised. This becomes a problem if your application is subject to large but infrequent spikes in the number of objects that exist within your program a particular moment in time because the free slots are taking up significant amounts of memory even when your application is twiddling its thumbs between the spikes.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Getting Drupal 7 (development snapshot) running on Ubuntu</title>
   <link href="http://www.theirishpenguin.com/2009/09/28/getting-drupal-7-development-snapshot-running-on-ubuntu.html"/>
   <updated>2009-09-28T01:23:41+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/09/28/getting-drupal-7-development-snapshot-running-on-ubuntu</id>
   <content type="html">&lt;h2&gt;Notes before starting&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;At time of writing, only experimental snapshots of Drupal were available with the actual Drupal 7 release being some way off. The Drupal 5.x or Drupal 6.x series is recommended if you want to use Drupal in production&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This guide was written against Ubuntu 8.04&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This guide assumes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You have apache, mysql and php happily installed on your machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That you are serving websites out of /var/www/&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;That that sites under /var/www/ are accessible in your browser via http://localhost/&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Instructions&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download Drupal 7 from the development release section at and http://drupal.org/project/drupal&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extract the folder and rename the extracted folder to drupal7&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move the folder to an appropriate place on your webserver, such as under /var/www/&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a fresh settings file for your new Drupal 7 site. You should use the supplied settings file as a basis, eg.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;cp sites/default/default.settings.php sites/default/settings.php
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make the settings file writeable, so that the installer can edit it, using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chmod a+w sites/default/settings.php
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a database for your Drupal 7 site&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Log into mysql, eg.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mysql -uroot -p
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a database once logged into mysql from the &#39;mysql&gt;&#39; prompt, eg.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;create database drupal7;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a user for the database and grant permissions from the &#39;mysql&gt;&#39; prompt, eg.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES, CREATE TEMPORARY TABLES ON drupal7.* TO &#39;drupal7user&#39;@&#39;localhost&#39; IDENTIFIED BY &#39;drupal7password&#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the install script as follows&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Browse to your new Drupal site at http://localhost/drupal7/install.php&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Elect to proceed with a normal Drupal install (ie. not minimal) in your chosen language&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As you proceed through the wizard, the installer may encounter issues creating certain directories for Drupal on the file system. If so, ensure then do the following&lt;/p&gt;

&lt;p&gt;cd to the root of your drupal7 directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mkdir sites/default/files
mkdir -p sites/default/private/files
mkdir sites/default/private/temp
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Change the ownership of the created directories to belong to user account under which the web server runs under (www-data)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;chown -R www-data:www-data private
chown -R www-data:www-data files
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The wizard now asks you to configure the database settings. In the form presented by the wizard, replace the user &#39;admin&#39; with the &#39;drupal7user&#39; you created earlier and point at the drupal7 database. Remember to put in the correct password for &#39;drupal7user&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you get a 500 error in the last step, then ignore it and elect to continue through to the error page. This will actually let you continue the install&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you get the error starting with something like &quot;Fatal error: Allowed memory size of 16777216 bytes exhausted&quot; then allocate Drupal more memory in the settings file (see See http://drupal.org/node/90605 for more information), eg. Add the line&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ini_set(&#39;memory_limit&#39;, &#39;30M&#39;);
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Hopefully now you should be good to go!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Audacity Tip of the Day - How Not to Lose Data!</title>
   <link href="http://www.theirishpenguin.com/2009/09/19/audacity-tip-of-the-day-how-not-to-lose-data.html"/>
   <updated>2009-09-19T09:00:45+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/09/19/audacity-tip-of-the-day-how-not-to-lose-data</id>
   <content type="html">&lt;p&gt;One issue when editing audio, is copy and pasting a section of a track from one open Audacity project to another. To save space audacity does not copy the underlying track completely to the new project, rather it links to it. This means that your second project (the one you are pasting into) is not completely self-contained as it depends on external files. This can be a quickfire way for the unsuspecting podcaster to lose a whole bunch of data (yes, me!). This problem is particularly nasty as you don&#39;t realise something has gone wrong until you close and reopen the project - finding that a long stretch of audio containing your beautiful voice is missing. To avoid this, adhere to the following workflow when copy and pasting from one project to another.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the first project, select and copy the audio you wish to duplicate&lt;/li&gt;
&lt;li&gt;Paste the audio into the second project&lt;/li&gt;
&lt;li&gt;In the File menu of the second project, click &#39;Check Dependencies&#39;&lt;/li&gt;
&lt;li&gt;Click &#39;Copy All Audio into Project (Safer)&#39;&lt;/li&gt;
&lt;li&gt;Just to stress the previous point, you really do want to use the &lt;strong&gt;Safer&lt;/strong&gt; of the two copying options. I&#39;ve found that using the other option results in some of the audio I wanted to copy being truncated&lt;/li&gt;
&lt;li&gt;Save the project&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;By following this workflow you should hopefully avoid seeing what I call the &#39;dreaded blue flat-line of death&#39; where, on reopening of a project, you find that the middle of a track has been lost. If you adhere to these instructions you should also be able to select &#39;Delete orphaned files&#39; when it appears from time to time while reopening an Audacity project. However, due to the frustrating and sensitive nature of audio loss issues, I accept no responsibility for anything that goes wrong! Best of luck and happy editing!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Open Letter to the Irish Government on Open Source Driven Innovation</title>
   <link href="http://www.theirishpenguin.com/2009/09/18/open-letter-to-the-irish-government-on-open-source-driven-innovation.html"/>
   <updated>2009-09-18T08:39:29+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/09/18/open-letter-to-the-irish-government-on-open-source-driven-innovation</id>
   <content type="html">&lt;p&gt;&quot;Recent years show that openness and collaboration is essential to the generation of innovation in the software sector. Technology increasingly means software. In Ireland, we can see that the production of hardware technology in many, but not all, cases is providing ever diminishing returns. Here we outline some key policy recommendations that are crucial to the fulfilling the vision of making the Irish Smart Economy a reality for the software industry through the adoption and encouragement of Open Source technologies.&quot;&lt;/p&gt;

&lt;p&gt;The above extract is from a paper we are submitting to the &lt;a href=&quot;http://www.taoiseach.gov.ie/eng/Innovation_Taskforce/Request_for_Submissions/&quot;&gt;Innovation Taskforce&lt;/a&gt; as requested by the Department of Taoiseach. The draft paper is available at &lt;a href=&quot;http://www.weuseopensource.com/open-letter-to-irish-govt-on-open-source-driven-innovation.html&quot;&gt;Positioning Ireland as an International Innovation Hub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note, we are submitting the paper ahead of the deadline which is Friday the 18th of September. We appreciate any feedback, support or criticisms you may have. Please post them as comments below.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Simple straight up caching for pages served by Heroku</title>
   <link href="http://www.theirishpenguin.com/2009/09/16/simple-straight-up-caching-for-pages-served-by-heroku.html"/>
   <updated>2009-09-16T10:08:24+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/09/16/simple-straight-up-caching-for-pages-served-by-heroku</id>
   <content type="html">&lt;p&gt;So you&#39;ve got an app that&#39;s ticking along nicely; being served up a good steak in a 5 star restaurant - but you&#39;d like to boost it&#39;s performance with some caching. For those who develop their apps on the Heroku platform, a great way to do this is to cache a dynamic page using Varnish. This means that your page is served up super fast without hitting Rails/Sinatra/whatever. And best of all it requires no extra gems or anything, just a well placed one-liner in your controller.&lt;/p&gt;

&lt;p&gt;Firstly, you can only use this technique if all users that visit this page expect to see the exact same content - in other words you have no &#39;per user&#39; customised content on a page. To help understand how this type of caching works, imagine that the first time your page (let&#39;s say an Events index page) is hit it is turned into a static html page for a pre-defined amount of time (let&#39;s say 60 seconds). Anyone else who visit this page (ie. anyone else who visits this particular controller action) during the next 60 seconds gets that static html page. After the 60 seconds the static html page is removed from the cache. Thus the next hit will cause your underlying dynamic page to be invoked; then the caching process kicks off again lasting another 60 seconds. And so on and so fourth.&lt;/p&gt;

&lt;p&gt;With the increasing amount of web applications that call APIs, such as Twitter&#39;s API, this is a really easy way to ensure that you do not end up spamming a service provider with an unreasonable number of calls per hour. This is the technique we use on www.thelisbontweety.com (link no longer available) to keep our API overhead down.&lt;/p&gt;

&lt;p&gt;So how do you do this? Simply put something along the lines of&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;response.headers[&#39;Cache-Control&#39;] = &#39;public, max-age=60&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;as the first line of your action for the page you wish to cache. The max-age setting means that this will be cached for 60 seconds. After you put this in your application and redeploy to Heroku, you can see if it&#39;s working by using http://hurl.it&lt;/p&gt;

&lt;p&gt;Just enter the  URL for your action and click Send. You should see something like &quot;Cache-Control: max-age=60, public&quot; in the output if it&#39;s working.&lt;/p&gt;

&lt;p&gt;And that&#39;s it! No need to install anything. Just cache your little heart out with Varnish. Top marks to chaps at Heroku for making this so easy to use out of the box at &lt;a href=&quot;http://heroku.com&quot;&gt;Heroku&lt;/a&gt;. For more on this technique check out their HTTP caching docs at &lt;a href=&quot;http://docs.heroku.com/http-caching&quot;&gt;http://docs.heroku.com/http-caching&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Packaging Ruby Apps for Ubuntu: Dissecting an existing Ruby Ubuntu Package</title>
   <link href="http://www.theirishpenguin.com/2009/09/09/packaging-ruby-apps-for-ubuntu-dissecting-an-existing-ruby-ubuntu-package.html"/>
   <updated>2009-09-09T09:34:13+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/09/09/packaging-ruby-apps-for-ubuntu-dissecting-an-existing-ruby-ubuntu-package</id>
   <content type="html">&lt;p&gt;One of the best ways to learn about how a Ubuntu package is put together is reverse engineer the package into it&#39;s constituent components. We are going to take a look at how to do this for the chef application and it&#39;s related libchef library is packaged as a Debian package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visit the page &lt;a href=&quot;http://packages.ubuntu.com/karmic/ruby/chef&quot;&gt;http://packages.ubuntu.com/karmic/ruby/chef&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Under the Download chef section, download the package via the &#39;All&#39; link into a directory called chef&lt;/li&gt;
&lt;li&gt;Visit the page &lt;a href=&quot;http://packages.ubuntu.com/karmic/ruby/libchef-ruby1.8&quot;&gt;http://packages.ubuntu.com/karmic/ruby/libchef-ruby1.8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Under the Download libchef-ruby1.8 section, download the package via the &#39;All&#39; link into a directory called libchef1.8&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;From the following guide (&lt;a href=&quot;http://www.g-loaded.eu/2008/01/28/how-to-extract-rpm-or-deb-packages&quot;&gt;http://www.g-loaded.eu/2008/01/28/how-to-extract-rpm-or-deb-packages&lt;/a&gt;) you can learn how to &#39;unzip&#39; a Debian package. This is easy as they are pure ar archives. Here&#39;s what we need to do&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the chef directory, run the commands&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ar vx chef_0.7.8-0ubuntu2_all.deb
tar -zxvf data.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the libchef1.8 directory, run the commands&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ar vx libchef-ruby_0.7.8-0ubuntu2_all.deb
tar -zxvf data.tar.gz
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Now you can study the layout of the of the data payload of the package (this is where to look in order to study the anatomy of the application as it was being packaged). This layout is what will be of most interest to you.&lt;/p&gt;

&lt;p&gt;If you have an application in a particular programming language that you wish to package, pick a similar application for which a package already exists and dissect it as shown above. Then bend your app into a similar shape in terms of directory layout before attempting to package it. To find out more about how to create your own Ubuntu packages check out this great video by Horst Jens &lt;a href=&quot;http://showmedo.com/videotutorials/video?name=linuxJensMakingDeb&quot;&gt;Ubuntu: Making a .deb package out of a python program&lt;/a&gt;. It&#39;s worth the effort of watching it to the end!&lt;/p&gt;

&lt;p&gt;Happy packaging!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bringing Back the Spirit of the Amateur Programmer</title>
   <link href="http://www.theirishpenguin.com/2009/08/26/bringing-back-the-spirit-of-the-amateur-programmer.html"/>
   <updated>2009-08-26T08:27:51+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/08/26/bringing-back-the-spirit-of-the-amateur-programmer</id>
   <content type="html">&lt;p&gt;In &lt;a href=&quot;http://www.kdedevelopers.org/node/4039&quot;&gt;a blog post&lt;/a&gt; this month, Richard Dale (the man behind Qt/KDE&#39;s Smoke bindings) eloquently phrased a noble goal,&lt;/p&gt;

&lt;p&gt;&quot;In the 1980s there were lots of computer magazines that used to publish programming articles with BASIC code, that everyone could input and run on their own computers. However, in the 1990s such large scale end user computer programming pretty much died out - tweaking the odd web page isn&#39;t quite the same thing. One of the assumptions that the Free Software movement makes is that every user is also a programmer of some sort, who is able to tweak the software on their computers. I hope we can get back to that spirit, and change the way that people think about KDE programming, because at the moment there is a tendency to think it is hard and that only the &#39;C++ gods&#39; like David Faure or Thiago Macieira can do it. In fact it is pretty easy to write small Python and Ruby apps and plasmoids, or to write a little script to message an app over DBus. We just need to get communities of like minded people together who write tutorials on TechBase, create blog entries with code (like the 1980s BASIC articles), and help beginners get started. These ubiquitous end user programming environments in Kubuntu (and other distributions I hope) will make it possible to do that.&quot;&lt;/p&gt;

&lt;p&gt;This really sums up something that would be fantastic to see over the next few years. There&#39;s so many gadget lovers and technology geeks out there - the type of people who would&#39;ve probably punched those BASIC tutorials into a Commodore 64, an Amstrad CPC464 or ZX Spectrum back in the good old days - that feel left behind as they perceive professional programmers to have blazed ahead a path that cannot be caught. But in many ways nothing could be further from the truth. For any programmer, there&#39;s always some guy or gal that&#39;s coding something more challenging or doing cleverer(er) stuff on the next machine. It&#39;s all relative. And since software turned into a mainstream industry over the last couple of decades, it&#39;s been the programmers doing the simplest tasks that have made the megabucks whilst the hardcore wizards of machine code and assembly have seen their demand dimish.&lt;/p&gt;

&lt;p&gt;So next time you think there&#39;s no point in picking up a few programming skills give a language like Ruby or Python a shot. Hopefully, with the continuing progress of Kubuntu and other distro&#39;s to make programming more accessible, you&#39;ll have the perfect environment to do so!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>HOWTO: Add a secondary hard drive for Windows via VirtualBox 2.1.4 OSE</title>
   <link href="http://www.theirishpenguin.com/2009/07/22/howto-add-a-secondary-hard-drive-for-windows-via-virtualbox-2-1-4-ose.html"/>
   <updated>2009-07-22T08:43:49+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/07/22/howto-add-a-secondary-hard-drive-for-windows-via-virtualbox-2-1-4-ose</id>
   <content type="html">&lt;p&gt;Sometimes one disk just isn&#39;t enough. In fact most times! Here&#39;s how to add an E Drive to your Windows Guest OS&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In VirtualBox, go to the File-&gt;Virtual Media Manager&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the New button to create a new hard disk and create a new hard drive file via the wizard (a .vdi file)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure Windows Guest OS has been shut down&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click on the Settings button for your Windows Guest OS, and choose the Hard Disks tab&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the .vdi file you just created to be a hard drive for the Guest OS by clicking the Add Attachmenticon on the right and selecting your .vdi file in the file explorer from the drop down list that appears, here is the typical order of drives on a system&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;IDE Primary Master: this is the main drive onto which your Guest OS is installed (very important!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IDE Primary Slave: this is the first additional drive you add on (ie. the E: drive)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IDE Secondary Slave: this is the second additional drive you add on&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once your done start up you Virtual Machine Guest OS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visit the Control Panel in Windows&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you&#39;re using XP elect to &#39;switch to classic view&#39; on the left of Windows Explorer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Visit Administrative Tools-&gt;Computer Management&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Under the storage node on the left, there should be a Disk Management node&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A wizard should instantly popup to help you add the drive as soon as you click on this, agree to its demands&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After the wizard, you should see a drive displayed as &#39;unallocated&#39; as you scroll down the list of drives&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Right click, select New Volume and before you know it you should be done!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now go and open Windows Explorer and experience the joy that is an extra drive!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</content>
 </entry>
 
 <entry>
   <title>A Breath of Fresh Air - The Well Grounded Rubyist</title>
   <link href="http://www.theirishpenguin.com/2009/06/09/a-breath-of-fresh-air-the-well-grounded-rubyist.html"/>
   <updated>2009-06-09T13:05:09+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/06/09/a-breath-of-fresh-air-the-well-grounded-rubyist</id>
   <content type="html">&lt;p&gt;After a tough day in the office you want to catch up on the news, so you look at the ticker on a TV channel or tune in your car radio. Other days you&#39;ll want to sit down with a meaty broadsheet and really take in the detail of what lies behind the headlines. This is a book about Ruby which which triumphs at walking the line between these two styles. The Well Grounded Rubyist aims to appeal to a developer that has been exposed to some Ruby coding and take their knowledge to the next level. And it succeeds brilliantly.&lt;/p&gt;

&lt;p&gt;This is not a book about Rails or any other web frameworks; purely Ruby. Though much of the material will also apply to the 1.8.x series of Ruby, this is a book about the 1.9 version of the Ruby language. It&#39;s broken into three parts - Ruby foundations, Built-in classes and modules and finally Ruby dynamics. But don&#39;t let the title of Ruby foundations fool you for part one - this is not some remedial rush through the basics of Ruby in six chapters. Rather, after a couple of warm-up chapters, it moves quickly to clarify the key aspects of how classes and module inter-relate, as well things such as crystallising what &#39;self&#39; really means in different contexts in a Ruby program. The author sets out his stall early - what makes Ruby different from other languages is it&#39;s focus on objects rather than classes. Everything else stems from this and by the end of the section you feel like you have an understanding of Ruby&#39;s design and focus.&lt;/p&gt;

&lt;p&gt;Part two of the book is Built-in classes and modules. Now that you know what makes Ruby tick, it&#39;s time to get seeped in all aspects of the core library that ships with it. One of the problems when learning a language is that becoming familiar with all methods of a particular core class is a tedious task. It&#39;s much more interesting to learn about concepts such as meta programming than memorising lists of methods by rote. But if you don&#39;t take the time to familiarise yourself with the dusty corners of a language&#39;s API then you&#39;re less likely to think of those handy methods when a problem they would elegantly solve presents itself. At this point the book shifts gear to a more reference style of text. However, it still gives the reader an interesting story to follow as it documents arrays, hashes and other classes - throwing in the occasional golden nugget of information that will be a valuable additional to the toolbox of even experienced Rubyists. One side effect of the change in style is that this section is probably the most accessible to beginners. Again it&#39;s broken down into six chapters. In addition to collections, it also covers topics such as regular expressions and file handling. Each topic takes a zero-to-hero approach meaning that you can bring little regular expression knowledge to the table yet still walk away learning an immense amount about the subject.&lt;/p&gt;

&lt;p&gt;The final part of the book, Ruby dynamics, returns to the book&#39;s roots from part one - a focus on imparting a deep knowledge of Ruby&#39;s design. Before you even pick up this book you have an inkling that procs and lamdas are going to make a guest appearance at this late stage. And they do not disappoint. Extending the behaviour of objects takes centre-stage and meta-programming based techniques move quickly to the fore. Any block/proc/lamda confusion you may have will be a distant memory by the time you finish this section. Threading is also covered here - though a detailed discussion of 1.9&#39;s new native OS threads vs green threads is left to one side to focus on the usage of threads regardless of which underlying type you use. Lots of material is also provided on querying objects; which is not only useful for program design but also invaluable as a debugging aid. The book really shines in this section because a lot of other texts make the mistake of going into &#39;super-boffin&#39; mode at this point, leaving the reader lost, whereas the author here continues to provide patience and context to get you round that final lap on you way to becoming a Well Grounded Rubyist!&lt;/p&gt;

&lt;p&gt;This book cannot be all things to all people. Because it is catering for a wide range of intermediate to advanced Rubyists, it will feel like it&#39;s moving a little too slowly for some. By the author&#39;s own admission, this is in order to make it accessible to a wider audience and no doubt it will make it easier for developers of all levels to digest - your humble reviewer very much included! Ruby first-timers would be best off having some straight-to-the-point tutorials or entry-level text to hand in order to get some instant gratification - as part one of the book, by it&#39;s very nature, is a little more abstract than a complete beginner would expect. But all in all, this book is a great way to learn just how Ruby crams so much expressiveness into such a simple clean framework. Whenever I read a book like this I keep a list of new things learned along the way. For The Well Grounded Rubyist it is a very long list! Well done to David A. Black and Manning for producing a book that fills those gaps in many Rubyists&#39; understanding of the language while at the same time delivering an absorbing readable book that would sit proudly on any Ruby programmer&#39;s bookshelf.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Optimising Apache serving Ruby on Rails via Passenger</title>
   <link href="http://www.theirishpenguin.com/2009/05/11/optimising-apache-serving-ruby-on-rails-via-passenger.html"/>
   <updated>2009-05-11T05:12:00+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/05/11/optimising-apache-serving-ruby-on-rails-via-passenger</id>
   <content type="html">&lt;p&gt;An unusual blog post this in that I have such little value to add other than pointing you at two great links. The first is a wonderfully useful post on tweaking Phusion Passenger when &lt;a href=&quot;http://www.cordinc.com/blog/2009/02/rails-performance-options-on-p.html&quot;&gt;running some Rails apps on a 256MB Slicehost VPS&lt;/a&gt; and the other link is a no-nonsense explanation of &lt;a href=&quot;http://forum.slicehost.com/comments.php?DiscussionID=3313&quot;&gt;tweaking Apache config options&lt;/a&gt; to cut down on your swap memory usage. Thanks so much to these folks!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>VirtualBox and Running a Virtual Ubuntu Image within an Ubuntu Host</title>
   <link href="http://www.theirishpenguin.com/2009/03/27/running-a-virtual-ubuntu-image-within-an-ubuntu-host.html"/>
   <updated>2009-03-27T10:33:18+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/03/27/running-a-virtual-ubuntu-image-within-an-ubuntu-host</id>
   <content type="html">&lt;p&gt;&quot;What?&quot; you say, &quot;that&#39;s a lot of Ubuntu going on! Why would you want to do such a thing?&quot; The answer - for testing applications, replicating environments or perhaps running a few servers on one box.&lt;/p&gt;

&lt;p&gt;This guide should work pretty well for any Linux distro, though you may need to replace the aptitude commands with the package manager of your choice. Here we&#39;ll install a Hardy Heron guest inside an Intrepid Ibex host. Afterwards, we&#39;ll also use dselect with apt in order to clone the packages on a machine we wish to replicate onto our guest OS. Oh ho the fun! Here goes...&lt;/p&gt;

&lt;p&gt;We&#39;ll start from scratch on your developer (host) machine with no prerequisites. Here are the steps&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install the VirtualBox program&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo aptitude install virtualbox
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install 7zip, needed to extract downloaded image&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo aptitude install p7zip
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download Ubuntu 8.04 Hardy Heron iso image from &lt;code&gt;http://virtualbox.wordpress.com/images/ubuntu/&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make a new folder called my_temp&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Move the downloaded file into my_temp
cd into my_temp
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extract image&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;p7zip -d downloaded_imagefile
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This should yield a folder called something like ubuntu-8.04-x86
cd into this directory and run&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mv VDI/ubuntu-8.04-x86 ~/.VirtualBox/VDI
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a new virtual machine&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run VirtualBox (should be in Accessories under the Applications menu or just type &#39;virtualbox&#39; at the command line)&lt;/li&gt;
&lt;li&gt;Click the New button to create a new virtual machine&lt;/li&gt;
&lt;li&gt;Create a name for your Virtual Machine and set it&#39;s OS Type&lt;/li&gt;
&lt;li&gt;Set the base memory to 256MB&lt;/li&gt;
&lt;li&gt;Elect to add an &#39;Existing Hard Disk&#39;, you the Add button and choose the ubuntu-8.04-x86.vdi under the ~/.VirtualBox/VDI directory&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run and customise new virtual machine&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You should now have a new Virtual Ubuntu machine at your disposal. Start it up by clicking the Start button.&lt;/li&gt;
&lt;li&gt;Log in with ubuntu/reverse as username password. Double check that this is correct by looking at the site you downloaded the image from&lt;/li&gt;
&lt;li&gt;Once logged in change the password through the System/Administration/Users and Groups menu&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &#39;Guest Host Additions&#39; from the Devices menu of the running window of you virtual machine. GHA allow you to copy and paste between the host and guest OS&#39;s, along with a raft of other improvements. Tip: If your mouse gets stuck in the virtual machine window then use the right control key to let it escape.&lt;/p&gt;

&lt;p&gt;If the GHA install does not work (due to a timeout) then you will need to install the Guest Host Additions manually, as follows&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;On your real Ubuntu machine (ie. the host) download the file that was specified as a URL in the popup that was displayed when you previously tried to install Guest Host Additions - if you forget the URL try to download the GHA again from the Devices menu and when the URL appears copy and paste it into FireFox running on your host machine. Note: The GHA are installed onto your host machine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once downloaded, move the file to /usr/share/virtualbox on your host machine and create the following symlink (as virtualbox won&#39;t recognise the file if it has the revision number in the filename)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ln -s /usr/share/virtualbox/VBoxGuestAdditions_2.0.4.iso /usr/share/virtualbox/VBoxGuestAdditions.iso
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once again try to install &#39;Guest Host Additions&#39; from the Devices menu of the running window of you virtual machine. This time it will pick up the local file you downloaded.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a shared folder - to swap files between your host and your VM&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On your host machine create a directory you will use for sharing&lt;/li&gt;
&lt;li&gt;On your running virtual machine create a directory you will use for sharing&lt;/li&gt;
&lt;li&gt;From the Devices menu of the running VirtualBox windows select Shared Folders and set the &#39;folder path&#39; to the folder you just created on your host. Give it a friendly name in the &#39;folder name&#39; field and elect to make it permanent. Then on your VM run
&lt;code&gt;mount -t vboxsf the_friendly_name /path/to/folder/on/virtual/machine&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Note: That vboxsf is the filesystem type that VirtualBox is using for shared folders&lt;/p&gt;

&lt;p&gt;Now you should be ready to go with your VM. Congratulations!&lt;/p&gt;

&lt;p&gt;As a final step you may want to take this vanilla Ubuntu machine update it so that it has the same packages as another machine, in the case where you are looking to replicate an environment. Use dselect and apt to do this as laid out in the following guide &lt;a href=&quot;http://kevin.vanzonneveld.net/techblog/article/restore_packages_using_dselectupgrade&quot;&gt;Restore Packages using dselect&lt;/a&gt; on Kevin von Zonneveld&#39;s blog.&lt;/p&gt;

&lt;p&gt;As a final step you may want to install any other software that is not covered by aptitude packages - such as programs for which no debian package exists or for things like Ruby on Rails gems. It shouldn&#39;t take you long to put these on your new virtual machine and &quot;hey presto!&quot; you&#39;re ready to rock!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Blackout Ireland - Not Condoning Piracy but Criticizing Coporate Internet Censorship</title>
   <link href="http://www.theirishpenguin.com/2009/03/09/blackout-ireland-not-condoning-piracy-but-criticizing-coporate-internet-censorship.html"/>
   <updated>2009-03-09T10:03:56+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/03/09/blackout-ireland-not-condoning-piracy-but-criticizing-coporate-internet-censorship</id>
   <content type="html">&lt;p&gt;One of the key points of the Blackout Ireland campaign is that letting individual companies control the Internet is not acceptable. (Link to external article no longer available).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Blackout Ireland Campaign Begins - No to Irish Internet Censorship</title>
   <link href="http://www.theirishpenguin.com/2009/03/05/blackout-ireland-campaign-begins-no-to-irish-internet-censorship.html"/>
   <updated>2009-03-05T11:01:09+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/03/05/blackout-ireland-campaign-begins-no-to-irish-internet-censorship</id>
   <content type="html">&lt;p&gt;The battle for control of the Internet has begun within Ireland. In the red corner, Eircom has sided with the Big Four record companies - Sony-BMG, Universal and Warner and EMI - who are seeking to control the Irish Internet using coporate censorship and civil law techniques. In the blue corner, the &lt;a href=&quot;http://www.blackoutireland.com&quot;&gt;Blackout Ireland&lt;/a&gt; campaign is looking to highlight the dangers of this censorship and has used social networking tools such as Twitter and Facebook to build support to protest this decision. A similar campaign was succesful in New Zealand, will it work again here?&lt;/p&gt;

&lt;p&gt;(Link that used to be here is no longer available).&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Phusion Passenger Configuration File Location - passenger.conf</title>
   <link href="http://www.theirishpenguin.com/2009/03/04/phusion-passenger-configuration-file-location-passengerconf.html"/>
   <updated>2009-03-04T08:45:10+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/03/04/phusion-passenger-configuration-file-location-passengerconf</id>
   <content type="html">&lt;p&gt;This was not easy for me to find! My beloved Ruby on Rails apps just sitting there untweaked! Google and even the Passenger website didn&#39;t specify where the config file may be found. And eventually it made a startling difference to my apps performance - possibly given that I&#39;m trying to host a few sites at once - so it would be nice if it was easier to learn about how to setup the config file when new to Passenger,&lt;/p&gt;

&lt;p&gt;Out of the box on a vanilla passenger install there is no passenger configuration file. However, there are a lots of &lt;a href=&quot;http://www.modrails.com/documentation/Users%20guide.html#_configuring_phusion_passenger&quot;&gt;configuration options&lt;/a&gt; and you can either dump these into&lt;/p&gt;

&lt;p&gt;a) /etc/apache2/apache2.conf file (messy) or
b) Create a new file called passenger.conf under the /etc/apache2/conf.d directory as files in thei directory automatically get loaded by apache
c) Create a passenger.load file in mods-available and then enable the module&lt;/p&gt;

&lt;p&gt;By the way, this setup is on Ubuntu, your mileage may vary depending on your distro. For an example passenger.conf file see this one (link no longer available), just be sure to get the &#39;LoadModule passenger_module&#39;, &#39;PassengerRoot&#39; and &#39;PassengerRuby&#39; settings correct. You may already have these specified correctly in your apache2.conf file if you already have passenger working; if so you can reuse these values.&lt;/p&gt;

&lt;p&gt;Apparently the recommended PassengerMaxPoolSize is 2 if you&#39;re on a 256 MB Virtual Private Server System that&#39;s running things like MySQL and keep the PassengerMaxInstancesPerApp smaller than this. If you&#39;re running a couple of rails sites then maybe set PassengerMaxInstancesPerApp to 1 if you want to have 1 instance always available for each site. A RailsSpawnMethod of &#39;smart&#39; can also lead to better performance depending on your setup.&lt;/p&gt;

&lt;p&gt;Certainly playing around with this config file helped me greatly improve my sites&#39; responsiveness for little effort and in particular it got the usage of the all important swap space down.&lt;/p&gt;

&lt;p&gt;One final tip for today is to install htop (is available through aptitude). This gives a very useful and pretty display of the &#39;top&#39; commands information and can make monitoring things like memory and swap at a glance much easier. So armed with this knowledge go forth and spawn! Well, till you run out of memory at least!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>5 Apache Troubleshooting Tips for Friday</title>
   <link href="http://www.theirishpenguin.com/2009/02/20/5-apache-troubleshooting-tips-for-friday.html"/>
   <updated>2009-02-20T08:34:46+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/02/20/5-apache-troubleshooting-tips-for-friday</id>
   <content type="html">&lt;p&gt;1) When you browse all your hosted sites and they&#39;re all down then there&#39;s a good chance Apache is too. Do a &#39;sudo /etc/init.d/apache2 restart&#39; and pay special attention to see if the &#39;fail&#39; message appears. Not sure if you get as good an indication that the server is &#39;ok&#39; if you just do the more graceful &#39;sudo /etc/init.d/apache2 restart&#39;&lt;/p&gt;

&lt;p&gt;2) It goes without saying but check your log files, especially the error.log file at /var/log/apache2&lt;/p&gt;

&lt;p&gt;3) Under /etc/apache2/sites-available/my_cool_website.com, ensure that any custom ErrorLog&#39;s or CustomLog&#39;s you have set actually exist on disk - or else apache may fail to restart&lt;/p&gt;

&lt;p&gt;4) Restart, restart, restart! When you enable sites or modules try not to forget to restart apache. It easy to change a setting such as the server url of your site in a sites-available file and forget the all import restart. You&#39;d think I did this before!&lt;/p&gt;

&lt;p&gt;5) When you migrate servers don&#39;t forget to set your application or site directories to the appropriate user. This is distro specific; on Red Hat and Cent OS this is &#39;apache&#39;, on Ubuntu this is &#39;www-data&#39;. Others could be different again.&lt;/p&gt;

&lt;p&gt;Bonus tip: Apache comes with mod_rewrite installed but not enabled. If you need it, be sure to enable it using a &#39;sudo a2enmod rewrite&#39; and ya, you guessed it, restart apache!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Site Outage - 19th Feb 2009</title>
   <link href="http://www.theirishpenguin.com/2009/02/19/site-outage.html"/>
   <updated>2009-02-19T21:48:46+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/02/19/site-outage</id>
   <content type="html">&lt;p&gt;Hi folks! The (hardworking) Irish Penguin has just been resolving some issues that led to a site outage last night due to a server migration that almost went smoothly! Apologies if it led to any inconvenience. All it takes is one little misplaced command!&lt;/p&gt;

&lt;p&gt;The outage has been resolved and will keep you posted if I notice any other issues.&lt;/p&gt;

&lt;p&gt;Happy hackin!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bug of the Day: nil.include error with create_time_zone_conversion_attribute</title>
   <link href="http://www.theirishpenguin.com/2009/01/22/bug-of-the-day-nilinclude-error-with-create_time_zone_conversion_attribute.html"/>
   <updated>2009-01-22T08:58:35+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/01/22/bug-of-the-day-nilinclude-error-with-create_time_zone_conversion_attribute</id>
   <content type="html">&lt;p&gt;This was an &#39;orrible bug. Tired and midway through writing up a Ruby on Rails tutorial on setting up emailing with AR Mailer and a little postfix configuration I wasn&#39;t exactly in the mood for a bizzarely cryptic issue to waste my time. Enter the mysterious create_time_zone_conversion_attribute? method in all it&#39;s glory. Basically you will get this error if you set ...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.cache_classes = false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... wherever it is set in your environment files (in my case config/development.rb) but the error goes away if you change it to ...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;config.cache_classes = true
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... bloody daft! Here is the bug on &lt;a href=&quot;http://rails.lighthouseapp.com/projects/8994/tickets/1339-arbase-should-not-be-nuking-its-children-just-because-it-lost-interest&quot;&gt;lighthouse&lt;/a&gt;. Arrgh!!!!&lt;/p&gt;

&lt;p&gt;Anyway here is the full stack trace which may help someone googling to pick up this page&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;NoMethodError in UsersController#create

You have a nil object when you didn&#39;t expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.include?

/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:142:in `create_time_zone_conversion_attribute?&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:75:in `define_attribute_methods&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:71:in `each&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:71:in `define_attribute_methods&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/attribute_methods.rb:350:in `respond_to?&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2587:in `attributes=&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2583:in `each&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2583:in `attributes=&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:2283:in `initialize&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:691:in `new&#39;
/usr/lib/ruby/gems/1.8/gems/activerecord-2.2.2/lib/active_record/base.rb:691:in `create&#39;
vendor/gems/ar_mailer-1.3.1/lib/action_mailer/ar_mailer.rb:92:in `perform_delivery_activerecord&#39;
vendor/gems/ar_mailer-1.3.1/lib/action_mailer/ar_mailer.rb:91:in `each&#39;
vendor/gems/ar_mailer-1.3.1/lib/action_mailer/ar_mailer.rb:91:in `perform_delivery_activerecord&#39;
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.2.2/lib/action_mailer/base.rb:526:in `__send__&#39;
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.2.2/lib/action_mailer/base.rb:526:in `deliver!&#39;
/usr/lib/ruby/gems/1.8/gems/actionmailer-2.2.2/lib/action_mailer/base.rb:392:in `method_missing&#39;
app/controllers/users_controller.rb:47:in `create&#39;
app/controllers/users_controller.rb:45:in `create&#39;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Happy hackin&#39;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Hackin on Gruff - A Brief Overview of Gem Development with Ruby</title>
   <link href="http://www.theirishpenguin.com/2009/01/16/hackin-on-gruff-a-brief-overview-of-gem-development-with-ruby.html"/>
   <updated>2009-01-16T08:25:08+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/01/16/hackin-on-gruff-a-brief-overview-of-gem-development-with-ruby</id>
   <content type="html">&lt;p&gt;Ah such is the life. Chillin&#39; in Havana (the bar, unfortunately not the city), hackin&#39; away on Gruff of all things. This is the my first attempt at development on a gem and it has to be said is surprisingly satisfying. Getting gems to build is a doddle. Here&#39;s a great &lt;a href=&quot;http://www.5dollarwhitebox.org/drupal/creating_a_rubygem_package&quot;&gt;link&lt;/a&gt; that shows how it&#39;s done in moments. Also a handy thing to know is how to suck the code out of your OS&#39;s gems directory and unpack them to under your app&#39;s vendor/gems directory - all courtesy of &lt;a href=&quot;http://errtheblog.com/posts/50-vendor-everything&quot;&gt;VendorEverything&lt;/a&gt;. You can create the vendor/gems directory manually if it doesn&#39;t already exist.&lt;/p&gt;

&lt;p&gt;When developing on the gem, I found that the best strategy was to clone down the gem source code from GitHub or Rubyforge to under the vendor/gems directory of my application rather than using the OS package unpacking technique of Vendor Everything (though they do it more for deployment than development - which is a great idea). That way I could easily stay on top of the latest source code using git. Actually, to make things even cleaner I downloaded the Gruff gem source code to a different directory totally unrelated to my sample project and then symlinked to it from under vendor/gems of my app. Clean as an (unused) whistle!&lt;/p&gt;

&lt;p&gt;And with Gem, Git and GitHub behind me life was trouble free. Now back to my search for great Cuban cigars...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Did Vista contribute to Dell's Limerick closure?</title>
   <link href="http://www.theirishpenguin.com/2009/01/12/did-vista-contribute-to-dells-limerick-closure.html"/>
   <updated>2009-01-12T08:09:00+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/01/12/did-vista-contribute-to-dells-limerick-closure</id>
   <content type="html">&lt;p&gt;Chris Mellor&#39;s recent &lt;a href=&quot;http://www.channelregister.co.uk/2009/01/11/dell_limerick_lessons/page2.html&quot;&gt;article&lt;/a&gt; on Channelregister.co.uk concerning Dell&#39;s Limerick manufacturing exodus covered various reasons for Dell&#39;s decision. Many of these break no new ground - it is simply the economics of the situation Dell finds itself in. But there were some subtleties that he unearthed that haven&#39;t been stated by many commentators. Firstly, had there been sufficient demand for the notebooks that Dell were producing, then it would have taken both the Irish and Polish plants to satisfy that demand. The downturn clearly put a dramatic dent in the purchasing of notebooks but even before that Dell had been overtaken by HP as the world&#39;s biggest supplier; and both Dell and HP were suffering at the hands of Apple. In June 2008, Jordan Golson &lt;a href=&quot;http://www.thestandard.com/news/2008/06/30/apple-notebook-sales-61-q1-07-trouncing-much-competition&quot;&gt;reported&lt;/a&gt; in The Industry Standard that at Apple notebook sales were up 61% since Q1 &#39;07. It seems that the Leopards and Tigers that populate Steve Jobs virtual zoo of operating systems were propelling Macbook sales to new heights while Vista was dragging Windows Notebook sales to down to Davy Jones locker.&lt;/p&gt;

&lt;p&gt;Meanwhile a completely new category of computers arrived - Netbooks - small low cost devices, pioneered by Asus and their initial range of Linux-based machines. These began to cut into the low end of the laptop sales and proved to be a disruptive force in the market. After years where people were paying extra money for small form factor laptops, Asus came along and made the cost of small portables proportional to their size, in a game changing move that would haunt the mainstream laptop manufacturers as time wore on. Things got so bad for Vista&#39;s adoption figures that Microsoft had to begin &lt;a href=&quot;http://www.pcworld.com/businesscenter/article/145145/dell_to_offer_windows_xp_beyond_june_30_cutoff.html&quot;&gt;counting Windows XP sales as Vista sales&lt;/a&gt; via their controversial &#39;downgrade licence&#39; program that allowed the likes of Dell to continue offering XP as an operating system on the machines they sold and allowed Microsoft to claim that another copy of Vista was now in circulation. But it wasn&#39;t the kind of thing that marketing dreams are made of. Even in August of 2008 &lt;a href=&quot;http://www.computerworld.com/action/article.do?command=viewArticleBasic&amp;amp;articleId=9112885&quot;&gt;research suggested&lt;/a&gt; that more than one in three new PCs were still being downgraded to from Vista to XP.&lt;/p&gt;

&lt;p&gt;So we set off into 2009 with more battles looming in the desktop, notebook, netbook and server markets. And who knows, maybe a completely new computing category will yet again be invented this year. Apple, Windows and Linux continue to vie for the position as the OS supreme. And with &lt;a href=&quot;http://www.usnews.com/blogs/daves-download/2009/01/02/firefox-gaining-internet-explorer-slipping.html&quot;&gt;Internet Explorer&#39;s market share falling to 68%&lt;/a&gt; from near dominance a few years ago,  gaps are still appearing in the browser market that will encourage Mozilla, Google and Apple to continue to innovate with Firefox, Chrome and Safari.&lt;/p&gt;

&lt;p&gt;Windows 7 is somewhere on the horizon. It will come too late for Dell and its Limerick workers - will it come too late for Microsoft?&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Uninstalling Gems from ~/.gem in your Home Directory</title>
   <link href="http://www.theirishpenguin.com/2009/01/10/uninstalling-gems-from-gem-in-your-home-directory.html"/>
   <updated>2009-01-10T12:40:02+00:00</updated>
   <id>http://www.theirishpenguin.com/2009/01/10/uninstalling-gems-from-gem-in-your-home-directory</id>
   <content type="html">&lt;p&gt;&lt;code&gt;&quot;It&#39;s installed Gem but not as we know it&quot;&lt;/code&gt;
-- Bones, if he was a Ruby Developer --&lt;/p&gt;

&lt;p&gt;Unfortunately, a careless keystroke can leave gems in lots of unusual places. About five minutes ago, that fate befell me as I ended up with gems under my home directory at ~/.gems. Not what I was expecting. To make matters worse when I tried to remove them I had no success - possibly there were PATH or GEM_PATH issues&lt;/p&gt;

&lt;p&gt;Fortunately, Google was to the rescue before you could say &#39;gem is no apt-get&#39;, with the command...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem uninstall ruby-debug-ide --install-dir $HOME/.gem/ruby/1.8
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... where in this case ruby-debug-ide is the misplaced gem in question.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href=&quot;http://rubyforge.org/tracker/index.php?func=detail&amp;amp;aid=22466&amp;amp;group_id=126&amp;amp;atid=575&quot;&gt;this thread &lt;/a&gt;for the solution.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Better to be Oriented than an Object</title>
   <link href="http://www.theirishpenguin.com/2008/12/10/better-to-be-oriented-than-an-object.html"/>
   <updated>2008-12-10T06:39:02+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/12/10/better-to-be-oriented-than-an-object</id>
   <content type="html">&lt;p&gt;Bit of a mixed bag of thoughts going into this post. Originally it was motivated by a couple of interesting points that I came across &lt;a href=&quot;http://www.chrylers.com/top-ten-of-programming-advice-to-not-follow&quot;&gt;a bunch of ideas on programming by Kristian Dupont&lt;/a&gt; but then it turned into one of those link hopping sessions where you end up click through a wealth of interesting material.&lt;/p&gt;

&lt;h3&gt;A Tip or Two for your Troubles&lt;/h3&gt;

&lt;p&gt;Kristian outlined a good test to determine if adding a comment to your code is justified saying that &quot;they should contain the word &#39;because&#39;. This way, you know that you are answering a &lt;em&gt;why&lt;/em&gt; rather than a &lt;em&gt;what&lt;/em&gt;.&quot; That&#39;s a great test I think. If your comment fails the test then you may well be more in need of a refactor than a comment.&lt;/p&gt;

&lt;p&gt;Secondly, when thinking about the classes you plan to use in your code, especially domain models, bear in mind that you&#39;re not actually trying to model the real world in a physical sense. For example, if you&#39;re writing software for a car dealership and one of your classes is going to be a car remember &quot;You&#39;re not implementing a car. You&#39;re probably implementing a record of a car which can carry a number of stock items from one city to another, with a certain mileage and speed.&quot; The key thing is the context of what you&#39;re trying to implement and focus on that - often the real world will map nicely to your domain model but don&#39;t force things where doesn&#39;t. To shoehorn irrelevant aspects of the physical world into your models doesn&#39;t make it &quot;more object oriented&quot; or more correct - quite the reverse. Generally, this in not a problem with the attributes for your models, rather it is a problem with relationships and in particular with inheritance. Should a subclass really be a subclass - just because it is in the real world doesn&#39;t necessarily mean that your software be designed on the foundation that it is. This brings on nicely onto the other article, &lt;a href=&quot;http://www.informit.com/guides/content.aspx?g=cplusplus&amp;amp;seqNum=84&quot;&gt;The Rise &amp;amp; Fall of Object Orientation&lt;/a&gt;, which ended up being another inspiration for this post.&lt;/p&gt;

&lt;h3&gt;What is Object Oriented these days anyway?&lt;/h3&gt;

&lt;p&gt;Danny Kalev argues that traditional OO is something that is less and less likely to be found in areas such as STL library of C++, as techniques such as inheritance give way to more template driven styles of programming. The problem he states &quot;is that a member function is useful only for a single class&quot; and goes on to highlight how this doesn&#39;t work well for things such as a library of containers.&lt;/p&gt;

&lt;p&gt;&quot;If each container class defines its own size() member function, you will end up writing numerous size() functions that basically do the same thing.&quot;&lt;/p&gt;

&lt;p&gt;Better to use a standalone function to solve the problem which can be used across the board by any class irrespective of inheritance hierarchies. It isn&#39;t just C++ that has looked to functional programming techniques to solve problems that traditional OO couldn&#39;t deliver on. Languages such as Ruby have effectively made blocks and closures one of the core and most used features of the language. All iteration is done through blocks and lamba functions can solve tricky problems in an elegant manner.&lt;/p&gt;

&lt;p&gt;It seems that traditional OO struggles most with collections but works well enough for single objects. &lt;a href=&quot;http://memeagora.blogspot.com/2008/10/library-oriented-programming.html&quot;&gt;Neal Ford&lt;/a&gt; thinks that Object Oriented Development is the wrong way to even frame the question of code reuse. Instead the focus should be on Library Oriented Development. “Ultimately, the class is just too fine grained to really achieve reuse, but libraries can.” On Java he states that while it “is a library oriented language, no good facilities exist within the language to manage libraries&quot; and notes it sorely lacks a fixed directory structure such as in Ruby on Rails, where plugin developers know the layout of the projects they will be interfacing with from the get go.&lt;/p&gt;

&lt;p&gt;Whether you prefer to consider your approach to software development an Object or Library Oriented approach it does seem that the modern developer will be drawing on a wide range of programming paradigms that go beyond traditional OO philosophy. In a hotly debated and opinionated field, it appears that the one true killer approach has not yet emerged to truly simplify and streamline development. At least it will continue to provide software developers, designers and architects with plenty to debate during their coffee breaks for years to come!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Installing Drupal on Ubuntu (Gutsy) in a few easy steps</title>
   <link href="http://www.theirishpenguin.com/2008/11/28/installing-drupal-on-ubuntu-gutsy-in-a-few-easy-steps.html"/>
   <updated>2008-11-28T03:54:51+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/11/28/installing-drupal-on-ubuntu-gutsy-in-a-few-easy-steps</id>
   <content type="html">&lt;p&gt;Drupal is a great solution if you&#39;re looking for a CMS system. In order to sneakily install LAMP with the minimum of fuss, I usually just install mod php and mod mysql (the apache related modules for php and mysql respectively) and that triggers pretty much everything else to be pulled automatically! So, from the command line...&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo aptitude install libapache2-mod-php5
sudo aptitude install php5-mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;... should give you Apache, MySQL and PHP in one fell swoop. Just to be sure that all is well run the following install commands&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo apt-get install mysql-server
sudo apt-get install apache2
sudo apt-get install php5
sudo apt-get install php5-mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then download and install Drupal (version 6.6 at time of writing) at http://drupal.org and follow their install guide.&lt;/p&gt;

&lt;p&gt;One final tip, if there&#39;s any problem with your apache installation&#39;s configuration, you can install phpMyAdmin in order to plough through these problems as it will supply its own configuration. For example, I got the database configuration error when I was trying to connect to my database for the first time using Drupal&lt;/p&gt;

&lt;p&gt;&quot;Your web server does not appear to support any common database types. Check with your hosting provider to see if they offer any databases that Drupal supports.&quot;&lt;/p&gt;

&lt;p&gt;Turns out my apache config was dodge as when I did a &lt;code&gt;sudo apache2ctl restart&lt;/code&gt; I got the following...&lt;/p&gt;

&lt;p&gt;&quot;apache2: Could not reliably determine the server&#39;s fully qualified domain name, using 127.0.1.1 for ServerName&quot;&lt;/p&gt;

&lt;p&gt;Installing phpMyAdmin and choosing apache2 when prompted during this process did the trick. Now go forth and Drupal!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>3 Cheers for OSS Barcamp Dublin!</title>
   <link href="http://www.theirishpenguin.com/2008/11/23/3-cheers-for-oss-barcamp-dublin.html"/>
   <updated>2008-11-23T01:52:29+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/11/23/3-cheers-for-oss-barcamp-dublin</id>
   <content type="html">&lt;p&gt;Another exciting event has just been announced for Dublin next year with an Open Source Software Barcamp planned for Dublin March 28th next year. And you could be one of the speakers! The idea behind a barcamp is to have a casual relaxed atmosphere where the attendees can help drive the schedule - like a conference done in the spirit of Digg. For more info check out &lt;a href=&quot;http://www.lczajkowski.com/2008/11/20/ossbarcamp-28th-march-2009&quot;&gt;Laura Czajkowski&#39;s blog post&lt;/a&gt; and if you want to keep up to date with further details you can track things on &lt;a href=&quot;http://twitter.com/ossbarcamp&quot;&gt;ossbarcamp on twitter&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>File downloads over the command line via CURL</title>
   <link href="http://www.theirishpenguin.com/2008/11/23/file-downloads-over-the-command-line-via-curl.html"/>
   <updated>2008-11-23T00:58:21+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/11/23/file-downloads-over-the-command-line-via-curl</id>
   <content type="html">&lt;p&gt;This could be a pretty obvious one to a lot of people but it&#39;s just so handy. This will download a file from example.com to your local directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl -O http://example.com/somefile.tar.gz
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Really handy when you&#39;re administering a remote server and need to pull down files.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Troubleshooting fcgi and the dreaded undefined method `require_gem' error</title>
   <link href="http://www.theirishpenguin.com/2008/10/09/troubleshooting-fcgi-and-the-dreaded-undefined-method-require_gem-error.html"/>
   <updated>2008-10-09T08:33:10+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/10/09/troubleshooting-fcgi-and-the-dreaded-undefined-method-require_gem-error</id>
   <content type="html">&lt;p&gt;It happens to the best of us. We&#39;ve coded our app go to deploy it and encounter some dispatch.fcgi issue. Today was the turn of&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;dispatch.fcgi error: undefined method `require_gem&#39; for main:Object (NoMethodError)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well way to troubleshoot and arrive at a solution is to actually run ./dispatch.fcgi. I didn&#39;t know you could do this! It&#39;s well handy! If you are on a remote server to which you don&#39;t have ssh access then you can probably still run it as a cron job. Something like cd /path/to/my/app/public &amp;amp;&amp;amp; ./dispatch.fcgi should do it. Remember that the dispatch.fcgi file is in the public directory of your application. The combination of running ./dispatch.fcgi and viewing the Rails log file revealed the useful error message above. Then a quick google search revealed that we need to change require_gem to simply gem (see &lt;a href=&quot;http://blog.nanorails.com/articles/2007/12/20/ruby-gem-1-0-is-out&quot;&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I had to change this in the dispatch.fcgi and then grepped the whole application directory for any instances of require_gem and changed them to gem too.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Recording Sound in Kubuntu 8.10 (running KDE 4.1)</title>
   <link href="http://www.theirishpenguin.com/2008/09/14/recording-sound-in-kubuntu-810-running-kde-41.html"/>
   <updated>2008-09-14T06:30:39+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/09/14/recording-sound-in-kubuntu-810-running-kde-41</id>
   <content type="html">&lt;p&gt;Exciting times ahoy! This weeks mystery was to get sound recording with the minimum of fuss. We&#39;re not sure what soundcard is running inside the Dell Inspiron 1520 which was our test laptop but it seems to report itself as an HDA Intel SigmaTel STAC9205 in the system settings. Anyway, the first thing to do was to apt install audacity which can then be used for testing the recording functionality. Not being sure if the laptops builtin in mic had been detected correctly, we jacked in an external microphone into the mic socket.&lt;/p&gt;

&lt;p&gt;This didn&#39;t produce any encouraging results initially when we tried recording in audacity so we opened up the KDE volume controls by clicking the speaker icon on the taskbar and electing to open the mixer. Unfortunately the GUI controls for the mixer doesn&#39;t have the full complement of volume controls so it was the good ol command line to the rescue - typing alsamixer in terminal brings up a nice range of controls. You can navigate between screens of controls with the tab key and jump from control to control using the left/right arrow keys. The trick was to navigate to the two controls marked &#39;Capture&#39; and bump up the volume (they also need to be activated by pressing the spacebar when you&#39;re on the control). Additionally, there were two controls marked &#39;Digital&#39;. One of these controlled the volume of the mic (via the up and down arrows) and the other switched between analog and digital mode (again via the up and down arrows). We found that the latter had to be set to &#39;Analog I&#39; for the best result.&lt;/p&gt;

&lt;p&gt;Then it was back to audacity to record a bit of chatter - and then lament how weird ones voice sounds when recorded! Now get mixing mon amis!&lt;/p&gt;

&lt;h3&gt;QUICK UPDATE (14 Sep 08)&lt;/h3&gt;

&lt;p&gt;One issue that occurred was that after recording a sample, it couldn&#39;t be played back(&quot;Error while opening sound device. Please check the output device settings and the project sample rate.&quot;). Additionally, a second track couldn&#39;t be recorded. The solution to these problems was to open the Preferences dialog and set both the Playback and Record devices to ALSA (default). Reference: http://audacityteam.org/forum/viewtopic.php?f=18&amp;amp;t=3377&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Getting Ruby Plasmoids up and running in KDE 4.1 (on Kubuntu)</title>
   <link href="http://www.theirishpenguin.com/2008/08/02/getting-ruby-plasmoids-up-and-running-in-kde-41-on-kubuntu.html"/>
   <updated>2008-08-02T23:24:12+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/08/02/getting-ruby-plasmoids-up-and-running-in-kde-41-on-kubuntu</id>
   <content type="html">&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; THIS ARTICLE IS NOT YET COMPLETE. IF YOU FOLLOW IT THEN YOU WILL GO A LONG WAY BUT THE PLASMOID IS NOT YET DISPLAYING. SEE THE &#39;Run your applet&#39; SECTION NEAR THE END OF THIS ARTICLE BEFORE PROCEEDING.&lt;/p&gt;

&lt;h3&gt;Introduction&lt;/h3&gt;

&lt;p&gt;KDE 4.1 is an absolutely terrific release of the KDE desktop, licking most of the issues presented in the original 4.0 release. Although it is still an early adopter release, 4.1 will be of interest to techie&#39;s who want to get their mitts on a sexy new graphical interface and is reasonably stable for daily usage. Not quite ready for Aunt Tillie yet though! One of the nicest features is the beauty and simplicity of Plasmoids and these super flexible little gadgets can now be written in Ruby - well almost!&lt;/p&gt;

&lt;p&gt;This guide assumes that you&#39;re using Kubuntu Hardy Heron. But you should be able to adjust the instructions for any distro.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The starting point for our tour is to have Ruby installed. Google this if you&#39;re unsure as to whether or not it&#39;s installed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need to install cmake via &#39;sudo aptitude install cmake&#39;. This is a cross-platform build system, similar to make.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It&#39;s likely that you will need to install the build UNIX build tools via &#39;aptitude search build-essential&#39;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Get coding!&lt;/h3&gt;

&lt;p&gt;And now you&#39;re be ready to go. The main tutorial out there on Ruby Plasmoids at time of writing is the &lt;a href=&quot;http://techbase.kde.org/Development/Tutorials/Plasma/RubyApplet&quot;&gt;Ruby Applet tutorial on KDE Techbase&lt;/a&gt;. This is a very good, well written guide on creating a simple Ruby applet in which a web browser is embeded inside the plasmoid. But the guide has a couple of gotcha&#39;s, especially for the newbie (myself included!), so we have listed solutions to these problems as we go. In summary, use our article as an supplement to KDE Techbase&#39;s.&lt;/p&gt;

&lt;p&gt;Ok, to start with a demo everyone wants a nicely packaged directory of files, so let&#39;s quickly put together the basic directory structure for our plasmoid - it&#39;s pretty simple!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Create a directory called &#39;ruby-web-applet&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Save the files &lt;a href=&quot;http://websvn.kde.org/trunk/KDE/kdebindings/ruby/plasma/examples/applets/webapplet/plasma-ruby-applet-web.desktop?view=markup&quot;&gt;plasma-ruby-applet-web.desktop&lt;/a&gt; and &lt;a href=&quot;http://websvn.kde.org/trunk/KDE/kdebindings/ruby/plasma/examples/applets/webapplet/web_applet.rb?view=markup&quot;&gt;web_applet.rb&lt;/a&gt; into this directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a file called CMakeLists.txt under your ruby-web-applet directory and paste the following code into it&lt;/p&gt;

&lt;p&gt;set(SERVICES_INSTALL_DIR /usr/lib/kde4/share/kde4/services/)
set(DATA_INSTALL_DIR /usr/lib/kde4/share/kde4/apps/)&lt;/p&gt;

&lt;p&gt;FIND_PACKAGE (Ruby REQUIRED)&lt;/p&gt;

&lt;p&gt;include_directories( ${RUBY_INCLUDE_PATH} )
install(FILES plasma-ruby-applet-web.desktop DESTINATION ${SERVICES_INSTALL_DIR})
install(FILES web_applet.rb DESTINATION ${DATA_INSTALL_DIR}/plasma_ruby_web_applet)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Go to KDE Techbase&lt;/h3&gt;

&lt;p&gt;Once you have the above directory in place, go and read the &lt;a href=&quot;http://techbase.kde.org/Development/Tutorials/Plasma/RubyApplet&quot;&gt;Ruby Applet tutorial on KDE Techbase&lt;/a&gt; article down to just before the &#39;Install and test the Applet&#39; paragraph. This will teach you what&#39;s going on in the code. At that point come back to me as I&#39;ll go into a little more detail on the final installation procedure!&lt;/p&gt;

&lt;h3&gt;You&#39;re back!&lt;/h3&gt;

&lt;p&gt;Great! Ok, so we have the files on disk, you have a good idea of what the code is doing, now let&#39;s install it and kick your plasmoid into action!&lt;/p&gt;

&lt;p&gt;Open the CMakeLists.txt file listed above in a text editor. Change the path listed for KDE4 services and data directories to the ones on your system. These are the lines to change.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;set(SERVICES_INSTALL_DIR /usr/lib/kde4/share/kde4/services/)
set(DATA_INSTALL_DIR /usr/lib/kde4/share/kde4/apps/)
&lt;/code&gt;&lt;/pre&gt;

&lt;blockquote&gt;&lt;p&gt;Do this by replacing &#39;/usr/lib/kde4/share/kde4/services/&#39; with the output of the command &#39;kde4-config --install services&#39; and replace &#39;/usr/lib/kde4/share/kde4/apps/&#39; with the output of the command &#39;kde4-config --install data&#39; command. If you are using Kubuntu then they should be the same as mine but otherwise you may need to change them.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Then make sure you are inside your ruby-web-applet directory and type&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;cmake .&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;to generate nice makefiles for you which the make command can then use. Don&#39;t forget the trailing dot! Now type &#39;make&#39; and &#39;sudo make install&#39;. This will install your plasmoid code into the KDE4 services directory (you can see where this is by running &#39;kde4-config --install services&#39;) and your plasmoid data into the KDE4 data directory (you can see where this is by running &#39;kde4-config --install data&#39;). Effectively, the installation just involves the two files - plasma-ruby-applet-web.desktop web_applet.rb. If it&#39;s worked then you&#39;ll get output like&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Install the project...
-- Install configuration: &quot;&quot;
-- Installing: /usr/lib/kde4/share/kde4/services/plasma-ruby-applet-web.desktop
-- Installing: /usr/lib/kde4/share/kde4/apps/plasma_ruby_web_applet/web_applet.rb&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The applet is now installed!&lt;/p&gt;

&lt;h3&gt;Run your applet (THIS DOES NOT WORK YET)&lt;/h3&gt;

&lt;p&gt;There are two ways to do this. In a developer kind of way you can run &#39;kbuildsycoca4&#39; from the command line followed by &#39;plasmoidviewer plasma-ruby-web-applet&#39;. Unfortunately this currently brings up the error&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;findServiceByDesktopPath:  not found
findServiceByDesktopPath:  not found
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;IF YOU HAVE A SOLUTION TO THIS THEN PLEASE COMMENT BELOW!!! &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a user, the cmake/make/make install procedure should have done all the necessary to install your plasmoid and you can activate it by going to the right of the task bar and clicking the Add Widgets icon. You should see your plasmoid listed but unfortunately this is not yet working - presumably for the same reason as the above. Oh well, I&#39;m sure a solution will soon be posted. Until then, happy hackin!&lt;/p&gt;

&lt;h3&gt;Final notes&lt;/h3&gt;

&lt;p&gt;Note that the KDE techbase article provides a version of this file but it didn&#39;t work for me because&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I knew nothing about cmake or cmake files and I didn&#39;t even cop that right clicking on the CMakeLists.txt file link in their article and saving it to disk would also save a load of HTML into the file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The line &#39;FIND_PACKAGE (RUBY REQUIRED)&#39; should really be &#39;FIND_PACKAGE (Ruby REQUIRED)&#39; as it&#39;s case sensitive and will otherwise give you the error&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;blockquote&gt;&lt;p&gt;CMake Error at CMakeLists.txt:6 (FIND_PACKAGE):
find_package could not find module FindRUBY.cmake or a configuration file for package RUBY.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Adjust CMAKE_MODULE_PATH to find FindRUBY.cmake or set RUBY_DIR to the directory containing a CMake configuration file for RUBY.  The file will have one of the following names:&lt;/p&gt;

&lt;p&gt;RUBYConfig.cmake
ruby-config.cmake&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The destination targets specified in the file didn&#39;t work for me. Perhaps some environment variables need to be set somewhere&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I didn&#39;t even know how to use cmake! Or that you needed to follow it up with &#39;make&#39;. Anyway we&#39;ll come cover this soon!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I didn&#39;t need to set any CMAKE_MODULE_PATH but if you are having troubles with this then it&#39;s at /usr/share/cmake-2.6/Modules/ on Kubuntu Hardy Heron. You may be able to set it in your script if your having difficulties as follows &#39;set(CMAKE_MODULE_PATH /usr/share/cmake-2.6/Modules/)&#39;. Again I haven&#39;t tried this my self!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>A Little Help on Importing Gmail Contacts using Ruby on Rails</title>
   <link href="http://www.theirishpenguin.com/2008/06/25/a-little-help-on-importing-gmail-contacts-using-ruby-on-rails.html"/>
   <updated>2008-06-25T08:46:33+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/06/25/a-little-help-on-importing-gmail-contacts-using-ruby-on-rails</id>
   <content type="html">&lt;p&gt;We came across a fabulous article on getting your RoR app to pull contacts from your Gmail account at Atlantic Domain Solutions called &quot;Import Gmail Contacts using Ruby on Rails&quot; (link http://rorblog.techcfl.com/2008/04/18/import-gmail-contacts-using-ruby-on-rails is no longer available). Kudos to Atlantic Domain Solutions! This is a really great article. The only slight issue is that it omitted a couple of details which may confuse the newbie - in particular, where does all the code in points 1, 2 and 3 go and how do the code snippets relate to each other.&lt;/p&gt;

&lt;p&gt;So here&#39;s a set of clarifications to the original article (a &#39;meta-guide&#39; if you will), as we didn&#39;t want to just rip off these nice folks source code. Thus read these clarifications in conjunction with the original Atlantic Domain Solutions guide.&lt;/p&gt;

&lt;p&gt;We&#39;ll assume that you know how to create a new rails app from scratch and create a controller. While you&#39;re following this you can use localhost as your server (eg. the default localhost:3000).&lt;/p&gt;

&lt;p&gt;Create yourself a controller called ImportedContacts&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class ImportedContactsController &amp;lt; ApplicationController

    def authenticate
        # Put the code from point 1 in the Atlantic Domain Solutions article here.

        # Note:
        # Set the next_param to the follow on controller action. For example,
        # next_param = url_for(:action =&amp;gt; &#39;authorise&#39;)
    end

    def authorise
        # Put the code from point 2 in the article here.

        # Note:
        # I changed some of the code as shown below...
        # if resp.code == &quot;200&quot;
        #     token = &#39;&#39;
        #     data.split.each do |str|
        #         if not (str =~ /Token=/).nil?
        #             token = str.gsub(/Token=/, &#39;&#39;)
        #         end
        #     end
        #     redirect_to(:action =&amp;gt; &#39;import&#39;, :token =&amp;gt; token)
        # else
        #     redirect_to (&#39;/&#39;)
        # end
    end

    def import
        # Put the code point 3 from the article here.

        # Some notes:
        # Put the line &#39;authsub_token = params[:token]&#39; at around line 4 of this method
        # (just after the two requires). It was accidentally omitted in the original article.
        # I also changed the local variable &#39;contacts&#39; to &#39;@contacts&#39; so that it is available to views
    end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To see the contacts after importing, I created a folder called &#39;imported_contacts&#39; under app/views and placed the file import.rhtml in it, containing the following code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;table&amp;gt;
  &amp;lt;%= @contacts.map { |c| &quot;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Name: #{c[&#39;name&#39;]}&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;Email: #{c[&#39;email&#39;]}&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&quot; } %&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok! You should be ready to rock! Ensure that you are not logged into gmail and visit http://localhost:3000/imported_contacts/authenticate&lt;/p&gt;

&lt;p&gt;You should be brought to a Google account login page. Login and you will be brought to the Google page for allowing third party access to the Google API. Click &#39;Grant&#39; and you should be brought to your app&#39;s import.rhtml page which should hopefully be displaying all your lovely contacts! Hurrah!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Just Diff the Internet</title>
   <link href="http://www.theirishpenguin.com/2008/06/22/just-diff-the-internet.html"/>
   <updated>2008-06-22T01:19:44+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/06/22/just-diff-the-internet</id>
   <content type="html">&lt;p&gt;Woke up this morning and found myself dead... Well, more to the point, my Internet connection dead. So being a Nymphobyte - someone feverously attracted to a reliable high bandwidth connection - there was little else to do than ponder the state of broadband in Ireland. Options are limited in the land currently home to the so called &#39;Pariahs&#39; of Europe. Just make our broadband better and we&#39;ll vote Yes! to Lisbon II and even Lisbon III &#39;The Search for Spock&#39;. Until then, you&#39;re better off sending your packets of data back and forth via carrier pigeon rather than trying to connect via the empty promises of the current providers.&lt;/p&gt;

&lt;p&gt;At least things aren&#39;t as bad as in Sweden, oft thought of as land of the liberal and freedom loving Swedes, where their elected leaders are trying to sell them down the river - forcing a copy of all networked communications to be forwarded on the government so that they can, presumably, check for things like terrorists trying to share the latest episode of Desperate Housewives over Bittorrent. Sweden is now being mentioned in the same breath as China and Saudi Arabia with respect to Internet Freedom. According to an Information Age article at http://www.information-age.com/home/information-age-today/443366/sweden-to-snoop-on-all-international-phone-and-email-traffic.thtml (link no longer available) even Google, not known to be adverse to collecting data on people, has been heavily critical of the crippling legislation. Blogger Oscar Swartz has a rallying mayday call on his &lt;a href=&quot;http://swartz.typepad.com/texplorer/2008/06/mayday-mayday-internet-wall-of-china---around-sweden.html&quot;&gt;site&lt;/a&gt;. Yes, that&#39;s right, even the Scandinavians have given up on civil rights - now we know the world is doomed! They&#39;re kind of like a civil liberties version of those budgies that used to warn of noxious fumes down the mine shafts in the old days - once they go tits up then you know the game is over.&lt;/p&gt;

&lt;p&gt;Nope, freedom is not on the menu anywhere this week. An &lt;a href=&quot;http://www.economist.com/world/britain/displaystory.cfm?story_id=11594471&quot;&gt;article&lt;/a&gt; in The Economist took stock of the scale of civil liberties that have been eroded under the Labour government and the relative apathy that this has been met with by the people. Gordon Brown, despite the having the popularity of Brian Cowan at a Eurocrat orgy, has even managed to push through legislation in Parliament to the effect that one can now be detained for 45 days at a go without charge. That&#39;s over 6 weeks! You could miss the whole European championships if you&#39;re unlucky enough! Which might suit you if you&#39;re a Portuguese or Croatian fan, after their sides painful exists. But 6 weeks! Perhaps Gordon just has a secret repressed side that he didn&#39;t know about - which is subconsciously upset that Ireland is now seen as more Eurosceptic than Britain. Forty five days isn&#39;t so bad though. After all, Tony Blair wanted to lock &#39;em up for 90 days without charge. Why not go the whole hog and just lock people up at birth? It saves all that awkward decision making and you wouldn&#39;t even need National Identity Cards anymore. Mind you, who needs ID cards when everyone one has already gotten their own copy of secret government dossiers that they picked up on the Tube on the way to work. Now there&#39;s a government I wouldn&#39;t trust mind my dog for the weekend, never mind my confidential information. And I don&#39;t even own a dog...&lt;/p&gt;

&lt;p&gt;It&#39;s been a tough week all right. It&#39;s hard to know how to stay on top of things. My great plan is to do away with RSS feeds and subscriptions and just diff the Internet each morning before going to work. If there was some interesting news found it could be managed using git and deltas emailed to friends to keep them informed. Sure, it would be a lot of data to contend with, but there would be some scant satisfaction knowing that it would make those draconian Swedish government servers that spy on their citizens work that little bit harder!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Quick Example of Serialisation via to_json in Ruby On Rails</title>
   <link href="http://www.theirishpenguin.com/2008/05/19/quick-example-of-serialisation-via-to_json-in-ruby-on-rails.html"/>
   <updated>2008-05-19T09:41:53+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/05/19/quick-example-of-serialisation-via-to_json-in-ruby-on-rails</id>
   <content type="html">&lt;p&gt;Ruby On Rails provides a few neat ways to serialise/deserialise objects to JSON. Out of the box you get the following approaches&lt;/p&gt;

&lt;p&gt;SERIALISING&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;json_string = a_house.to_json
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;DESERIALISING&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;an_object = ActiveSupport::JSON.decode(json_string) # gives you an object of type Object

a_house.from_json(json_string) # gives you an object of type House, note that a_house
                               # is an instance of House
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;These are pretty straightforward and do exactly what they say on the tin. Of the deserialising methods, note that using ActiveSupport directly gives you an object of type Object so you may prefer the stronger typing of the second technique which gives you an actual House object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; There&#39;s  been some great improvements to JSON support built right into Rails since Rails 2 has come around. For more info on this see &lt;a href=&quot;http://blog.codefront.net/2007/10/10/new-on-edge-rails-json-serialization-of-activerecord-objects-reaches-maturity/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When things just aren&#39;t enough...&lt;/strong&gt;
There are times when you will want to override the default serialisation that Rails provides - such as if you want to do some object &#39;flattening&#39; like including an attribute from an association on serialising. Now before proceeding check out the latest Rails 2 JSON support mentioned at the end of the previous section as this might make your life a lot easier. Otherwise, let&#39;s press on with an example of DIY JSON handling.&lt;/p&gt;

&lt;p&gt;Given a House object which has an associated Owner object, you might want to include the Owner&#39;s name attribute when serialising a House.&lt;/p&gt;

&lt;p&gt;House Class&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;has address and value attributes&lt;/li&gt;
&lt;li&gt;has an associated Owner object&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Owner Class&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;has a name attribute&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;We&#39;ll need to override the default to_json method on the House model.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class House::Base
  def to_json
    result = Hash.new

    self.class.content_columns.each do |column|
      if self.attributes.include?(column.name)
        result[column.name.to_sym] = self.send(column.name)
      end
    end

    if self.attributes.include?(column.name)
      result[:owner_name] = owner.name
    end

    result.to_json
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above was partially taken from the howtogeneratejson at http://wiki.rubyonrails.org/rails/pages/howtogeneratejson page on the Rails wiki (which is no longer available), which is has little bit more detail. Now all you need to do is call the a_house.to_json method and you get lots of lovely JSON which represents your model! One final note is that you may not want to override the default to_json method. If not, just call your method something else like to_custom_json. Also, there&#39;s&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Mercurial, Python and a Packet of Crisps</title>
   <link href="http://www.theirishpenguin.com/2008/04/07/mercurial-python-and-a-packet-of-crisps.html"/>
   <updated>2008-04-07T06:07:59+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/04/07/mercurial-python-and-a-packet-of-crisps</id>
   <content type="html">&lt;p&gt;Came across this exciting bit of news on the ol wireless just recently that &lt;a href=&quot;http://weblog.rubyonrails.com/2008/4/2/rails-is-moving-from-svn-to-git&quot;&gt;rails is moving from SVN to Git&lt;/a&gt;. Exciting times indeed as more and more developers are realising the merits of distributed source control to manage an ever expanding code base. This Irish Penguin&#39;s been in the fortunate position of working a lot with Mercurial, an alternative to Git, for the last few weeks and these types of tools are just a great way to work.&lt;/p&gt;

&lt;p&gt;One of the big pluses is that your code and your repository (the history of all edits you&#39;ve ever made to the code) is all in one directory which makes the process of source control really filesystem based. This is great when you&#39;re learning and just experimenting as you become more familiar with your new favourite toy. If you want to try something out, you just copy the directory somewhere and if it all goes to pot then it&#39;s just a quick copy command to restore it back to its original state!&lt;/p&gt;

&lt;p&gt;If you&#39;re a Ruby or Python dev one of the really nice things about Mercurial (also known as hg - after the chemical symbol) is that it&#39;s done in Python, which means that it&#39;s pretty easy to hack a bit of code together if you want to extend functionality. A whole Saturday was lost to the cause of hacking Mercurial in Dublin&#39;s Central Hotel last weekend - as your host recovered from a bout of Extreme Coughing (there are more germs going round here at the moment than sheep in New Zealand!) over a pint of orange and a packet of crisps. Good fun! It was kind of weird though. As soon as urs truly had booted up the laptop, a bunch of folks grabbed seats to the back of the room muttering about Ubuntu cds and wifi. Sounds like Linux is all over Dublin like a rash. A very nice rash of course!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Getting the Huawei E870 to work on Kubuntu (and Mobile Internet from O2) </title>
   <link href="http://www.theirishpenguin.com/2008/03/26/getting-the-huawei-e870-to-work-on-kubuntu-and-mobile-internet-from-o2.html"/>
   <updated>2008-03-26T10:48:46+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/03/26/getting-the-huawei-e870-to-work-on-kubuntu-and-mobile-internet-from-o2</id>
   <content type="html">&lt;p&gt;It&#39;s a shiny express card and it promises Internet free from cables, plugs and sockets but will it work on your pretty Kubuntu laptop? Let&#39;s hope so. This guide worked for me and hopefully it&#39;ll work for you too!&lt;/p&gt;

&lt;p&gt;Now before we start let me tell you my setup. I&#39;ve got this working on a Kubuntu based Dell Inspiron using O2 as my network provider. It did not work on a separate Dell Vostro running Ubuntu 7.10 (however I did get it working on a different Kubuntu 7.10 Dell Inspiron laptop). So I&#39;m not sure whether that was a Ubuntu or Vostro thing or just bad luck. Also, note that the below approach worked for me when setting up Huawei&#39;s E220 USB modem too.&lt;/p&gt;

&lt;p&gt;In any case, here&#39;s the 6 step plan to happiness
1.) Download the huaweiAktBbo-i386.out file
2.) Create the /etc/chatscripts/huawei-e220.chat file
3.) Create the /etc/ppp/peers/huawei-e220 file
4.) Create the /etc/wvdial-huawei.conf
5.) Edit the /etc/resolv.conf
6.) Create and tailor the /home/username/bin/connectme script (and chmod it!)
7.) Tip of the day - lose the Edge!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.) Download the huaweiAktBbo-i386.out&lt;/strong&gt;
This can be done by visiting &lt;a href=&quot;http://www.kanoistika.sk/bobovsky/archiv/umts/&quot;&gt;http://www.kanoistika.sk/bobovsky/archiv/umts/&lt;/a&gt; and downloading the file huaweiAktBbo-i386. If you really want you can also build it from the C source provided (in order to build it you will need to have a C compiler and some basic tools on your system). NB: Copy the huaweiAktBbo-i386.out file to your /home/username/bin directory after downloading. If you don&#39;t have a bin folder under your home directory then create one (&#39;mkdir /home/username/bin&#39;). Also ensure that it is in your $PATH environment variable. Try echo $PATH and if you don&#39;t see it listed add the following line to your /home/username/.bashrc file&lt;/p&gt;

&lt;p&gt;export PATH=$PATH:/home/username/bin&lt;/p&gt;

&lt;p&gt;To get this change immediately picked up by your shell run the command &#39;source ~/.bashrc&#39;. This something I didn&#39;t learn for years!!! D&#39;oh!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.) Create the following /etc/chatscripts/huawei-e220.chat file&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;TIMEOUT 3
ABORT BUSY
ABORT &#39;NO CARRIER&#39;
ABORT VOICE
ABORT &#39;NO DIALTONE&#39;
ABORT &#39;NO DIAL TONE&#39;
ABORT &#39;NO ANSWER&#39;
ABORT DELAYED
&quot;&quot; ATZ
OK ATQ0V1E1S0=0&amp;amp;C1&amp;amp;D2
OK ATDT*99#
CONNECT &quot;&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;3.) Create the /etc/ppp/peers/huawei-e220 file&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/dev/ttyUSB0
460800
noipdefault
defaultroute
persist
noauth
nodetach
usepeerdns
connect &quot;/usr/sbin/chat -vf /etc/chatscripts/huawei-e220.chat&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;4.) Create the /etc/wvdial-huawei.conf&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;[Dialer Defaults]
Modem = /dev/ttyUSB0
#Baud = 3600000
Baud = 7200000
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &amp;amp;C1 &amp;amp;D2
Init3 =
Area Code =
Phone = *99#
Username = ppp
Password = ppp
Ask Password = 0
Dial Command = ATDT
Stupid Mode = 1
Compuserve = 0
Force Address =
Idle Seconds = 0
DialMessage1 =
DialMessage2 =
ISDN = 0
Auto DNS = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;5.) Edit the /etc/resolv.conf file&lt;/strong&gt;
Add the following entries at the top of this file (they are O2&#39;s nameservers)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;nameserver 62.40.32.33
nameserver 62.40.32.34
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;6.) Create the and tailor the /home/username/bin/connectme script as follows (and chmod it!)&lt;/strong&gt;
Note: See step 1 for more instructions if you don&#39;t have a bin folder in your home directory&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
sudo /home/username/bin/huaweiAktBbo-i386.out # CHANGE THIS TO YOUR &#39;USERNAME&#39;
sleep 3 # wait for the USB host to settle down...
sudo wvdial --config /etc/wvdial-huawei.conf
#/usr/sbin/pppd call provider
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then just do a &#39;chmod u+x /home/username/bin/connectme&#39; from the command line (to allow you to run &#39;connectme&#39; from the command line directly) and hopefully you should be ready to rock! The next step is to insert your E870 into the express slot. You might start to see Linux picking up the the devices and popping dialogs asking you if you want to mount the device (you should select &#39;Cancel&#39; for them all).Wait about 5 seconds for it to steady itself and then run &#39;connectme&#39; from the command line. You should see&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Hladam HUAWEI E220 a prepnem na modem - bbo 06
4 set feature request returned 0
Prepnute-OK, Mas ttyUSB0 ttyUSB1 (cez usbserial vendor=0x12d1 product=0x1003)
pozri /proc/bus/usb/devices
WvDial&amp;lt;*1&amp;gt;: WvDial: Internet dialer version 1.56
WvModem&amp;lt;*1&amp;gt;: Cannot get information for serial port.
WvDial&amp;lt;*1&amp;gt;: Initializing modem.
WvDial&amp;lt;*1&amp;gt;: Sending: ATZ
WvDial Modem&amp;lt;*1&amp;gt;: ATZ
WvDial Modem&amp;lt;*1&amp;gt;: OK
WvDial&amp;lt;*1&amp;gt;: Sending: ATQ0 V1 E1 S0=0 &amp;amp;C1 &amp;amp;D2
WvDial Modem&amp;lt;*1&amp;gt;: ATQ0 V1 E1 S0=0 &amp;amp;C1 &amp;amp;D2
WvDial Modem&amp;lt;*1&amp;gt;: OK
WvDial&amp;lt;*1&amp;gt;: Modem initialized.
WvDial&amp;lt;*1&amp;gt;: Sending: ATDT*99#
WvDial&amp;lt;*1&amp;gt;: Waiting for carrier.
WvDial Modem&amp;lt;*1&amp;gt;: ATDT*99#
WvDial Modem&amp;lt;*1&amp;gt;: CONNECT
WvDial&amp;lt;*1&amp;gt;: Carrier detected.  Starting PPP immediately.
WvDial: Starting pppd at Tue Mar 25 21:22:08 2008
WvDial: Pid of pppd: 11465
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: Using interface ppp0
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: local  IP address 62.40.58.185
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: remote IP address 10.64.64.64
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: primary   DNS address 62.40.32.33
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: secondary DNS address 62.40.32.34
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you want to disconnect from the web simply press Ctrl-C twice to kill it off. The first time you press it, it talks of wanting to exit gracefully - but better to press it a second time and exit effectively ;-)&lt;/p&gt;

&lt;p&gt;You&#39;ll see the following&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Caught signal 2:  Attempting to exit gracefully...
WvDial&amp;lt;*1&amp;gt;: Terminating on signal 15
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: Connect time 8.6 minutes.
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: pppd: H���h�[06][08]`�[06][08]
WvDial&amp;lt;*1&amp;gt;: Disconnecting at Tue Mar 25 21:30:45 2008
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;7.) Tip of the day - lose the Edge!&lt;/strong&gt;
Disclaimer: this is just my opinion as to the performance of the Edge network so O2 lawyers keep your knickers on (however Apple iPhone suckers, enjoy the sheer speed of the Edge network, getting dripfeed broadband at 1500 Euros a year!). In stark contrast though, my experience with the HSDPA network have been good. Yes, as you may have already guessed, the Edge network was not really delivering for me. But a friend of mine showed me how to change your O2 broadband Express card (or USB modem) settings so that it not even bother connecting if it can&#39;t get a proper UTMS or HSDPA signal. For this you need a Windows friend. Install the express card on their machine and from the O2 broadband application and select &quot;Tools-&gt;Choose Network Type-&gt;3G Only&quot;. This setting directly updates the card so even when you switch back to a using it on a Linux box it will go with 3G only. If I don&#39;t do this I&#39;ve found that it will flip flop between Edge (GPRS) and 3G networks and drive you mad in the process. I found it pretty much impossible to even check my email on Edge.&lt;/p&gt;

&lt;p&gt;Special thanks to Andy and Paul on the &lt;a href=&quot;http://www.linux.ie&quot;&gt;ILUG&lt;/a&gt; mailing lists for their help and also to O2, Vodaphone, Three et al. for providing Mobile Internet via hardware that can actually be used on an Open Source platform such as Linux; as we hopefully move from an era of proprietary lock-in and DRM-based crippleware to software that delivers genuine value for businesses and users.  Vodafone have gone as far as having their own Open Source website to help along development at &lt;a href=&quot;http://www.vodafonebetavine.net/web/guest/projects/open_source&quot;&gt;Betavine.&lt;/a&gt; Enjoy!&lt;/p&gt;

&lt;p&gt;The revolution will not be televised! It will be streamed over TCP/IP...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Simple 'Through Associations' in Ruby on Rails</title>
   <link href="http://www.theirishpenguin.com/2008/01/14/simple-through-associations-in-ruby-on-rails.html"/>
   <updated>2008-01-14T14:12:21+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/01/14/simple-through-associations-in-ruby-on-rails</id>
   <content type="html">&lt;p&gt;This little article shows one way to model many-to-many relationships using a join table.&lt;/p&gt;

&lt;p&gt;Obviously, The Penguin isn&#39;t the first so &lt;a href=&quot;http://wiki.rubyonrails.org/rails/pages/Beginner+Howto+on+has_many+%3Athrough&quot;&gt;here&lt;/a&gt; is an alternative good practical example which might give your good self an different perspective. Also &lt;a href=&quot;http://wiki.rubyonrails.org/rails/pages/ThroughAssociations&quot;&gt;this documentation&lt;/a&gt; has some more detailed information but doesn&#39;t have a simple self contained example like below (and neglects to mention belongs_to in its primary example - at time of writing this).&lt;/p&gt;

&lt;p&gt;Here goes. The following statements define our basic requirements.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An order has many items&lt;/li&gt;
&lt;li&gt;An item has many orders&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We shall model this through a join table called order_items&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;orders     order_items    items
-----      ----------     ----
 id         order_id        id
            item_id
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Before we continue, please note that a massive massive thing to remember is that Order needs to have a has_many to the join table model AS WELL as a has_many (through the join table model) to Item. Also the join table model has a belongs_to for each model.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  class Order &amp;lt; ActiveRecord::Base
        has_many :order_lines #Don&#39;t forget this line!
        has_many :items, :through =&amp;gt; :order_lines
  end

  class Item &amp;lt; ActiveRecord::Base
        has_many :order_lines  #Don&#39;t forget this line!
        has_many :orders, :through =&amp;gt; :order_lines
  end

  class OrderLine &amp;lt; ActiveRecord::Base
        belongs_to :order
        belongs_to :item
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok so that&#39;s it folks! The Penguin has to admit that the above code hasn&#39;t been run in a RoR interpreter so if has typo&#39;s or smelly code please comment below.&lt;/p&gt;

&lt;p&gt;One last thing is that if you&#39;re going to try and present a RoR solution in an enterprise situation it is quite likely that the powers that be will want to see foreign key relationships in your database tables (note, this applies to all db relationships; not just man-to-many). These will give referential integrity to your associations. One very very handy and straightforward way to do this is using Red Hill&#39;s foreign_key_migrations plugin. This really is great (it does pretty much all the hard work for you!) so it&#39;s worth a serious look.&lt;/p&gt;

&lt;p&gt;One gotcha with using foreign keys in Rails, is that the order in which test fixtures load becomes important. See Per Olesen&#39;s &lt;a href=&quot;http://techpolesen.blogspot.com/2007/04/rails-fixture-tips.html&quot;&gt;post&lt;/a&gt; for tips on countering this. Other than that happy hacking and may the &lt;a href=&quot;http://en.wikipedia.org/wiki/May_the_road_rise_to_meet_you&quot;&gt;Rails Rise to Meet You&lt;/a&gt;!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>EU Commission unDRMines European Multimedia Sector</title>
   <link href="http://www.theirishpenguin.com/2008/01/05/eu-commission-undrmines-european-multimedia-sector.html"/>
   <updated>2008-01-05T22:48:10+00:00</updated>
   <id>http://www.theirishpenguin.com/2008/01/05/eu-commission-undrmines-european-multimedia-sector</id>
   <content type="html">&lt;p&gt;The ever confusing term &#39;Intellectual Property&#39; gets another run out today as the EU attempts to shoot itself in the foot, yet again on crucial IT issues. This time the European Union wants to embark on a plan to encumber its multimedia sector in a cocoon of red tape through the introduction of DRM. And goes to the absurd length of stating that it is doing so in the interests of consumers. What the ...???&lt;/p&gt;

&lt;p&gt;The Irish Penguin is a die-hard market fanatic. The reason is not just because it&#39;s the most efficient way to run an economy but rather that it is the best for the consumer (Note: The Penguin doesn&#39;t think that its the best way to run some things like health care but that&#39;s another story altogether). The bottom line is the customer truly is always right. Remember this for later. Which is way todays announcement is not just bad news for budding business entrepreneurs within Europe&#39;s software economy but also a smack in the chops for European consumers. One of the frantic undertones of the EU is often one of desperation - an attempt to try and emulate America - in order to somehow shed the image of a union which is hamstrung fragmented markets and business unfriendly polices. Unfortunately, it sometimes goes about it the wrong way. Instead of the Japanese tradition of copying a process and improving it, the EU cumbersomely ambles towards the wrong target and periodically releases sound bites which it thinks will make it sound economically competent. Today was a comical case in point. Here is an excerpt from its &lt;a href=&quot;http://europa.eu/rapid/pressReleasesAction.do?reference=IP/08/5&amp;amp;format=HTML&amp;amp;aged=0&amp;amp;language=EN&amp;amp;guiLanguage=nl&quot;&gt;press release&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&quot;The European Commission has decided today to give a new boost to Europe&#39;s online content sector. EU citizens should be able to enjoy easier and faster access to a rich variety of music, TV programmes, films or games via the Internet, mobile phones or other devices.&quot;&lt;/p&gt;

&lt;p&gt;Let&#39;s read that first line again. The European Commission has decided what? This opening sentence sounds like the EU is trying to convince itself that this is a good idea. In reality, the European Commission has NOT decided today to give a boost to Europe&#39;s online content sector. This is because included in its announcement the EU has decided that DRM (a completely misnamed and dangerous Digital Rights Management technology) should be forced on the European customer at every turn - in order to stifle the promising multimedia sector. It is highly useful to see that DRM has roundly been rejected by media consumers right across the globe. All of the major record company&#39;s used to have DRM woven into their CDs and products at the turn of the year. DRM prevented users playing music on more than one music playback device. For example, it locked customers who had purchased an album online into playing it back on an iPod only; the user could not choose to play that same album on their home computer. And it also locked users who had bought CDs from playing them on their iPod. As sales plumetted and customers rebelled, EMI was the first to reject this notion and give back consumers the right to play their music on any device. That the left the remaining labels with an inferior product and they all quickly followed suit. Sony BMG, Warner Music Group and Vivendi&#39;s Universal Music Group all now sell &#39;clean&#39; products in United States which are not contaminated with DRM. This shows the power of the Free Market to correct problems like DRM. So if it makes sense for these major players to roundly reject DRM then how on earth can it make sense for the EU to move towards it? The answer - it doesn&#39;t!&lt;/p&gt;

&lt;p&gt;Ironically, the second sentence is also meaningless rhetoric. The EU Commission&#39;s announcement today does NOT make it easier or faster to access rich multimedia. The only thing that can do that is solid broadband policies and Net Neutrality. Net Neutrality is crucial. It guarantees that the all services provided over the Internet are treated equal. This allows the separation of the bandwidth providers (such as European telecom companies and ISPs) from the content providers (movie distributors, news channels, websites, email services) in order to prevent the bundling of content with services. The big word there is &#39;bundling&#39;. If your telecom company is providing your movies via cable TV and an online company seeks to compete with them by providing movie downloads it is unwise to let the telecom company to control the bandwidth available to the online company - clearly it would be in the Telecom&#39;s interest to restrict bandwidth for movies thus ruining the challengers business model and locks consumers into the telecom company&#39;s cable movie offering. Thankfully, thus far Net Neutrality is not under serious threat in Europe. However, DRM certainly does nothing to make your Internet connection any faster. All is does is make digital media that you purchase over the Internet into an inferior product than it otherwise could have been.&lt;/p&gt;

&lt;p&gt;One of the driving forces of the damaging policies is Viviane Reding, EU Commissioner for the Information Society and Media. She says &quot;We have to make a choice in Europe: Do we want to have a strong music, film and games industry?&quot; However the report issued goes on to call for the &quot;establish(ing of) a framework for DRM transparency concerning, amongst others, the interoperability of different DRMs, and ensuring that consumers are properly informed of any usage restrictions placed on downloaded content...&quot; The question remains, why create &#39;usage restrictions&#39;? Why not let the user just play their music how they want. It&#39;s like selling someone a car and then letting them drive down only one street. It defies logic. Not to mention the that fact that every digital item you purchase will be more expensive as the cost of DRM will be included in each product. A more expensive and less functional product is not what the consumer wants. And the consumer is always right! They have rebelled against DRM before and they will rebel again. And the EU Commission wants to drag down European software houses and content providers with this sinking ship. With a ratification on the Lisbon treaty coming up in Ireland with guaranteed influx of the &quot;No&quot; vote protesters from neighbouring countries, we can only hope that Europe starts to give its citizens reasons to vote for Europe than against it.&lt;/p&gt;

&lt;p&gt;For a more technical analysis of the announcement, as well as an open letter which you can sign that argues against the EU&#39;s position, check out this &lt;a href=&quot;http://www.defectivebydesign.org/Do_Not_Sanction_DRM&quot;&gt;link&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Uninitialized Constant GemRunner Error When Using Ruby Gem</title>
   <link href="http://www.theirishpenguin.com/2007/12/09/uninitialized-constant-gemrunner-error-when-using-ruby-gem.html"/>
   <updated>2007-12-09T10:13:16+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/12/09/uninitialized-constant-gemrunner-error-when-using-ruby-gem</id>
   <content type="html">&lt;p&gt;Here&#39;s the problem...&lt;/p&gt;

&lt;p&gt;me@host:~$ sudo gem update
/usr/bin/gem:23: uninitialized constant Gem::GemRunner (NameError)&lt;/p&gt;

&lt;p&gt;... which had us on the ropes more than on the rails for a while. Unusually googl&#39;ing on this error provided no solutions.&lt;/p&gt;

&lt;p&gt;What led to the situation was that we used the source install of rubygems on Ubuntu Gutsy (7.10) instead of using the rubygems in Ubuntu&#39;s repository but then changed our mind and apt-getted the Ubuntu repository version. Surprise! Surprise! These 2 versions were conflicting a bit; leading to the above error. The workaround is pretty simple, just go to your /usr/local/lib section and delete the site_ruby directory (as this is the remnant of the rubygems source install and thus cause of the problem). This removes all the gems (that were downloaded by the original rubygems which we no longer want) off our system. Perhaps you want to simply move this directory first in case something goes wrong and you need to revert (eg. sudo mv /usr/local/lib/site_ruby /usr_local/lib/site_ruby_old).&lt;/p&gt;

&lt;p&gt;Note: In case your not aware, /usr/local/* is the set of directories under which programs that you compile yourself get installed to by default. Generally the directories will start out pretty empty on a freshly installed Linux distro and then as you (if ever!) compile and install programs from source (eg. using ./configure &amp;amp;&amp;amp; make &amp;amp;&amp;amp; make install) then they end up under this directory. Also not that programs installed using apt-get (or via rpms on non-Debian systems) don&#39;t get put here - they usually end up under the /usr/ directory itself (this varies a bit from distro to distro but what we&#39;ve just outlined holds true for Ubuntu anyway).&lt;/p&gt;

&lt;p&gt;Now, once your finished you should find that gem works. Do a &#39;gem list&#39; and see if the above error is gone. If this doesn&#39;t work you may need to &#39;sudo apt-get install rubygems&#39;. Next up, we need to rebuild that gem directory that we deleted (site_ruby) with the apt-gotten rubygems (if apt-gotten is a real word!). To do this run&lt;/p&gt;

&lt;p&gt;&#39;sudo gem update&#39;
&#39;sudo gem update --system&#39;&lt;/p&gt;

&lt;p&gt;You will notice that the result of these commands means that /usr/local/lib/site_ruby is back and populated. This is where ruby likes to put it&#39;s gem extensions. Finally reinstall rails with&lt;/p&gt;

&lt;p&gt;&#39;sudo gem install rails&#39;&lt;/p&gt;

&lt;p&gt;Hope this solution works for you! We&#39;re still getting to grips with this rails stuff so if you find any glaring errors in this post please comment below to let us know.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>New KDE Theme - Castle at Night</title>
   <link href="http://www.theirishpenguin.com/2007/12/06/new-kde-theme-castle-at-night.html"/>
   <updated>2007-12-06T09:29:26+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/12/06/new-kde-theme-castle-at-night</id>
   <content type="html">&lt;p&gt;After initially being a little disappointed with Kubuntu&#39;s default theme, The Irish Penguin new he&#39;d have to roll his own.&lt;/p&gt;

&lt;p&gt;Well, finally it&#39;s been tweaked to penguin perfection and, amidst much wing flapping, uploaded as a KDE theme for everyone to enjoy. However, before it&#39;s unleashed upon you, please be aware of a little gotcha. The KDE Theme Manager is the tool you&#39;ll need to install/create your own themes. However it&#39;s not to be found in &#39;System Settings&#39; on the K-menu. Rather you must go to the command line (unless I am missing the menu icon with my dodgy eyes!) and type &#39;kcontrol&#39;. From here you navigate to &#39;Appearances &amp;amp; Themes&#39; and then &#39;Theme Manager&#39;. Ok, now armed with this knowledge here&#39;s what to do.&lt;/p&gt;

&lt;p&gt;Save the Castle at Night (link no longer available) zipped theme file to your &#39;/home/yourusername/.kde/share/apps/kthememanager/themes/&#39; directory. Then unzip it and, via the KDE Theme Manager, install this file and, hey presto(!), you&#39;re looking good.&lt;/p&gt;

&lt;p&gt;Note: If you are having trouble with installing this theme you can download, unzip and install some additional files (link no longer available) into your  /home/yourusername/.kde/share/apps/kthememanager/themes/&#39; folder.&lt;/p&gt;

&lt;p&gt;To fully enjoy the theme you should right-click on the quicklauncher at left of the taskbar and configure it to have a fine big icon size - 28 looked good on the Inspiron (I think big icons always look nice in KDE’s taskbar).&lt;/p&gt;

&lt;p&gt;Note: It&#39;s been created on a Dell Inspiron 1520 laptop (running Kubuntu 7.10 &#39;Gutsy&#39;) so perhaps the colours might look at little different depending on your machine. Now hopefully one day we&#39;ll all have gamma correction that works. Until then, enjoy!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Shock Horror! 18000 Pints of the Finest Irish Guiness Stolen (+ Some Bad Beer)</title>
   <link href="http://www.theirishpenguin.com/2007/12/01/shock-horror-40000-pints-of-the-finest-irish-guiness-stolen.html"/>
   <updated>2007-12-01T00:12:39+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/12/01/shock-horror-40000-pints-of-the-finest-irish-guiness-stolen</id>
   <content type="html">&lt;p&gt;It&#39;s coming up to Christmas and it&#39;s the time to be merry - especially if you are a certain thief, who has made off with 450 kegs of festive beer, including 180 kegs of the black stuff, from Ireland&#39;s premier brewery! (source: Times Online at http://www.timesonline.co.uk/tol/news/world/europe/article2971318.ece link no longer available
) St James’s Gate, home of the famous pint that is Guiness, was the scene of the crime as the assailant drove off (staggered???) in a trailer drawing vehicle; the most exciting heist since &lt;a href=&quot;http://en.wikipedia.org/wiki/Cattle_raid_of_cooley&quot;&gt;The Cattle Raid of Cooley&lt;/a&gt;. Interesting it has come admist a police blitz in the nation&#39;s capital - 160 police on the beat in the Xmas run-up. You&#39;d think someone would have noticed the equivalent of half a mega-pint.&lt;/p&gt;

&lt;p&gt;(Note: link to pic removed)&lt;/p&gt;

&lt;p&gt;Only one person is believed to have been involved in the incident; who&#39;s now shot to fame with the infamous title &quot;The Beer Hunter&quot;. Their whereabouts is currently unknown as a &#39;thirsty-man hunt&#39; sweeps the nation.  One thing is clear however, the sought-after thief does not have much respect for his/her taste buds - making off with an additional 180 kegs of Budweiser (which in Ireland tastes like a cross between a dog&#39;s urine, and well... another dog&#39;s urine - mostly drank by people who hate the taste of beer, footnote 1) and 90 kegs of Carlsberg. All in all, the liquid loot was worth in the region of 65000 euro. Quote of the day goes to Grainne Mackin, spokesperson for Guinness&#39; owner Diageo Ireland, who said &quot;What could they possibly want with all that beer?&quot; Hmm... Have a very merry Christmas perhaps?&lt;/p&gt;

&lt;p&gt;Footnote 1: ... in your correspondent&#39;s humble opinion&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>K-k-kubuntu 7.10 on a Dell Inspiron 1520</title>
   <link href="http://www.theirishpenguin.com/2007/11/22/k-k-kubuntu-710-on-a-dell-inspiron-1520.html"/>
   <updated>2007-11-22T20:17:36+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/11/22/k-k-kubuntu-710-on-a-dell-inspiron-1520</id>
   <content type="html">&lt;p&gt;Ahhh... Another day, another distro. The harddrive partitions around here are a bit like the Wizard of Oz; every day a new one joins the merry troupe. Todays turn was the KDE spin on Ubuntu Gutsy. So armed with the standard Kubuntu CD, which serves as a live distro and an install CD in one, we set on the path to enlightment (or should that be KDE - always good to end the week on a bad pun).&lt;/p&gt;

&lt;p&gt;Generally, it seems to be recommended practice these days to install Ubunutu or its derivates off the &#39;alternate&#39; CD when trying to set up an Inspiron to avoid things like incompatible versions of ALSA or wireless drivers working their way into the install. But the Penguin didn&#39;t really feel like giving the whole GUI experience a miss. And so the live CD was fired up before you could say &#39;Holy wireless drivers, Batman!&#39;. A nice desktop link provided a pretty path to installation and within an hour Kubuntu was installed and ready to go.&lt;/p&gt;

&lt;p&gt;First thing that was apparent was that the default Kubuntu appearance is quite bland. Especially when compared with something like OpenSuse&#39;s nice crisp out-of-the-box KDE look (however nothing will ever get installed waiting around for YAST!). But the good news is that Kubuntu&#39;s eye-candy vacuum can be fixed with a bit of tweaking. That wasn&#39;t the initial major concern though. The lack of sound and wireless was!&lt;/p&gt;

&lt;p&gt;The fix for the sound was easy, running &#39;sudo apt-get install linux-backports-modules-generic&#39; from the command line delivered sound after a reboot. The wireless was a lot more fiddly to get working - the strange thing is that NetworkManager was picking up all the secured networks and tantilisingly displaying them in its wireless list. But no way in the world was it going to connect to any of them. (BTW, the card is a Intel Pro Wireless 3945). However, the laptop in question is also running Ubuntu Studio out of another partition and it can connect through Gnome&#39;s network-admin program without any probs. So there was definitely something fishy up.&lt;/p&gt;

&lt;p&gt;Plan A at solving the problem was to install wlassistant (sudo apt-get install wlassistant) in order to try and put a different network program in the firing line. But alas still no connection. Then after a bit of head scratching we decided to install the whole bloody Gnome network admin and try and use that (sudo apt-get install gnome-system-tools) - which can be run via the &#39;network-admin&#39; command. There was a time there when this was looking like a winning plan but no joy. Weird thing is, and the Irish Penguin has no explaination for this, is that rebooting and connecting via wlassistant did the job! Worked a charm! A lucky charm!!!&lt;/p&gt;

&lt;p&gt;Final things on the list was to glam up that gaudy GUI. The install of Gnome&#39;s networking stuff had left a few stray icons in the menu so they had to be wisked away as they weren&#39;t working anyway. Then a few nice things to do are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Right-click on the quicklauncher at left of the taskbar and configure it to have a fine big icon size - 28 looked good on the Inspiron. Big icons always look nice in KDE&#39;s taskbar, otherwise where&#39;s the fun?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of the best ways to brighten up the panel is to (right-click on the taskbar and configure) set &#39;Enable background image&#39; for the panel and select a nice tile. This also puts a pretty sash down the left of the K-menu. Optionally choose &#39;Colorize to match desktop theme&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the system settings keep the Style-&gt;Widget Style as &#39;Polyster&#39; but change the Window Decoration to &#39;Keramik&#39;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the window background to be a nice soft colour - a very light fawn is nice - and in keeping with the Ubuntu theme...&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And for God&#39;s sake pic a nice desktop background!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Along the way, we flicked over to the proprietary NVidia drivers via the restricted driver management without problems. Although it did make all the fonts bigger for some reason - so they had to be tamed again using the following &lt;a href=&quot;http://ubuntuforums.org/showthread.php?t=94737&quot;&gt;fix&lt;/a&gt;  (note: changing font properties in System Settings isn&#39;t enough to fix this). I used a dpi of 75 instead of 100 as the fix did. Another thing that was hard to track down was power management adjustment there&#39;s no setting in System Settings - rather it can be found by right-clicking on the battery icon to the right of the task bar and selecting &#39;Restore&#39; to bring up the dialog - of course!&lt;/p&gt;

&lt;p&gt;So what&#39;s the verdict after all the hard work is out of the way. Kubuntu is a fine desktop if you&#39;re prepared to put in a little effort customising its look and feel. Because of the effort required in prettying it up - Kubuntu initially feels less polished than it&#39;s sister Ubuntu. Package management in Adept isn&#39;t as smooth as Synaptic. But there are some real pluses out of the K stable. Dolphin has replaced Konqueror as the default file browser and its two pane mode is great. Not quite sure why its taken so long for a two pane file manager to crop up in a modern OS but it&#39;s not before time. All the usual great KDE apps from K3B to Amarok are in there. The Penguin&#39;s final verdict is that it feels a little more &#39;bright&#39; and &#39;fun&#39; than Ubuntu which is more &#39;finished&#39; but serious.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Microsoft to Release Windows XP as Upgrade to Vista in 2010</title>
   <link href="http://www.theirishpenguin.com/2007/09/29/microsoft-to-release-windows-xp-as-upgrade-to-vista-in-2010.html"/>
   <updated>2007-09-29T23:16:40+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/09/29/microsoft-to-release-windows-xp-as-upgrade-to-vista-in-2010</id>
   <content type="html">&lt;p&gt;An anonymous source at Microsoft&#39;s Redmond headquarters revealed today how the software giant plans to release Windows XP as the successor to the ill-fated Vista operating system in the next decade.&lt;/p&gt;

&lt;p&gt;&quot;User&#39;s want choice and Microsoft will offer customers the choice of a mandatory upgrade cycle which will deliver value to the end user and a greater end user experience. Part of that experience will include the launch of Windows XP as the next generation operating system in 2010 and will replace Windows Vista as our flagship product.&quot;&lt;/p&gt;

&lt;p&gt;&quot;We have listened to customers that have told us that they would like a responsive GUI that can offer productivity gains over Windows Vista technology. In particular, usability tests have shown that Vista&#39;s &quot;preparing to copy - calculating&quot; feature, which gave the users the option to go and make a cup of tea whilst the underlying OS took 5 minutes to decide how long it would take to copy those two 4 kilobyte text files, are not proving to be the win we expected. Instead we shall revert to our patented MS-DOS technology which can perform the same task in a fraction of the time. A patent which Linux infringes.&quot;&lt;/p&gt;

&lt;p&gt;&quot;Additionally we will be removing the patented &#39;99 OK Click&#39; security functionality security feature that Vista introduced as many users asked how security was improved by providing an OK click without requesting any password. We just saw some kind of similar feature when we visited our friends at Novell called &#39;su &#39;and &#39;sudo&#39; and we thought our users would also like that. But we also knew that they wouldn&#39;t like entering passwords. This was borne out through extensive usability testing with rabbits in our lab scenarios. The rabbits also suggested that they liked the idea of a ribbon when working with the office programs. We were determined to deliver such productivity gains and value, not only to these rabbits, but also sheep and other users of our products.&quot;&lt;/p&gt;

&lt;p&gt;&quot;We found Windows XP to be the most efficient way to deliver these gains to our users through a familiar and proven user interface as well as harnessing our synergies across the Windows brand. The good news for users is that through our software assurance policy means that their subscription plan will cover the licencing cost for the XP upgrade - unless its release gets delayed like Windows Vista. Existing Windows XP licence holders will only have to pay the licence fee one more time in order to continue to use their product.&quot;&lt;/p&gt;

&lt;p&gt;Rumour also has it that Microsoft are already even planning the next OS release after Windows XP which will be in 2015. The provisional codename for it is to be &quot;Long Horn, Short Memory&quot; and it is expected that it will be built on the Windows 3.1 codebase that delivered such rich functionality through much of the nineties...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Quick European Fox Jumps Over the Lazy Dog</title>
   <link href="http://www.theirishpenguin.com/2007/09/19/the-quick-european-fox-jumps-over-the-lazy-dog.html"/>
   <updated>2007-09-19T18:48:39+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/09/19/the-quick-european-fox-jumps-over-the-lazy-dog</id>
   <content type="html">&lt;p&gt;Breaking with the blogging tradition of incredibly obvious (and search engine indexable) article titles, I think it&#39;s fitting to have a subtle, more European perhaps, heading for this post. To cut to the chase, it deals with the great transatlantic dog fight between possibly the world&#39;s biggest monopoly and the Eurocrats - that is Microsoft vs  European Competition Commission.&lt;/p&gt;

&lt;p&gt;This has caused great entertainment for those browsing the net as, for some, this has broken down into a full scale Europe vs America battle. The ruling is Microsoft&#39;s first court loss of significance that stands to have genuine legal ramifications as most other similar cases have been settled out of court by deep pockets and hamstrung prosecutions. Although it&#39;s always hard to pick the legal meat off the bones in a lot of software related court cases, other articles have mentioned that the ruling means limited scope for MS to appeal, possible requirement of protocols disclosure and of course the small matter of hundreds of millions of dollars in fines. Small change to a big fish perhaps but no one likes to throw away money.&lt;/p&gt;

&lt;p&gt;Those who support the decision are proudly strutting the streets with their vin rouge in one hand and their petit pain in the other singing &quot;Vive la Revolution&quot; as they go. Some have changed to spelling color with a &#39;u&#39; and prefer to organise their day than organize it. Those against, see the fleeting head of communism attacking capitalism&#39;s finest hour. Cries of &quot;Red! Reds! Under the beds&quot; can be heard from those who shun the European Courts ruling. Particularly entertaining is the comments at the end of the article &lt;a href=&quot;http://www.microsoft-watch.com/content/corporate/microsofts_stunning_court_defeat.html&quot;&gt;Microsoft&#39;s Stunning Court Defeat&lt;/a&gt;. I don&#39;t normally mange to keep chugging through the comments but I did find this little flame quite amusing.&lt;/p&gt;

&lt;p&gt;So what does the future legal direction of this case hold? Well that&#39;s anyone&#39;s guess, but the interesting thing that FFII correctly pointed out in one of their &lt;a href=&quot;http://press.ffii.org/Press_releases/Microsoft_will_trump_EU_competition_ruling_with_patents&quot;&gt;recent press releases&lt;/a&gt; is that patents are where the battle is at. Whatever respect Europe can garner by being the first one to call a spade a spade - or an illegal monopoly an illegal monopoly - will be soon squandered if software patents are allowed in the back door. How anyone could be stupid enough to repeatedly bring software patents to the brink of legality in Europe is amazing. But that is what&#39;s happened time and time again. Software lifecycles are measured in months (not decades like in big pharma) and innovation has always occurred by building on the ideas of others. But yet there are those who are scared that taking a stance against software patents means being anti-intellectual property - when the reverse is the case. Let&#39;s hope that the next time software patents are on the European menu, that there will be enough intelligent people in the room to call the spade again.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Kissed a QT and now I've caught Mono</title>
   <link href="http://www.theirishpenguin.com/2007/09/02/kissed-a-qt-and-now-ive-caught-mono.html"/>
   <updated>2007-09-02T18:54:06+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/09/02/kissed-a-qt-and-now-ive-caught-mono</id>
   <content type="html">&lt;p&gt;The Irish Penguin branches out to a new platform this week as Mono, the Linux-y version .NET of is tackled. What wonders await...&lt;/p&gt;

&lt;p&gt;Well, thus far, we&#39;re not actually sure, although early signs are promising. We pulled down the MonoDevelop codebase as well as it&#39;s dependancies via Subversion and most things built without major problems (on Ubuntu Fiesty) and a little help from the fabulous monodevelop-list AT lists.ximian.com (just replace AT with @) #. Although the holy grail of having a happily built MonoDevelop environment is proving just a little elusive - a conflict between Cario from v1.0 mono libraries and Cairo from v2.0 libraries is a spanner in the works. This should be a straightforward one to iron out.&lt;/p&gt;

&lt;p&gt;It will be interesting to compare the Form&#39;s/Widget designer to the fabulous QT Designer and see if MonoDevelop provides a stable and first rate environment for doing GUIs. But of course, even more interesting will be the politics...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Judge to SCO - You Don't Own Unix!</title>
   <link href="http://www.theirishpenguin.com/2007/08/12/judge-to-sco-you-dont-own-unix.html"/>
   <updated>2007-08-12T00:50:57+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/08/12/judge-to-sco-you-dont-own-unix</id>
   <content type="html">&lt;p&gt;And so the biggest legal saga to face Linux over the last few years was that of SCO trying to sue people for copyright infringement, saying that it owned the rights to UNIX. This has dragged Novell, IBM and more into the courts to fight for the right to party. Well today that party was in full swing as the judge in the case, Dale Kimball, has ruled in Novell&#39;s favour saying that it is Novell, and not SCO, who own the UNIX and Unixware rights.&lt;/p&gt;

&lt;p&gt;Kudos to Novell! It&#39;s hard to see that there is much, if anything, left in the SCO locker that they can accuse IBM of infringing. In fact, it looks like they&#39;ll be busy trying to organise a whip-a-round to pay up to Novell who will now be due a big cheque from SCO for the UNIX rights that Microsoft and Sun had previously paid SCO for. Yes, that sentence is a bit long and confusing. Perhaps it would be better to allocate IP addresses to each note in the UNIX rights cash pile and use traceroute to track its hops from one accounting subnet to another!&lt;/p&gt;

&lt;p&gt;Interesting it was Microsoft who were reported to have set the SCO ball rolling back in 2003 by paying them for the first UNIX licence . &lt;a href=&quot;http://news.com.com/2100-1016-1007715.html&quot;&gt;Here&#39;s one of the article&#39;s&lt;/a&gt; from back then when the news first broke and the world looked a bleaker place. Once details of a Microsoft-SCO association had been reported it prompted one analyst, Gordon Haff of Illuminata, &lt;a href=&quot;http://news.com.com/2100-7344_3-5172426.html&quot;&gt;to say&lt;/a&gt; &quot;Microsoft should certainly be worried about even a little bit of SCO&#39;s stench rubbing off.&quot; Well the only stench today will be from rear end of the trousers of the SCO management as they nervously wonder where to go next from here.&lt;/p&gt;

&lt;p&gt;Given that Microsoft stumped up the initial cash to set SCO off like a bull in a China shop, it is possibly fitting that such money will now likely pass on to Novell to fund Linux development. Mind you, it&#39;s hard to keep track of the amount of Microsoft cash that the Novell management are rolling around in these days. Maybe the Redmond team should just give up on Windows and focus on their Linux development entirely. Let&#39;s be honest, it&#39;s much more fun!&lt;/p&gt;

&lt;p&gt;Groklaw has been covering this tale from the start of the case and and PJ is in bouyant mood as she covers the details whilst downing some chocolates (Note: Link that used to be here no longer works http://http://www.groklaw.net/article.php?story=20070810165237718#comments). Thanks for a great site PJ, to keep the great unwashed up to date on the legal rumblings over the last few years, and please continue to do so as this fish gets reeled in.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>YouTube Vs Hollywood: Transformers Movie Shootout!</title>
   <link href="http://www.theirishpenguin.com/2007/07/30/youtube-vs-hollywood-transformers-movie-shootout.html"/>
   <updated>2007-07-30T22:59:06+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/07/30/youtube-vs-hollywood-transformers-movie-shootout</id>
   <content type="html">&lt;p&gt;And the results are in, YouTube 2 - 0 Hollywood! Mr Bay you have been beaten...&lt;/p&gt;

&lt;p&gt;Easily, the best Transformer films of the summer are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://youtube.com/watch?v=gGQsthDNGW0&amp;amp;mode=related&amp;amp;search=&quot;&gt;SuperNews! - Transformers 2&lt;/a&gt; Michael Bay tries to talk Optimus and Co into doing a sequel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;http://youtube.com/watch?v=ZWYOQoui6Ks&amp;amp;mode=related&amp;amp;search=&quot;&gt;Optimus Prime Gets Prostrate Cancer&lt;/a&gt; Despite it&#39;s morbid title, this is hilarious!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Mee, Grimlock luv U-Tube!!!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Momentumless Linux and the Death of Open Source - A Developer's Response</title>
   <link href="http://www.theirishpenguin.com/2007/07/15/momentumless-linux-and-the-death-of-open-source-a-developers-response.html"/>
   <updated>2007-07-15T00:18:28+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/07/15/momentumless-linux-and-the-death-of-open-source-a-developers-response</id>
   <content type="html">&lt;p&gt;A couple of blog and news posts on the Internet this week seemed to make the headlines with death knells for Linux and Open Source for a multitude of reasons, both chronic (less anti-Microsoft sentiment about) and recent (GPL 3). But on reading, I couldn&#39;t help but feel that both posts sounded wrong, utterly utterly wrong in fact. No disrespect intended to the authors of course.&lt;/p&gt;

&lt;p&gt;The first post &lt;a href=&quot;http://www.informationweek.com/software/open-source-is-dead-long-live-open-paten/229215592&quot;&gt;Open Source Is Dead, Long Live Open Patents?&lt;/a&gt; by David DeJean, which took a commonly cited angle on GPL3 hurting Open Source by fragmenting the community. But that is to not understand the community. Bare in mind one important fact about community-oriented Open Source developers, of which I am one - we write the software because we love to. For the vast majority of SMD&#39;s (Small-to-Medium size project Developers, for want of a better term) we don&#39;t really care whether our project is GPL2 or GPL3 - why? Because they are both effective Open Source licences and they will both serve our personal purposes fine as either licence would suit our pet projects. Of course, we&#39;ll all still get our goat up as to whether Linux or the GNU Compiler Tools should be GPL 2 or 3 - but that&#39;s a separate issue - it&#39;s won&#39;t stop us writing the software we love. It is naive for commentators to think that because a new licence comes out that it will hurt the amount of FOSS produced. As for businesses, if it made sense to switch to Linux before GPL 3, it will still make sense after GPL3 - irrespective of what or who adopts GPL 3. It technically affects Tivo (although they will be able to stick with Linux 2.4 kernel) - so what? Such cases only make up a small part of the econosphere. Plenty of business providers seem to be happy (note: link to http://www.builderau.com.au/news/soa/GPL3-welcomed-by-IBM-Red-Hat-Novell-MySQL/0,339028227,339279403,00.htm no longer works). Even embedded solution providers are saying that GPL 3 won&#39;t turn customers off, with Jason Wacha of MontaVista saying, &quot;Our customers are used to working with licenses that are much more restrictive than the GPL. In my opinion, typical proprietary licenses are much more restrictive in pretty much all instances than the GPL.&quot; (Reference: http://www.internetnews.com/dev-news/article.php/3686486)&lt;/p&gt;

&lt;p&gt;The second article &lt;a href=&quot;http://www.itbusinessedge.com/cm/blogs/enderle/why-open-source-and-linux-are-losing-momentum/?cs=16550&quot;&gt;Why Open Source and Linux Are Losing Momentum&lt;/a&gt; seemed a bizarre choice of title for a engineering philosophy and a platform which is currently experiencing stellar momentum towards ever greater adoption. As one commenter at the end of the article said - check out the Gartner and IDC statistics. But being a lazy developer I&#39;ll just speak from my own experience. I&#39;m finding that small to medium sized Microsoft shops are getting squeezed as Microsoft have made it more difficult for such companies to maintain partnership status. Today, a given company is required to have more and more MCSE&#39;s or MCAD&#39;s on the books in order to get any level of partnership. But obviously it is easier for 100 employee company to get X number of MCSE&#39;s than it is for a company of 4 employees. Despite the fact that small tight teams tend to deliver better results (in a traditionally managed non-bazaar environment). So why penalise the small guys? Why make them fork out more licencing costs for things such as Visual Studio and Team Studio while the big fish get these through the partnership program?&lt;/p&gt;

&lt;p&gt;Perhaps, Rob Enderle, the author of this second article might reflect on this as a reason for lower software project margins than blindly (I don&#39;t mean to be offensive, I really don&#39;t, but the following assertion amazed me) stating that GPL and Linux drove developers to India. If Microsoft want to help boost profit margins for software houses then help developers in small business. Otherwise the trend showing that &lt;a href=&quot;http://www.pcworld.com/article/id,134115-c,researchreports/article.html&quot;&gt;Microsoft&#39;s Windows platform is losing traction as a target for application developers in North America&lt;/a&gt; is likely to continue. In this article, John Andrews, the CEO of Evans Data, says &quot;We attribute [the decline] largely to the increase in developers beginning to target Linux and different Linux [distributions].&quot;&lt;/p&gt;

&lt;p&gt;One reason that seems to be driving this shift is that customers like web apps more than desktop applications and even though C# marches forward, making big progress on the taking Java on head to head, it is being flanked by the likes of Ruby and even Python on the web app development scene. It also is interesting to note that if you have recently had your Microsoft partnership cut short and you still want to dog food you will probably be using SourceSafe to manage your source code. My advice - don&#39;t. Because similarly positioned competitors are most likely using &lt;a href=&quot;http://subversion.tigris.org/&quot;&gt;Subversion&lt;/a&gt; and this will give them a technical advantage that you will find hard to bridge. SourceSafe is interesting in that, despite it&#39;s name, it does not source control code. Unless you like tagging every revision - there is no way to see what you project looked like for a given revision - something that is trivial in Subversion and in particular &lt;a href=&quot;http://tortoisesvn.tigris.org/&quot;&gt;TortoiseSvn&lt;/a&gt;. It&#39;s a sign of the times when it makes so much more sense for Microsoft Shops to use Free Software alternatives to dog food.&lt;/p&gt;

&lt;p&gt;Another bone of contention I have with the article is it&#39;s stance on outsourcing. The reason that jobs get outsourced is simple because the destination countries have well skilled professional people who can help lower costs for a business if properly utilised. It is the U.S. that agrees trade pacts with these countries, not Richard Stallman, Linus Torvalds - those happy bed fellows :) - or Eben Moglen. If you don&#39;t like that then vote accordingly but I&#39;m a little confused at how GPL/Linux could be blamed. On the subject of Google rising on the hard work of FOSS, it&#39;s worth noting that Google does participate in the community - Google Web Toolkit, Google Summer of Code and Google&#39;s Open Source Project Hosting service to name but a few - and in addition, Google pays lots of top notch Linux dev&#39;s a handsome salary.&lt;/p&gt;

&lt;p&gt;Another point I took from the article was how Bill Gates almost &#39;invented&#39; the notion of software developer jobs and turned a bunch of hobbyists into professionals - from the &lt;a href=&quot;http://www.thocp.net/companies/microsoft/microsoft_company.htm&quot;&gt;Microsoft history&lt;/a&gt; link provided. But realistically it just so happened that Microsoft came on the scene just as desktops started becoming useful to business in this manner. There were plenty of others out there to pay developers - I certainly think that IBM would have paid a few along the way. A more interesting trip back in time would be to 1991, when Bill Gates said &lt;a href=&quot;http://eupat.ffii.org/archiv/zitate/#bgates91&quot;&gt;Patents exclude competitors, lead industry to standstill&lt;/a&gt; compared to the anti-Linux saber rattling patent assault going on at the moment. No doubt you&#39;ve all seen the now infamous &lt;a href=&quot;http://money.cnn.com/magazines/fortune/fortune_archive/2007/05/28/100033867/&quot;&gt;Fortune&lt;/a&gt; magazine article linked to on more than one occasion.&lt;/p&gt;

&lt;p&gt;So that&#39;s another day in the life of the Internet. I&#39;ll sign off on the following note. At one point in the latter article I&#39;ve covered, Rob Enderle, asks of GPL 3 &quot;What has it done to increase software value, programmer salaries or software company profitability?&quot; My answer is simple, by championing the goal of removing the scourge of software patents from the software industry, the GPL encourages the development of programs without the fear and persecution of anti-competitive legal intervention from 3rd parties. It&#39;s message is clear &#39;Spend your precious cash on paying software developers, not lawyers&#39;. Rob says that Microsoft is no longer a danger... We&#39;ll all believe that when they sign up to the patent non-proliferation treaty. Until then, look up, sit back, and watch them pigs fly!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Transformers - The Worst Movie Ever!</title>
   <link href="http://www.theirishpenguin.com/2007/07/08/transformers-the-worst-movie-ever.html"/>
   <updated>2007-07-08T22:53:46+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/07/08/transformers-the-worst-movie-ever</id>
   <content type="html">&lt;p&gt;Robots in disguise? No. Michael Bay - film maker in disguise. He has taken a cult classic and turned it into a steaming pile of utter junk of the &quot;Yeeh hawww! God bless America variety.&quot; Certainly, he should never be allowed near a movie studio ever again. Here&#39;s why.....&lt;/p&gt;

&lt;p&gt;You would think that Transformers would be a film about robots. No, in fact the only time robots make it into the film is to appear in cabaret style slapstick sketches where they incompetently fall about the place. They are like extras from a pantomime, lacking any personality, led by incredibly boring Optimus Prime who comes across a sort of Treebeard, from Lord of the Rings, with a number plate strapped - he really is that bland in this film.&lt;/p&gt;

&lt;p&gt;A massively disappointing thing in the film is that all the Transformers look the same - kind of like a couple of electricity pylons stuck together. It&#39;s actually hard to tell Megatron, the ultimate baddie, from any of the robots because they all look the same. Poor Megatron doesn&#39;t even have his trademark canon strapped on his arm??? And Optimus&#39; colour scheme makes him looks like he&#39;s about to lead a gay pride Autobot march rather than go into battle. Worse again he has lips - no doubt this is to give the audience something &#39;human&#39; to identify with. However the only thing this movie could be identified with is the type of thing that you flush down a toilet after a long night on the beer. Yes, it&#39;s that bad.&lt;/p&gt;

&lt;p&gt;And to top it off the film can&#39;t resist rolling out the usual racial stereotypes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The black people in the film are portrayed as stupid and fat&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The dialogue is peppered with things such as &#39;Could the Iranians have invented this weapons system? No, they&#39;re not smart enough. It must be the Chinese or the Russians...&#39; (not an exact quote as I&#39;m trying to forget things about this film but close enough)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;And whilst the autobots collapse clumsily around the place, the U.S. marines fly in to save the day. Wup dawg!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The Autobots and the Decepticons also never really get to have a good fight with each other. For example when Megatron and Optimus tee off they look more like a couple of fat wrestlers bumbling each other around that robots having a death match. You don&#39;t really get to see much, just a blurry zoomed in camera on their shoulders as they tussle about like drunks thrown out after closing time. There are a few saving graces to this movie. The acting isn&#39;t bad, there&#39;s a few funny gags along the way, the lead female in the film - Megan Fox - does a very good job of looking hot, the small boom-box radio transformer at the start of the film is funny and has a bit of personality.&lt;/p&gt;

&lt;p&gt;But the bottom line, if you want to watch a war film - along the lines of Armageddon or something - then this might pass the time for you. Think of this as Iraq with cabaret robots. If you, like me, grew up with Optimus and Co and were hoping for a strong appearance on the silver screen then this is two and half hours of your life that you&#39;ll want back! But like the brilliance of the original series - you can&#39;t have it!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>QObject, QMake and Sadness - 'Undefined reference to vtable'</title>
   <link href="http://www.theirishpenguin.com/2007/07/01/qobject-qmake-and-sadness-undefined-reference-to-vtable.html"/>
   <updated>2007-07-01T13:24:51+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/07/01/qobject-qmake-and-sadness-undefined-reference-to-vtable</id>
   <content type="html">&lt;p&gt;Mmmm... Bit of a longwinded title there! Basically, I could not shake off the following error recently, when writing a class Browser which inherited from QObject. Apparently, the answer is that sometimes you simply have to delete your Makefiles and regenerate them using QMake (KDevelop automatically creates Makefiles from me if none are found), in order to get over this error.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/path/to/frogface/trunk/src/browser.cpp:38:
undefined reference to `vtable for Browser&#39;
browser.o: In function `Browser&#39;:
/path/to/frogface/trunk/src/browser.cpp:34:
undefined reference to `vtable for Browser&#39;
/path/to/frogface/trunk/src/browser.cpp:34:
undefined reference to `vtable for Browser&#39;
collect2: ld returned 1 exit status
gmake[1]: *** [../bin/frogface] Error 1
gmake: *** [sub-src-make_default] Error 2
*** Exited with status: 2 ***
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thanks to the patient folks on the QT mailing for the help!&lt;/p&gt;

&lt;p&gt;Funnily enough as I write this, someone&#39;s just posted the following checklist on the #qt irc channel, which is good advice&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Make sure the Q_OBJECT macro is present in the definition of all QObject-derived classes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you define your QObject-derived classes in your header files ONLY&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure all of your header files are listed in your .profile in the HEADERS=list&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run qmake every time you add Q_OBJECT to one of your classes or modify your .pro file&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The last one is particularly important as I&#39;ve made an art form out of forgetting it :)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>QDomDocument is not a QObject</title>
   <link href="http://www.theirishpenguin.com/2007/06/29/qdomdocument-is-not-a-qobject.html"/>
   <updated>2007-06-29T12:43:26+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/29/qdomdocument-is-not-a-qobject</id>
   <content type="html">&lt;p&gt;Aha! Here&#39;s one that caught me out for a while. I was writing a class that inherited from QDomDocument and was more than a bit puzzled when I got the error&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;moc_fdom.cpp:37: error: &#39;staticMetaObject&#39; is not a member of &#39;QDomDocument&#39;
moc_fdom.cpp: In member function &#39;virtual void*
JsDomDocument::qt_metacast(const char*)&#39;:
moc_fdom.cpp:51: error: &#39;qt_metacast&#39; is not a member of &#39;QDomDocument&#39;
moc_fdom.cpp: In member function &#39;virtual int
JsDomDocument::qt_metacall(QMetaObject::Call, int, void**)&#39;:
moc_fdom.cpp:56: error: &#39;qt_metacall&#39; is not a member of &#39;QDomDocument&#39;
gmake[1]: *** [moc_fdom.o] Error 1
gmake: *** [sub-src-make_default] Error 2
*** Exited with status: 2 ***
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Turns out QDomDocument isn&#39;t a QObject so I was making the mistake of including the Q_OBJECT macro at the start of my class definition. D&#39;oh!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class XDomDocument : public QDomDocument
{
    Q_OBJECT //Don&#39;t do this!!!
    public:
        XDomDocument();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A side effect of not being a QObject is that you cannot wire up signals and slots in the normal manner. Although googling around should bring up a few workarounds.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Linux Kernel - An Overview from IBM</title>
   <link href="http://www.theirishpenguin.com/2007/06/29/the-linux-kernel-an-overview-from-ibm.html"/>
   <updated>2007-06-29T12:37:13+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/29/the-linux-kernel-an-overview-from-ibm</id>
   <content type="html">&lt;p&gt;Good things come in small packages packages. But great things are scabable!&lt;/p&gt;

&lt;p&gt;One such example is the Linux kernel - it can run on anything from a toaster to a supercomputer; how does it do it? The answer to this, and other interesting questions, can be found in the very readable guide to the Linux kernel by IBM &lt;a href=&quot;http://www.ibm.com/developerworks/linux/library/l-linux-kernel/?S_TACT=105AGX59&amp;amp;S_CMP=GR&amp;amp;ca=dgr-lnxw02LKernalAnatomy&quot;&gt;Anatomy of the Linux kernel&lt;/a&gt;.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>.NET - Develop in Visual Studio, Deploy on Linux</title>
   <link href="http://www.theirishpenguin.com/2007/06/24/net-develop-in-visual-studio-deploy-on-linux.html"/>
   <updated>2007-06-24T18:25:30+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/24/net-develop-in-visual-studio-deploy-on-linux</id>
   <content type="html">&lt;p&gt;Recently, a new product has hit the market for those folks who would like to develop in .NET, and in particular Visual Studio, but prefer to run their application on Linux.&lt;/p&gt;

&lt;p&gt;Although you could already code up .NET solutions in MonoDevelop - which itself has made great progress recently - most enterprises will only want to write .NET server and web apps in Visual Studio. Mainsoft has seen the gap in the market and filled it with a free plugin for Visual Studio, called &lt;a href=&quot;http://xml.sys-con.com/read/393685.htm&quot;&gt;Grasshopper&lt;/a&gt;, which lets you deploy to Linux. It achieves this by compiling the application to Java bytecode rather than the .NET intermediate language and also leverages work done in the Mono project, which has already done much work in bringing .NET to Linux.&lt;/p&gt;

&lt;p&gt;In other news, Silverlight has been successfully ported to Linux through an incredible hackathon effort by Miguel de Icaza and his Mono team! Going under the name of Moonlight, the port was pretty much wrapped up in 21 days - so it&#39;s amazing to think that with all this going on Miguel has any time to keep &lt;a href=&quot;http://tirania.org/blog/archive/2007/Jun-21.html&quot;&gt;his blog&lt;/a&gt; updated!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The PHP Header() Trap</title>
   <link href="http://www.theirishpenguin.com/2007/06/24/the-php-header-trap.html"/>
   <updated>2007-06-24T17:48:11+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/24/the-php-header-trap</id>
   <content type="html">&lt;p&gt;This is just a quick tip for young players - new to the PHP game. The rather sexy header() function can be used to redirect the user from one page to another. But an important point about this function is that you cannot send ANY html or empty lines or spaces (or anything) to the client browser prior to calling the header() function.&lt;/p&gt;

&lt;p&gt;This sounds easy to guard against but it isn&#39;t always obvious. You could include a file using include(), require() or require_once() and it could be the culprit. This hit home particularly hard today when it turned out that out database connection file had empty lines after the closing php tag &quot;?&gt;&quot;&lt;/p&gt;

&lt;p&gt;Ironically, if the empty lines had been located before the closing php tag then everything would have been fine, as they would not have been sent to the client - c&#39;est la vie! The solution became apparent after stumbling across this &lt;a href=&quot;http://us3.php.net/manual/en/function.header.php&quot;&gt;page&lt;/a&gt; which spelt the problem out clearly.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Unexpected Javascript Postbacks?</title>
   <link href="http://www.theirishpenguin.com/2007/06/21/unexpected-postbacks.html"/>
   <updated>2007-06-21T16:08:36+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/21/unexpected-postbacks</id>
   <content type="html">&lt;p&gt;This has been driving me bananas for hours. If you&#39;re finding that your javascript function is causing your page to post back to itself unexpectedly, then ensure that it returns false at the end of the function. Also &lt;a href=&quot;http://www.quackit.com/javascript/tutorial/javascript_void_0.cfm&quot;&gt;void(0)&lt;/a&gt; can be your friend.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Surviving Migration from ASMX to WCF Webservices</title>
   <link href="http://www.theirishpenguin.com/2007/06/11/surviving-migration-from-asmx-to-wcf-webservices.html"/>
   <updated>2007-06-11T21:15:29+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/11/surviving-migration-from-asmx-to-wcf-webservices</id>
   <content type="html">&lt;p&gt;Just when you thought you&#39;d gotten the hang of the good ol&#39; fashioned .NET webservices (the ASMX variety) those Redmond boys went and changed everything with the release of WCF! The benefits of WCF webservices are that they&#39;re considerably more flexible but the transition can be a lot steeper than you&#39;d expect. Here&#39;s a nice little guide by Dominick Baier on some of the day-to-day areas of the API that can catch you out unawares...&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://leastprivilege.com/2006/09/25/hosting-wcf-services-in-asp-net-the-survival-guide/&quot;&gt;Hosting WCF Services in ASP.NET - The Survival Guide&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Viva Le Gaelic Penguin!</title>
   <link href="http://www.theirishpenguin.com/2007/06/09/viva-le-gaelic-penguin.html"/>
   <updated>2007-06-09T00:56:53+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/06/09/viva-le-gaelic-penguin</id>
   <content type="html">&lt;p&gt;Phew! After much fiddling and tweaking I finally managed to get my header image together for this site. All the while I had the song &quot;The Irish Rover&quot; bouncing round in my head - which probably didn&#39;t help matters!&lt;/p&gt;

&lt;p&gt;But I think the above header was worth it.  Veronica, my glamorous girlfriend and graphic design mentor, didn&#39;t like it much to start with. At least I managed to pacify her by throwing in a cute penguin pic, which I did up in the absolutely fabulous Inkscape. Inkscape has to be one of the best Free Software programs ever. It&#39;s just so easy to use and yet things just always turn out good.  It&#39;s magic. And that&#39;s just the kind of thing you&#39;ll be hearing more about on this blog over the coming months along with other news and discussion from the filthy dirty world of Open Source.&lt;/p&gt;

&lt;p&gt;Just a heads up for anyone trying to change their WordPress header image - make sure that you haven&#39;t changed the header&#39;s colours or anything previously in WordPress. If you have made changes then you should revert them - which can be done from the dashboard. Otherwise all the image uploading and CSS styling in the world won&#39;t be enough to get that flamin&#39; header to change! Now there&#39;s an hour of my life that I won&#39;t get back! At least I had The Irish Rover playing away in the back of my head to keep me going...&lt;/p&gt;

&lt;p&gt;Doo do doo...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>GPL V3 - Its True Purpose</title>
   <link href="http://www.theirishpenguin.com/2007/05/30/gpl-v3-a-potential-misrepresentation-of-its-purpose.html"/>
   <updated>2007-05-30T19:30:28+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/30/gpl-v3-a-potential-misrepresentation-of-its-purpose</id>
   <content type="html">&lt;p&gt;Recently, I read some interesting commentary on the Microsoft-Novell pact in an Linux Insider article entitled &lt;a href=&quot;http://www.linuxinsider.com/story/57594.html&quot;&gt;GPLv3 Could Be Risky Business&lt;/a&gt; which concluded with the following statement.&lt;/p&gt;

&lt;p&gt;&quot;Regardless of the GPLv3 outcome, it should be noted that Microsoft and Novell are two large companies with plenty of attorneys -- if they want to do business together over Linux and Microsoft products, it&#39;s not hard to imagine that they&#39;ll be able to find a way.&quot;&lt;/p&gt;

&lt;p&gt;This statement didn&#39;t seem to ring true for me - it seemed to be wrong way to view what the Free Software Foundation is doing with GPL V3. Here&#39;s why.&lt;/p&gt;

&lt;p&gt;Nobody wants to &#39;stop&#39; Microsoft and Novell, or any other Open Source distributor, from doing business together. In fact, it would be desirable to see Microsoft produce more Open Source software - as they have with the projects such as the Web Service Software Factory - and collaborate with other players in the Open Source software field.&lt;/p&gt;

&lt;p&gt;Rather the point of GPL V3 is to defend the rights of Free Software developers to produce software without the fear of litigation hanging over their head - by extending the patent covenant to all of the Free Software community - not just Novell customers. This fear of potential litigation has been raised more strongly than ever by recent Microsoft comments in &lt;a href=&quot;http://money.cnn.com/magazines/fortune/fortune_archive/2007/05/28/100033867/&quot;&gt;Fortune magazine&lt;/a&gt;. However, it appears that by not having an expiry date on the Linux coupons that Microsoft is distributing, &lt;a href=&quot;http://community.linux.com/article.pl?sid=07/05/17/1640207&amp;amp;from=rss&quot;&gt;Microsoft itself will become a GPL V3 Linux distributor&lt;/a&gt;, and finally their patent covenant will extend to every corner of the Free Software communities. This will be genuinely good for software development, for the Open Source community and most of all for Microsoft - who has a lot to offer in the field of Open Source software.&lt;/p&gt;

&lt;p&gt;They have a lot of bright developers and engineers and it is in everyone&#39;s interests to see these people contribute greatly to the I.T. sector over the coming years. But it is important that the playing field is level and that instead of &#39;innovative lock-ins&#39; and restrictive file formats we see a truly great Microsoft emerge that is founded on on true innovation, engineering excellence and co-operation. The first step on this path is to build a true bridge to the Free Software community and not seemingly pretend that this intellectual property bridge is any more than an attempt to scare companies into paying a high premium for &#39;Microsoft-approved&#39; Linux of Novell - using patents instead of file formats as the lock-in.&lt;/p&gt;

&lt;p&gt;In summary,  it is important to note that the purpose of the latest version of the GNU Public Licence is not on preventing co-operation between Microsoft and Novell with their pact, rather it is to defend everyone else who is threatened by the it. To this end, GPL V3 looks like it will do it&#39;s job very well - winning over many of those who doubted its necessity early on in its GPL 3 draft process. And the &lt;a href=&quot;http://www.softwarefreedom.org/&quot;&gt;Software Freedom Law Centre&lt;/a&gt; and it&#39;s &#39;plenty of attorneys&#39; has another feather in its cap as it shows an interesting hand in the poker game of software licensing. And if this hand is not enough for now, &#39;it&#39;s not hard to imagine that they&#39;ll be able to find a way&#39; to continue to keep software development a free and democratic process. If you weren&#39;t sure why you needed GPL V3 yesterday, you probably know why today.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>XML Document Creation in Javascript - Cross Platform</title>
   <link href="http://www.theirishpenguin.com/2007/05/28/xml-document-creation-in-javascript-cross-platform.html"/>
   <updated>2007-05-28T17:55:06+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/28/xml-document-creation-in-javascript-cross-platform</id>
   <content type="html">&lt;p&gt;This is an absolutely super guide which basically gives you some neat code in order to work with XML documents across multiple platforms in the sadistic language of the web - Javascript.&lt;/p&gt;

&lt;p&gt;It&#39;s a 4 page tutorial which overviews a static JS class that the author has put together which provides helper methods for creating a new XML document on the client browser by loading from disk, URL&#39;s or strings.  I found it especially useful for squeezing a javascript string into a nice XML representation. Check it out on &lt;a href=&quot;http://www.webreference.com/programming/javascript/definitive2/4.html&quot;&gt;WebReference.com&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Microsoft Not So Sure on Taking on World…</title>
   <link href="http://www.theirishpenguin.com/2007/05/15/microsoft-not-so-sure-on-taking-on-world.html"/>
   <updated>2007-05-15T09:30:33+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/15/microsoft-not-so-sure-on-taking-on-world</id>
   <content type="html">&lt;p&gt;Under pressure arising from comments made by Microsoft&#39;s Horacio Gutierrez and Brad Smith in an Fortune magazine article earlier this week saying that Open Source software contains 235 Micrsoft patents, the company has &lt;a href=&quot;http://www.informationweek.com/news/showArticle.jhtml?articleID=199501831&quot;&gt;released a statement&lt;/a&gt; that it does not intend to resort to litigation in an effort to halt the growth of Open Source software. So why would they highlight an issue and then when asked to state specifically which are the patents in question they respond, &quot;We&#39;re not going to have a discussion publicly with that level of detail.&quot;&lt;/p&gt;

&lt;p&gt;The answer is simple. If they publish them it is likely that most of them will be thrown out by the U.S. courts as invalid. This became much easier recently, when the &lt;a href=&quot;http://arstechnica.com/news.ars/post/20070430-supreme-court-ruling-makes-obvious-patents-harder-to-defend.html&quot;&gt;U.S. Supreme court made it easier to legally challenge individual patents&lt;/a&gt; and get them invalidated. This is because most software patents have been granted without due consideration and aren&#39;t actually valid for many reasons. Patents have been grantly for things that are patently unpatenable.&lt;/p&gt;

&lt;p&gt;Once this weeds out the likely majority of patents - Open Source developers will endevour to work around what patents, if any, remain.&lt;/p&gt;

&lt;p&gt;So, back to the question, why would Microsoft highlight a meaningless question? Well, to bring up the issue in this manner creates a degree of uncertainty in the minds of certain business owners - however misplaced. Such people must weigh up risk every day and anything that they perceive adding risk to their business they will avoid. This will take two forms, one is to avoid Open Source software and stick with closed solutions. But this is becoming increasingly difficult as it is making more and more business sense to deploy Open Source solutions every day. The other is pay royalties to Microsoft for these (vaguely) alledged infringing patents. This is a sad situation because paying &#39;money for nothing&#39; is money that you could otherwise use to grow your business.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Microsoft Vs The World</title>
   <link href="http://www.theirishpenguin.com/2007/05/14/microsoft-vs-the-world.html"/>
   <updated>2007-05-14T11:40:58+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/14/microsoft-vs-the-world</id>
   <content type="html">&lt;p&gt;Microsoft is allegedly preparing it&#39;s army of lawyers (&lt;a href=&quot;http://scobleizer.com/2007/05/13/microsoft-about-to-enter-into-patent-war/&quot;&gt;more than 800 strong&lt;/a&gt; according to one commentator) to issue an &lt;a href=&quot;http://money.cnn.com/magazines/fortune/fortune_archive/2007/05/28/100033867/&quot;&gt;almighty patent onslaught&lt;/a&gt; on Open Source software. It lists 235 patents which it says are being violated by Open Source software projects. Microsoft CEO Steve Balmer says that it is in the &quot;name of honour&quot; that he must fight the Open Source community. The battle lines are being drawn in what could prove to be the ultimate shakeup of the U.S. software patent system. As Microsoft comes under increased pressure from Open Source software it is making lawyers, not software developers, the front-line soldiers in the fight to maintain the apparent monopoly. It looks like we&#39;re entering interesting times.&lt;/p&gt;

&lt;p&gt;On a lighter note, here&#39;s a &lt;a href=&quot;http://www.youtube.com/watch?v=wvsboPUjrGc&quot;&gt;clip&lt;/a&gt; of Steve Balmer trying to rally the Redmond programmers in better days before lawyers led software development. I wonder does he exhibit the same passion today when he stands in front of his devs or does he prefer to go into the TV lounge and flick on an episode of Boston Legal...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Installing the Netgear WG511v2 (China) Wireless Card on Linux</title>
   <link href="http://www.theirishpenguin.com/2007/05/12/installing-the-netgear-wg511v2-china-wireless-card-on-linux.html"/>
   <updated>2007-05-12T14:03:13+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/12/installing-the-netgear-wg511v2-china-wireless-card-on-linux</id>
   <content type="html">&lt;p&gt;These instructions are intended to be used to install a Netgear WG511 v2 (China) on a Linux machine that dual boots with Windows. I take no responsibility for anything bad that might happen if you follow this guide (I try to avoid responsibility at every turn).&lt;/p&gt;

&lt;h3&gt;PRE-REQUISITES&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your machine must be a dual boot system&lt;/li&gt;
&lt;li&gt;You must have the wireless card installed and functioning on Windows&lt;/li&gt;
&lt;li&gt;The Windows partition on which you installed the wireless card already must be accessible to the Linux system (my Windows partion had the FAT32 filesystem which made this easy). If not you will first have to find a tutorial that covers this. A quick google on this topic should help. It will require you to update your /etc/fstab file. Here&#39;s an article on this file http://www.tuxfiles.org/linuxhelp/fstab.html but as I said googling around might find you even easier tutorials on this.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;ADDITIONAL NOTES&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I performed this on an IBM T22 running Ubuntu Linux 5.10 &#39;Breezy Badger&#39; and also on OpenSuse 10.2. Windows 2000 was also installed as part of my dual boot system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As I did this on Ubuntu I used sudo instead of logging in as root. That&#39;s what the rest of this guide assumes. On OpenSuse, I used su from the command line in order to become the root user. Depending on your distro you may have to log in as root if it doesn&#39;t support sudo.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;INSTRUCTIONS&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ensure that the wireless driver is installed and working on Windows&lt;/li&gt;
&lt;li&gt;Shutdown and remove your wireless card from it&#39;s PCMCIA slot (I&#39;m not sure if this step is needed)&lt;/li&gt;
&lt;li&gt;Boot into your Linux distro&lt;/li&gt;
&lt;li&gt;Install the ndiswrapper packages&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the command prompt (whilst still logged into Linux), search for the driver on the windows partition (storing the results in a file for easy viewing). For example (your path to Windows will probably be different)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;find /mnt/windisk/ -iname &#39;*.inf&#39;&amp;gt;inf_files_on_windows.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open inf_files_on_windows.txt in your favourite editor and look for the matching driver. It should be something like WG511v2.INF (this may vary on your system). Do some searches on &#39;WG&#39; or on &#39;511&#39; to track it down. Note: You will need the full path to this file for the next step&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the command line type (but make sure the path matches the one you found in the previous step and remember to use the FULL path)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ndiswrapper -i /mnt/windisk/winnt/inf/WG511v2/WG511v2.INF
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;N.N.B. Sorry to labour the point but remember you need to reference the ORIGINAL driver file on your windows partion; you can&#39;t copy it over to your Linux partion and reference it from there (I tried!). This is at the heart of the &#39;dual boot&#39; system requirement (perhaps you know a way around this - I&#39;m not terribly clever at this sort of thing!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type the following command to see if your installation was successful&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo ndiswrapper -l
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A message like this indicates success&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Installed ndis drivers:
wg511v2 driver present
&lt;/code&gt;&lt;/pre&gt;

 A message like this indicates failure (sorry!)

&lt;pre&gt;&lt;code&gt;Installed ndis drivers:
wg511v2 invalid driver!
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I really hope the last step worked. If not you&#39;ll have to re-google and try another solution (double check that you&#39;ve followed this guide correctly first). If so, plug your wireless card into the PCMCIA slot. Then type &#39;sudo ndiswrapper -l&#39; again. You should get&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Installed ndis drivers:
wg511v2 driver present, hardware present
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I can remember the excitment when I saw the above line. Share the fun! The rest of this should be a doddle (but don&#39;t count your chickens!)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Load the ndiswrapper module into the kernel using&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;sudo modprobe ndiswrapper
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To see that this worked (the green LED on your card should now have flicked into life) run the command &#39;dmesg&#39; and you should get some info on how your wireless card has been installed, for example&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ndiswrapper version 1.1 loaded (preempt=no,smp=no)
ndiswrapper: driver wg511v2 (NETGEAR,02/22/2005,3.1.1.7) loaded[4296766.069000] PCI: Enabling device 0000:22:00.0 (0000 -&amp;gt; 0002)
ACPI: PCI Interrupt 0000:02:02.0[A] -&amp;gt; Link [LNKA] -&amp;gt; GSI 11 (level, low) -&amp;gt; IRQ 12
PCI: Setting latency timer of device 0002:02:00.0 to 64
ndiswrapper: using irq 12
wlan0: ndiswrapper ethernet device 01:0f:b5:8e:4e:2d using driver wg511v2, configuration file 11AB:1FAA:2385:4E00.5.conf
wlan0: encryption modes supported: WEP, WPA with TKIP, WPA with AES/CCMP
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the above output I can now tell that my card has been assigned to the &#39;wlan0&#39; interface. Yours may differ.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Your card is now ready for use. You can use the &#39;iwlist&#39; command to scan for connections. For example (replace &#39;wlan0&#39; with the interface that your card in the dmesg output above),&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;iwlist wlan0 scan
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One final thing, set the &#39;sudo modprobe ndiswrapper&#39; command to be run on each boot (how you do this will depend on your disto). Otherwise, you&#39;d have to run this command each time you log in.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I actually haven&#39;t used my wireless card yet (in fact, I&#39;m just writing this article 10 seconds after completing these steps I&#39;m describing!) but apparently Pawel Nawrocki&#39;s Wireless Assistant is a great tool. So says Linux Format at http://www.linuxjournal.com/article/8398 which might have a link to it&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Happy networking. Why don&#39;t you go and listen to the following &lt;a href=&quot;http://www.gnu.org/music/free-software-song.html&quot;&gt;Free Software Song&lt;/a&gt; to top off the perfect day.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;One final note&lt;/h3&gt;

&lt;p&gt;I was never able to connect to networks protected by the basic encryption WEP but had no problems connecting to networks using the more more secure encryption WPA. This could just be me...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Future?</title>
   <link href="http://www.theirishpenguin.com/2007/05/09/the-future.html"/>
   <updated>2007-05-09T07:19:01+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/09/the-future</id>
   <content type="html">&lt;p&gt;Beau-ti-ful...&lt;/p&gt;

&lt;p&gt;This used to have a link to http://www.dell.com/content/topics/segtopic.aspx/ubuntu?c=us&amp;amp;cs=19&amp;amp;l=en&amp;amp;s=dhs but it is no longer available.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Javascript Tip Of The Day: “When Is A Width Not A Width?”</title>
   <link href="http://www.theirishpenguin.com/2007/05/05/javascript-tip-of-the-day-when-is-a-width-not-a-width.html"/>
   <updated>2007-05-05T06:50:23+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/05/javascript-tip-of-the-day-when-is-a-width-not-a-width</id>
   <content type="html">&lt;p&gt;This is a bit of a gotcha for young players in the Javascript game. You have a web page with a DIV which you fill dynamically with, let&#39;s say, 5 IMG elements. How do you get the width of the DIV? You can try&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;document.getElementById(&#39;divId&#39;).width
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;but it will do you no good. The answer, use&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;document.getElementById(&#39;divId&#39;).offsetWidth
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;http://msdn2.microsoft.com/en-us/library/ms533024.aspx&quot;&gt;Here&#39;s&lt;/a&gt; a handy guide when it comes to DHTML element position and locations.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Community Must Help Dell Sell Linux</title>
   <link href="http://www.theirishpenguin.com/2007/05/01/linux-community-must-help-dell-sell-linux.html"/>
   <updated>2007-05-01T22:21:45+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/05/01/linux-community-must-help-dell-sell-linux</id>
   <content type="html">&lt;p&gt;The announcement that many people wanted to hear is imminent.  Early rumours &lt;a href=&quot;http://news.com.com/Dell+picks+Ubuntu+for+Linux+PCs/2100-7344_3-6180419.html&quot;&gt;abound&lt;/a&gt; on &lt;a href=&quot;http://www.desktoplinux.com/news/NS8661763902.html&quot;&gt;various sites&lt;/a&gt; but possibly by the time you are reading this, Dell will have already made the official announcement that they are to ship Dell PC&#39;s with the Linux operating system - Ubuntu. This is the major breakthrough that Linux as a desktop OS has been waiting for. Now all Linux communities -be it Open Source, Free Software, Linux for home or business that is your cup of tea - must help Dell sell this dream.&lt;/p&gt;

&lt;p&gt;The most obvious way to help is for bloggers or people with websites to display a prominent ad for Dell Linux boxes. Let&#39;s show Dell that by listening and embracing the Linux community that we can help them out. Each and everyone can be a partner to Dell and it is in everyone&#39;s interest that Linux market share grows. A bigger pie means that more hardware vendors will support Linux and having the Open Source desktop OS in the limelight will mean more development work for Open Source programmers. For consumers, it brings choice like they&#39;ve never had before - the modern day Linux OS thoroughly outshines it competitors. I do not make this comment lightly. But this week I got my first glimpse at the 3D accelerated desktop for Linux - it is incredible! It leaves Vista for dead. And comparing the two side-by-side there is only one winner.&lt;/p&gt;

&lt;p&gt;So let&#39;s help Dell sell Linux. I&#39;m going to be emailing them after the official announcement to get my Dell Linux ad. Never has marketing been such a pleasure! And never has the Linux Desktop looked so good!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>The Frogface Project Website Launched</title>
   <link href="http://www.theirishpenguin.com/2007/04/30/the-frogface-project-website-launched.html"/>
   <updated>2007-04-30T16:32:23+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/30/the-frogface-project-website-launched</id>
   <content type="html">&lt;p&gt;We&#39;ve tried to start this before and never quite finished it. You (edit: used to be able, this link is no longer available!) can check out the site at http://www.frogface.org This time things went smoothly, however I had to struggle through my hangover on Saturday while I polished off the final details. A big kudos to Veedles who did a smashing job creating the images and logo for the site - and now that she is the queen of web design is gonna spruce the site up even more over the coming weeks!&lt;/p&gt;

&lt;p&gt;(Note: Link to Frogface logo no longer available)&lt;/p&gt;

&lt;p&gt;The Frogface project is an effort to create a user friendly scuba dive logging application which runs on any computer. It&#39;s still not ready for everyday use so us developers will have to keep beavering away for a while. Things are going well recently as I escaped my horribly busy work schedule in order to get phase 1 of the project done. Ganesh is working on getting the menu&#39;s together over the coming weeks and I&#39;m gonna try and get my head around beautifying the user interface and making it look real pretty. As they say, &quot;There&#39;s more than one way to skin an app!&quot;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Elephant Dream - Art House Animation Extraordinaire</title>
   <link href="http://www.theirishpenguin.com/2007/04/29/elephant-dream-art-house-animation-extraordinaire.html"/>
   <updated>2007-04-29T09:56:21+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/29/elephant-dream-art-house-animation-extraordinaire</id>
   <content type="html">&lt;p&gt;Here&#39;s a superb 12 minute animation which features crisp industrial post-modern backdrops puncuated by expressively crafted chararcters; all done in Blender - an open source 3D modelling on the verge of the big time. It&#39;s a hefty download so you&#39;ll want a broadband connection, but it&#39;s worth the wait. Just sit back and simply enjoy these wonderful graphics  by visiting the download section at &lt;a href=&quot;http://orange.blender.org&quot;&gt;http://orange.blender.org&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Object Orientation and Javascript</title>
   <link href="http://www.theirishpenguin.com/2007/04/26/object-orientation-and-javascript.html"/>
   <updated>2007-04-26T11:58:28+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/26/object-orientation-and-javascript</id>
   <content type="html">&lt;p&gt;Javascript is muck; don&#39;t let anyone tell you otherwise. But it&#39;s also unavoidable. My latest effort to write better JS code is to use inheritance when creating classes and objects. So before I forget, I&#39;m posting these links - as they&#39;re pretty handy. Sounds like a lot of hassle for a bit of inheritance though!&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.ajaxpath.com/javascript-inheritance&quot;&gt;Very hardcore OO - but efficient&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm&quot;&gt;Again hardcore OO&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Linux Sound Problem: Nvidia nForce 430 and Asus M2NPV-VM</title>
   <link href="http://www.theirishpenguin.com/2007/04/20/linux-sound-problem-nvidia-nforce-430-and-asus-m2npv-vm.html"/>
   <updated>2007-04-20T20:08:31+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/20/linux-sound-problem-nvidia-nforce-430-and-asus-m2npv-vm</id>
   <content type="html">&lt;p&gt;This is just a quick post covering a sound problem I encountered when running OpenSuse 10.2 with Nvidia nForce 430 and Asus M2NPV-VM. The solution that worked for me is to open the /etc/modprobe.conf.local file and make sure it includes the options line below&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#
# please add local extensions to this file
#

options snd-hda-intel position_fix=1 model=3stack
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This did the job nicely. I found the solution &lt;a href=&quot;http://www.latenightpc.com/blog/archives/2006/11/10/sound-quirk-with-the-nvidia-nforce-430-and-asus-m2npv-vm/&quot;&gt;here&lt;/a&gt;, which has a lot more detail.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Installing the SMART Package Manager on OpenSuse 10.2 Linux</title>
   <link href="http://www.theirishpenguin.com/2007/04/20/installing-the-smart-package-manager-on-opensuse-102-linux.html"/>
   <updated>2007-04-20T19:33:33+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/20/installing-the-smart-package-manager-on-opensuse-102-linux</id>
   <content type="html">&lt;p&gt;Easy installing of software is the make-or-break aspect of any operating system. This is no different with Linux. Far and away, in my humble opinion, the best tool for this (on an rpm based system) is SMART. This quick post just overviews the steps I took to get it installed on my machine, as some of the instructions deviated from the &lt;a href=&quot;http://susewiki.org/index.php?title=SMART_Package_Manager&quot;&gt;SMART on Suse wiki&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I went into Suse&#39;s main configuration tool called YAST and checked made sure that the following were installed as pre-requisites
* python-xml
* python-elementtree
* rpm-python&lt;/p&gt;

&lt;p&gt;Then I went to the command line and typed&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;su
rpm -ihv http://ftp.skynet.be/pub/suser-guru/smart/10.2/i586/smart-latest.rpm&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This did the hard work of installing smart which then asked a series of questions as to what sources to use for installing software (called channels). I said yes to everything except any channels with KDE in the title as the KDE channels can contain &#39;developmental&#39; bleedin edge software which can destabilise your system (I wasn&#39;t sure if it was ok to say yes to the KDE-backports so I just err&#39;ed on the side of caution and said no).&lt;/p&gt;

&lt;p&gt;Then came the tricky bit - which is the reason I&#39;m writing this blog post - installing a user interface for SMART. This is because when I followed the instructions on the &#39;SMART on Suse wiki&#39; (ie. the above link) I typed&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;smart install smart-gui&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;but got the error...&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Computing transaction... error: Can&#39;t install smart-gui 0.50-1 guru.suse102@i686: no package provides python-gtk&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The fix for this is to install python-gtk the same way as the prerequisites (python-xml , python-elementtree, rpm-python) using YAST. I found this answer at the following &lt;a href=&quot;http://www.suseforums.net/index.php?s=45e9658b8fb46fe31d611f9f87b4f935&amp;amp;showtopic=27845&amp;amp;pid=148595&amp;amp;st=0&amp;amp;&quot;&gt;forum thread&lt;/a&gt;. Once that&#39;s complete type the following&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;smart install smart-gui&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;and agree to its demands. Here presto! You&#39;re done... and now have the easiest way to install software in town! To run SMART just type&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;sux -c &quot;smart --gui&quot;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;I was doing this on a 32 bit machine. If your architecture is different you might want to refer to the
SMART on Suse wiki, which also has a lot more detail on the powerful ways to configure and use this wonderful little program.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Use the Force to Fix Evil Vista’s Bootloader</title>
   <link href="http://www.theirishpenguin.com/2007/04/20/use-the-force-to-fix-evil-vistas-bootloader.html"/>
   <updated>2007-04-20T16:54:48+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/20/use-the-force-to-fix-evil-vistas-bootloader</id>
   <content type="html">&lt;p&gt;Hmmm... Those lovely folks at Microsoft are at it again. This time trying to break my lovely Linux system by killing my bootloader - the clever bit of software which lets you choose whether to boot into Linux or Windows. Cheers guys! You&#39;re real sweet!&lt;/p&gt;

&lt;p&gt;I bought my machine with Vista pre-installed with about 50 gig spare for Linux. I installed OpenSuse 10.2 into this space, which uses a little program called GRUB to switch between the Windows Vista and OpenSuse Linux when you start up the computer. Somehow Vista managed to overwrite this - I don&#39;t know how, as I installed Linux second, but anyway in order to fix you need to do the following&lt;/p&gt;

&lt;p&gt;1.) Get yourself a LIVE Linux CD (ie. a linux system that boots of a CD with requiring it be installed on your harddrive). I used the OpenSuse 10.2 Live CD
2.) Boot from this disk and then folllow the brief instructions at the following &lt;a href=&quot;http://ubuntuforums.org/showthread.php?t=224351&quot;&gt;link&lt;/a&gt;. Even though it outlines the process for Ubuntu (a different Linux distribution), it works just as well for OpenSuse 10.2&lt;/p&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Help Improve Computer User Interfaces…</title>
   <link href="http://www.theirishpenguin.com/2007/04/20/help-improve-computer-user-interfaces.html"/>
   <updated>2007-04-20T10:48:17+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/20/help-improve-computer-user-interfaces</id>
   <content type="html">&lt;p&gt;Here&#39;s a quick survey which you can fill in to help the OpenUsability project, which studies how you use a computer. The less you know the better as this study is especially interested in getting a broad cross section of the public to respond. It only takes a few minutes so why not give it a quick go!&lt;/p&gt;

&lt;p&gt;Link used to be at http://test.openusability.org/UCCASS/survey.php?sid=43 but is no longer available.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Bumblebee in Mobile Phone Horror</title>
   <link href="http://www.theirishpenguin.com/2007/04/16/bumblebee-in-mobile-phone-horror.html"/>
   <updated>2007-04-16T20:28:12+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/16/bumblebee-in-mobile-phone-horror</id>
   <content type="html">&lt;p&gt;To date mobile phones have been blamed for brain tumours, low sperm counts and making kids even more annoying on bus trips, but here is the latest to add to the list - serial bee killer...&lt;/p&gt;

&lt;p&gt;Bee colonies around the world have been mysteriously  disappearing over the last couple of years and apparently sticking a mobile phone phone in front of a hive is like sticking a AIDS patient in front of John Howard - they&#39;ll both run the other away screaming hysterically...&lt;/p&gt;

&lt;p&gt;No bees means no pollenation... and &lt;a href=&quot;http://news.independent.co.uk/environment/wildlife/article2449968.ece&quot;&gt;that&#39;s not good&lt;/a&gt;. I like apples.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Blair Government Throws UK Programmer to the Dogs of US Justice</title>
   <link href="http://www.theirishpenguin.com/2007/04/03/blair-government-throws-uk-programmer-to-the-dogs-of-us-justice.html"/>
   <updated>2007-04-03T21:45:13+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/03/blair-government-throws-uk-programmer-to-the-dogs-of-us-justice</id>
   <content type="html">&lt;p&gt;Gary McKinnon is a computer programmer who likes UFOs and rainy Sundays. Curiousity got the better of him so he went searching online for UFO conspiracy theorys and photos believing that the evidence to date suggests that US was hiding something Roswell style et al.  Not exactly a profile of a notorious threat to national US security yet. His curiosity brought him to various US military networks which he then found were remarkably easy to access given that apparently the username and password were the same in several cases and security was incredibly lax. He managed to find some folders containing pictures of nice shiny UFO-like things and got excited as his dream of seeing became a reality. Heart pumping he clicking on one of the files. As them image began to slowly come up on his screen his dream was cut short - one of the administrators had noticed him in the system and promptly cut him out...&lt;/p&gt;

&lt;p&gt;Needless to say, the US authorities were pretty pissed about the whole episode. The UFO equivalent of a trainspotter had managed to waltz around their systems like a kid in a candy store because aledgedly their administrators couldn&#39;t do their job properly. You would think that given the background to the case Gary would have been handed down a punishment apportionate to the crime - after all no one got hurt, no one was killed or maimed in the incident. It is alledged that some damage was done but Gary maintains that such allegations are false and in an article on .NET magazine outlines how the figures don&#39;t add up. Given the facts of the case to date and what Gary&#39;s motivations, it is unlikely that someone who wants to keep a low profile in a system to look around for information is going to go deleting files for the sake of damaging a system.&lt;/p&gt;

&lt;p&gt;So instead being given a big slap on the wrists, some UK jail time or 400 hours community service cleaning viruses of peoples computers Gary is being threatened with - get this - extradition to the US, a 45 year prison sentence to be served on US soil only and, worst of all, a possible handover to the US military trails. This latter point wouldn&#39;t be good, not only against the backdrop of Guantanamo bay and big orange jump suits, but because of &#39;alledged threats by the US authorities in New Jersey to see Gary &quot;fry&quot;, which could be a reference to the electric chair&#39;. &#39;Currently, the US civil legal authorities are not calling for the death penalty (which would stop the extradition to the USA under United Kingdom and European Union law), but such a penalty is possible if the case gets hijacked by a US Military Tribunal, once Gary is physically in the power of the US authorities.&#39; (&lt;a href=&quot;http://freegary.org.uk/&quot;&gt;http://freegary.org.uk&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;So our UFO trainspotter is in a bit of bother. It&#39;s sad then to hear yesterday that John Reid, UK home secretary, has given the green light to ship Gary McKinnon off to the US. He&#39;s already lost his job, girlfriend and has been in poor health in recent hearings as the stress of the case takes it&#39;s toll. He has never denied his actions and has taken responsibility for what he has done. He has already suffered enough. Will it really do any more good for the US to show how big and mighty it is by beating the soul out of this guy in order to show who&#39;s boss. It might be better to spend that energy on employing a few new system administrators who know how to put passwords on a system instead.&lt;/p&gt;

&lt;p&gt;This opinion piece was based in part on the following &lt;a href=&quot;http://news.bbc.co.uk/2/hi/uk_news/scotland/glasgow_and_west/6360917.stm&quot;&gt;BBC News item&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>EMI Heralds a Revolution in Online Music</title>
   <link href="http://www.theirishpenguin.com/2007/04/02/emi-heralds-a-revolution-in-music-freedom.html"/>
   <updated>2007-04-02T23:09:02+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/04/02/emi-heralds-a-revolution-in-music-freedom</id>
   <content type="html">&lt;p&gt;At last the fight against anti-consumer record labels crippling music purchased online is looking to be at an end. EMI have decided to make their songs sold on iTunes free of DRM (Digital Rights Management) - a technology which prevented users playing back their music on any device of their choice. This is probably one of the most important changes that could have happened in the delivery of online music and is set to transform the industry and reduce piracy. As EMI boss Eric Nicoli said,&lt;/p&gt;

&lt;p&gt;&quot;We have to trust our consumers. We have always argued that the best way to combat illegal traffic is to make legal content available at decent value and convenient.&quot;&lt;/p&gt;

&lt;p&gt;The new tracks will cost about 30 cent more per track. But the advantages of this greatly outweigh the cost increase and the tracks will also be of higher quality. In addition, customers who have already bought tracks will be given the option to pay the difference in price to make their entire existing collection DRM free.&lt;/p&gt;

&lt;p&gt;The move is set to put pressure on other labels to stop restricting consumers&#39; freedom to choose how to enjoy the music they&#39;ve purchased. A victory for choice, economics and anti-piracy in the music industry. This post is based on a news item on the BBC at the following &lt;a href=&quot;http://news.bbc.co.uk/2/hi/technology/6516189.stm&quot;&gt;link&lt;/a&gt;. So read more of the good news there. Here&#39;s to EMI taking a leading role in the music industry and setting the ball roling on the most important music issue today!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>AJAX - More than just a Toilet Cleaner - Not!</title>
   <link href="http://www.theirishpenguin.com/2007/03/29/ajax-more-than-just-a-toilet-cleaner-not.html"/>
   <updated>2007-03-29T12:22:56+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/03/29/ajax-more-than-just-a-toilet-cleaner-not</id>
   <content type="html">&lt;p&gt;Just to warn non-geeks, this is actually an article about programmin stuff so don&#39;t get too excited about replacing Toilet Duck just yet! This is just a rant...&lt;/p&gt;

&lt;p&gt;In short, my head is wrecked. After watching .NET mature into .NET 2.0 and now .NET 3.0, there&#39;s been loads of nice improvements. It&#39;s a pleasure to write code on the server with the latest C# additions, especially generics and partial classes. So with all thing clean tidy technology available on the server, it is thoroughly depressing that most (90%) of the time is spent writing code in bloody Javascript - possibly the worst language ever! Painstakingly, writing reams of rubbish which you must translate into different types of rubbish for different browsers. The best approach seems to be a James Joyce style &#39;Stream of Consciousness&#39; technique where you deprive yourself of sleep for a week, then grab your keyboard and type blindly away for 4 hours and then see what works at the end - preferably with a large vodka in one hand and a larger vodka in the other hand. Who on earth invented this spawn of satan language - which should just be turned off on every computer. We need a revolution! Somebody please write a client side C# implementation.&lt;/p&gt;

&lt;p&gt;Otherwise the vodka wins...&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Slaps on the Backs All Round</title>
   <link href="http://www.theirishpenguin.com/2007/03/11/slaps-on-the-backs-all-round.html"/>
   <updated>2007-03-11T10:04:34+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/03/11/slaps-on-the-backs-all-round</id>
   <content type="html">&lt;p&gt;A big congratulations goes to Sun Microsystems, who have finally open sourced Java - under the GPL, if you don&#39;t mind. This is the move that will finally stop me criticising them so I&#39;ll shut up now. In addition, they&#39;ve very kindly given me permission to use their Joint Copyright Agreement for my Frogface project (just thought I&#39;d plug that one again!) which is ticking along nicely on www.sourceforge.net/projects/frogface&lt;/p&gt;

&lt;p&gt;Man of the moment is Ganesh, who&#39;s managed to submit the first non-me patch to the Frogface codebase and, along with all the other Frogface developers, has demonstrated great patience as the project gets up on its feet!&lt;/p&gt;

&lt;p&gt;Finally, a big shout goes out to Vee who&#39;s working her little socks off studying at the moment. All she&#39;s missing is the hang&#39;n&#39;cheese sandwiches to complete the student lifestyle - mainly cause she doesn&#39;t have the time to make them!!!&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Money Can’t Buy You Love, And Gift Cards Can’t Buy You An Apple</title>
   <link href="http://www.theirishpenguin.com/2007/03/05/money-cant-buy-you-love-and-gift-cards-cant-buy-you-an-apple.html"/>
   <updated>2007-03-05T10:22:24+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/03/05/money-cant-buy-you-love-and-gift-cards-cant-buy-you-an-apple</id>
   <content type="html">&lt;p&gt;You would think that if you or your friends lined Apple Computer&#39;s coffers buy purchasing a load of Apple gift cards off them that the least they could do is let you easily trade in those gift cards for a purchase. Well, maybe not. Here&#39;s another story that shows how customer friendly the big Apple is.&lt;/p&gt;

&lt;p&gt;Which is pretty much about as friendly as I&#39;ve ever found Apple&#39;s customer service. Here&#39;s the skinny on &lt;a href=&quot;http://consumerist.com/2008/03/apple-still-wont-sell-you-a-computer-because-youve-got-too-many-gift-cards.html&quot;&gt;&lt;strong&gt;&lt;em&gt;TheConsumerist.com&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Frogface - Open Source Dive Log Project Launched</title>
   <link href="http://www.theirishpenguin.com/2007/01/17/frogface-open-source-dive-log-project-launched.html"/>
   <updated>2007-01-17T10:18:40+00:00</updated>
   <id>http://www.theirishpenguin.com/2007/01/17/frogface-open-source-dive-log-project-launched</id>
   <content type="html">&lt;p&gt;After spending a good bit of time scuba diving the shores of Asia and Australia, it was time to combine some geek powers with underwater prowess - and Frogface was born! - a free software scuba dive log.&lt;/p&gt;

&lt;p&gt;The idea first struck me when I was out on a dive with a nice Dutch girl called Leanne at Perhentian islands. We came across two Lionfish getting it on in some sort of fight or mating ritual. A bit like humans, sometimes you can&#39;t tell the difference! So we hung there at 15 metres for 15 minutes until our air ran out and I thought, &quot;Wouldn&#39;t it be nice to have a good dive log tool for Linux, Mac and Windows boxes to write my story.&quot; A dive log that was more focused on recording the cool stuff one sees on a dive than what my deco time was exactly one minute and thirty seconds into a dive! Generally, divers say things more like &quot;What a cool nudibranch!&quot; and look for a big fat book to try and identify their new favourite found sea slug rather than &quot;What is the gaussian distribution of my dive depths when the co-variance due to wave height is normalised?&quot; (I have no idea of what the last sentence means - you&#39;ve caught me out, I made it up!). Unfortunately, most dive logs I&#39;ve seen seem to be more focused on the latter question.&lt;/p&gt;

&lt;p&gt;What will be the outcome of this bastard child of C++/QT4 and XML will be? Who knows! My initial goals for it is to get it stable, easy to use ease and add the basic features one would expect from a dive log. It shouldn&#39;t take too long to realise this as work is already well underway. Dives can be logged, dive locations added and a user profile can be created. What I&#39;d really like to get done next is getting things like dive buddy lists working and working toward the first stable release. Once that&#39;s achieved, we can really try to &quot;enhance the users logging experience&quot; - which sounds a bit like corporate mission statement for a toilet...&lt;/p&gt;

&lt;p&gt;You can get the code from SourceForge.net at &lt;a href=&quot;http://sourceforge.net/projects/frogface&quot;&gt;Frogface project on SourceForge&lt;/a&gt;. If you&#39;re interested in this kind of project, you could do worse than help out. We&#39;re always on the lookout for people - from your regular joe websurfer who might give Frogface a go and send feedback to elite hackers who can churn out C++ code quicker than you can say &quot;Watch out! Whale Shark!&quot;&lt;/p&gt;

&lt;p&gt;In any case, it should be fun to give this a project go and if it doesn&#39;t work out we can always quit and go diving!&lt;/p&gt;
</content>
 </entry>
 
 
</feed>