<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;C08ARHg7cCp7ImA9WxNUF0U.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287</id><updated>2009-11-09T15:50:45.608Z</updated><title>3spoken</title><subtitle type="html">Honest opinions - freely given</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><link rel="self" href="http://feeds.feedburner.com/3spoken" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;DEUNRXs7eyp7ImA9WxNQFk0.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-6245351572193993960</id><published>2009-09-22T08:56:00.001+01:00</published><updated>2009-09-22T08:58:14.503+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-22T08:58:14.503+01:00</app:edited><title>The value of University Education - is it a myth?</title><content type="html">&lt;span class="Apple-style-span" style="font-family: monospace; font-size: 13px; white-space: pre-wrap; "&gt;I doubt that the increase in University places translates into 'better jobs' for the majority - regardless of the truth by repeated assertion spouted by the government, Universities and so called business leaders.  What we are creating here is a system where ordinary individuals pay for their own apprenticeships so that business can bank the profits.  Very simply if University was such a good investment that the majority would get a much higher paid job because of it, then it would make sense for the Government to invest in it fully - because it would get much more back in increased taxes later on from the higher wages earned.  Apparently we can borrow billions to bail out bankers, but when it comes to investing in the future skills of the country we can't afford it.  The current system and the proposal is essentially another tax rise by stealth using a straightforward front loading mechanism.  Why not just put an additional income tax band in at the income level of a 'graduate job' and have done with it?&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-6245351572193993960?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/6245351572193993960/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=6245351572193993960" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6245351572193993960?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6245351572193993960?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2009/09/value-of-university-education-is-it.html" title="The value of University Education - is it a myth?" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkYBRXc8eSp7ImA9WxNTFE4.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-1621743314619202011</id><published>2009-08-16T14:31:00.004+01:00</published><updated>2009-08-16T14:42:34.971+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-16T14:42:34.971+01:00</app:edited><title>How to get HDMI sound out of a Radeon Device in Ubuntu Karmic</title><content type="html">After much searching of the Interweb I've managed to get sound out of my TV when connected to my Acer Aspire 5536 via HDMI.&lt;br /&gt;&lt;br /&gt;It turns out that Ubuntu Karmic has full support on the Audio side for the sound part of the RS780 chipset. Pulseaudio picks it up and the new volume control lets you select the output effortlessly.&lt;br /&gt;&lt;br /&gt;Unfortunately the Radeon Video driver that Ubuntu uses by default doesn't support 'HDMI Sound pass through', so the bits never get to the TV.&lt;br /&gt;&lt;br /&gt;Fortunately there another Radeon driver - 'radeonhd' and that does have HDMI sound support, but it doesn't detect it automatically so you have to configure it in the good old 'xorg.conf'.&lt;br /&gt;&lt;br /&gt;To get the driver, first make sure you have the 'universe' repository activated and then install the driver via apt.&lt;br /&gt;&lt;pre&gt;apt-get install xserver-xorg-video-radeonhd&lt;/pre&gt;&lt;br /&gt;and then edit /etc/X11/xorg.conf to add in the following:&lt;br /&gt;&lt;pre&gt;&lt;p&gt;Section "Device"&lt;br /&gt;      Identifier      "ATI Radeon HD 3200/RS780"&lt;br /&gt;      Driver          "radeonhd"&lt;br /&gt;      Option          "DRI" "On"&lt;br /&gt;      Option          "Audio" "On"&lt;br /&gt;      Option          "HDMI"  "all"&lt;br /&gt;EndSection&lt;/p&gt;&lt;p&gt;Section "DRI"&lt;br /&gt;      Mode 0666&lt;br /&gt;EndSection&lt;/p&gt;&lt;/pre&gt;&lt;br /&gt;(Change the Identifier as required so that it ties in with the rest of the configuration).&lt;br /&gt;&lt;br /&gt;The DRI Option activated direct rendering, which again doesn't active by default for certain chipsets. The DRI section allows non-privileged commands to access direct rendering.&lt;br /&gt;&lt;br /&gt;Details of the options and default are on the radionhd manual page that is installed alongside the driver.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-1621743314619202011?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/1621743314619202011/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=1621743314619202011" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1621743314619202011?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1621743314619202011?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2009/08/how-to-get-hdmi-sound-out-of-radeon.html" title="How to get HDMI sound out of a Radeon Device in Ubuntu Karmic" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;DE4MR3Y8eip7ImA9WxJaF0Q.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-1881736131030777050</id><published>2009-08-09T06:34:00.006+01:00</published><updated>2009-08-09T06:49:46.872+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-09T06:49:46.872+01:00</app:edited><title>Making Wine sound work with PulseAudio on Ubuntu - properly</title><content type="html">Wine sounds in Ubuntu has had a problem for a while now since they introduced to PulseAudio sound server. There are a lot of kludgy workarounds on the Internet that will get the sound working for one particular application, but the side effect is that it stops it working for everything else. And you lose pulseaudio's ability to move sound streams between sound cards and sound servers.&lt;br /&gt;&lt;br /&gt;There is a way of fixing it properly, and that is to run a version of Wine with a native Pulseaudio driver installed. The code exists, but due to the politics of Open Source it hasn't been included in the main upstream codebase.&lt;br /&gt;&lt;br /&gt;Since I can't stand kludgy workarounds I decided to take it upon myself to create a wine package with the pulseaudio driver in place and now that is available on my PPA.&lt;br /&gt;&lt;br /&gt;It is targeted at the Karmic Koala release, which contains the required version of PulseAudio. Can I ask all those currently testing the new Ubuntu release to try out the package and see if it improves matter for you. Everybody else will have to wait until October :)&lt;br /&gt;&lt;br /&gt;If you do try out the software can you report back your experiences in Launchpad&lt;br /&gt;&lt;br /&gt;&lt;a href="https://bugs.launchpad.net/wine/+bug/371897"&gt;https://bugs.launchpad.net/wine/+bug/371897&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The more data we collect, the more evidence we have that this should be included in Ubuntu as standard. And of course if you have problems I can work with upstream to get them sorted.&lt;br /&gt;&lt;br /&gt;You can install the software from my PPA&lt;br /&gt;&lt;br /&gt;&lt;a href="https://launchpad.net/%7Eneil-aldur/+archive/ppa"&gt;https://launchpad.net/~neil-aldur/+archive/ppa&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To install the software follow the instructions on Launchpad (&lt;a href="https://help.launchpad.net/Packaging/PPA/InstallingSoftware"&gt;https://help.launchpad.net/Packaging/PPA/InstallingSoftware&lt;/a&gt;)&lt;br /&gt;&lt;a href="http://art.ified.ca/?page_id=40"&gt;&lt;br /&gt;Read more about the Winepulse patches and why they're not in the mainline&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-1881736131030777050?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/1881736131030777050/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=1881736131030777050" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1881736131030777050?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1881736131030777050?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2009/08/making-wine-sound-work-with-pulseaudio.html" title="Making Wine sound work with PulseAudio on Ubuntu - properly" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total></entry><entry gd:etag="W/&quot;Ak4BQXY6eSp7ImA9WxJbGU4.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-7649523198282900182</id><published>2009-07-30T08:12:00.007+01:00</published><updated>2009-07-30T08:29:10.811+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-30T08:29:10.811+01:00</app:edited><title>EULA and cars - an analogy</title><content type="html">&lt;div&gt;Let's say that you've just bought a shiny new car. It's your pride and joy, and you've spent weeks researching the market just to find the perfect model. You've been to the showroom; you've grimaced at the lousy 'complimentary' coffee and you've shook hands and laid out your hard-earned. After waiting what seems like an eternity it's pick up day.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;So you're stood there with the new car gleaming in front of you and you're itching to get in and hear the roar of the engine. The salesman is there with the keys and you reach out your trembling hand to take them...&lt;/div&gt;&lt;br /&gt;&lt;div&gt;However the saleman then says:&lt;/div&gt;&lt;br /&gt;&lt;div&gt;"Before I allow you to use this car, you must agree to these terms&lt;/div&gt;&lt;br /&gt;&lt;div&gt;(i) you can't sell it on to anybody else&lt;/div&gt;&lt;br /&gt;&lt;div&gt;(ii) whenever you drive it, it can transmit its location and what music you're listening to on the radio to a central location and they can use that information for whatever they like.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;(iii) and you must come back here for warranty and services and not go anywhere else&lt;/div&gt;&lt;br /&gt;&lt;div&gt;If you don't agree to these terms then you musn't use the key to start the car and you need to go to talk to the manufacturer about a refund"&lt;/div&gt;&lt;br /&gt;&lt;div&gt;And then he walks off leaving the keys in a locked box with a button on it marked 'I accept the terms".&lt;/div&gt;&lt;br /&gt;&lt;div&gt;You wouldn't stand for that. You'd explode with rage. You never agreed to those terms when you laid out your money. How dare they. You'd be onto trading standards in a flash. You'd demand that the retailer drops those terms instantly.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;So why do you meekly accept this situation when you buy an operating system to run on a computer?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-7649523198282900182?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/7649523198282900182/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=7649523198282900182" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7649523198282900182?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7649523198282900182?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2009/07/eula-and-cars-analogy.html" title="EULA and cars - an analogy" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUYCQHY_fSp7ImA9WxJbGU4.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-6785468647248482273</id><published>2009-07-30T07:39:00.005+01:00</published><updated>2009-07-30T07:59:21.845+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-30T07:59:21.845+01:00</app:edited><title>Getting your Microsoft Windows Tax back from Amazon - it's not all plain sailing.</title><content type="html">Based on the encouraging exploits of &lt;a href="http://www.theopensourcerer.com/2009/07/21/getting-your-microsoft-tax-refunded-1010-for-amazon-uk/"&gt;The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Opensourcerer&lt;/span&gt;&lt;/a&gt; in getting a Windows refund from Amazon I thought I'd have a go at getting a refund as well for the copy of Windows on my new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Acer&lt;/span&gt; Aspire 5536 machine (which definitely does have &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;VM&lt;/span&gt; capability 'cos I've checked the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;cpuflags&lt;/span&gt;).&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;quitely&lt;/span&gt; confident that Amazon had adopted a sensible refund position in accordance with the law of the land. And so I sent off my email in the same manner that The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Opensourcerer&lt;/span&gt; had done expecting it to be sorted in minutes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately it hasn't turned out like that and after several frustrating exchanges I ended up with this.&lt;br /&gt;&lt;blockquote&gt;We are not in a position to offer a partial refund for this product. You can of course return the laptop to us for a full refund if you wish.&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;So it seems I must turn to the law of the land and enforce those mystical 'statutory rights' that you see mentioned in every retail establishment.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The next few posts will describe what I believe is the statutory basis for recovering the cost of Windows and the result of my discussions with Amazon will determine whether I'm right or not.&lt;br /&gt;&lt;br /&gt;We shall see.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-6785468647248482273?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/6785468647248482273/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=6785468647248482273" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6785468647248482273?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6785468647248482273?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2009/07/getting-your-microsoft-windows-tax-back.html" title="Getting your Microsoft Windows Tax back from Amazon - it's not all plain sailing." /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total></entry><entry gd:etag="W/&quot;AkIESXs4eip7ImA9WxVSF0Q.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-7759630376734798416</id><published>2009-01-12T21:59:00.003Z</published><updated>2009-01-12T22:15:08.532Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-12T22:15:08.532Z</app:edited><title>Extracting CDs as WAV files with Rhythmbox</title><content type="html">For future reference. Doc for Ubuntu 8.10 (Intrepid Ibex)&lt;br /&gt;&lt;br /&gt;Edit | Preferences. Click Edit Button on 'Preferred Format'.&lt;br /&gt;&lt;br /&gt;Click New. Enter 'CD Quality, Raw' and click Create.&lt;br /&gt;&lt;br /&gt;Edit 'CD Quality, Raw' and put&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;audio/x-raw-int,rate=44100,channels=2 ! wavenc name=enc&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;in the Gstreamer pipeline and click 'active'.&lt;br /&gt;&lt;br /&gt;Close down the Preference Windows and Rhythmbox then restart it.&lt;br /&gt;&lt;br /&gt;You can now select 'CD Quality, Raw' as the menu type.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Why do this? You get the WAV files in your Music directory with the correct titles and they transfer across to Windows a bit easier than FLAC.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-7759630376734798416?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/7759630376734798416/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=7759630376734798416" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7759630376734798416?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7759630376734798416?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2009/01/extracting-cds-as-wav-files-with.html" title="Extracting CDs as WAV files with Rhythmbox" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;Ck8ARnc9eip7ImA9WxRREkg.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-3709825799197443628</id><published>2008-09-24T09:32:00.008+01:00</published><updated>2008-09-24T11:07:27.962+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-09-24T11:07:27.962+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tax" /><category scheme="http://www.blogger.com/atom/ns#" term="ir35" /><title>Freelancers - you will be assimilated. Resistance is futile.</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_tCoIrwRl6js/SNoQzkzNElI/AAAAAAAAAAc/pz1my0n7RY4/s1600-h/166630759_b9ccde043b_m.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_tCoIrwRl6js/SNoQzkzNElI/AAAAAAAAAAc/pz1my0n7RY4/s200/166630759_b9ccde043b_m.jpg" alt="" id="BLOGGER_PHOTO_ID_5249526793891549778" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The plot to ensure that everybody becomes an employee of some large organisation (preferably the state) for their 'protection' gathered pace this month. If the announcement that Economic Work Units (aka mothers) are to be required to hand their 2 year olds over to some state sponsored indoctrination centre wasn't enough, there was the disappointing, but largely inevitable, result on the IR35 'Dragonfly' case.&lt;br /&gt;&lt;br /&gt;Once again Freelancers are going to have to look closely at the way they operate and review their relationships with clients if they don't want a 'a-posteriori' bill from HMRC.&lt;br /&gt;&lt;br /&gt;Conspiracy theorists will have enough to go on at this point. Thanks for reading. Those of you who want the details - read on.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The New Rules&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I won't go into the gory details. There is plenty of analysis elsewhere: the best being:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.egos.co.uk/ir35_cases/Dragonfly.htm"&gt;Dragonfly appeal&lt;/a&gt; by Roger Sinclair at &lt;a href="http://www.egos.co.uk/"&gt;Egos&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.accountingweb.co.uk/cgi-bin/item.cgi?id=188332"&gt;Dragonfly shot down in cold blood&lt;/a&gt; by Steve Gratton on &lt;a href="http://www.accountingweb.co.uk/"&gt;AccountingWeb&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What the new 'clarification' boils down to is this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;if you do work for somebody and get paid for it that is enough to to satisfy one condition of being an IR35 employee. You are essentially assessed against a Day Casual Worker and not a Full Time Employee.&lt;/li&gt;&lt;li&gt;That you determine what and how (and probably where in these days of homeworking) the work is done is no longer sufficient. You have to have the right to do more than a similarly qualified professional employee would ever be allowed to do.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;if you allow yourself to become part of the furniture you will become an IR35 employee regardless of what is written in any documents.&lt;/li&gt;&lt;li&gt;intention is nothing: perception is everything; what the client employees see you as is probably definitive.&lt;/li&gt;&lt;/ul&gt;IR35 has become a 'Duck Tax', to slightly mangle that wonderful Ruby term. Arguably that is as it should be. So your tax bill may very well be determined by client employees terrified of an HMRC investigation into them. Bear that in mind in how you allow them to treat you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-3709825799197443628?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/3709825799197443628/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=3709825799197443628" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/3709825799197443628?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/3709825799197443628?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/09/freelancers-you-will-be-assimilated.html" title="Freelancers - you will be assimilated. Resistance is futile." /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_tCoIrwRl6js/SNoQzkzNElI/AAAAAAAAAAc/pz1my0n7RY4/s72-c/166630759_b9ccde043b_m.jpg" height="72" width="72" /><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;CkYNQ3g_eyp7ImA9WxZaGUw.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-1127779657396379702</id><published>2008-05-04T15:02:00.004+01:00</published><updated>2008-05-04T15:09:52.643+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-05-04T15:09:52.643+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Upgraded to Hardy</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ubuntu.com/themes/ubuntu07/images/masthead-cds.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://www.ubuntu.com/themes/ubuntu07/images/masthead-cds.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Well I've taken the plunge and upgraded my laptop to the 8.04 Ubuntu release (Hardy Heron). Overall the process was very smooth. There are some minor irritations with the way the wireless network works. (To do with the move from the binary ipw3945 driver to the open ipl3945 driver) and a trivial problem with my ML-1610 printer that simply required reselection of the driver to update the appropriate PPD. Other than that I'm here on Firefox 3, printing happily and transmitting over a secure wireless connection and generally enjoying life.&lt;br /&gt;&lt;br /&gt;The main reason for upgrading was so I can show presentations on an external screen, and so I can use submodules in git (both in Hardy, but not Gutsy). We'll see if any more irritations pop up over the next few days. However so far, so good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-1127779657396379702?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/1127779657396379702/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=1127779657396379702" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1127779657396379702?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1127779657396379702?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/05/upgraded-to-hardy.html" title="Upgraded to Hardy" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CkUNQnozcCp7ImA9WxZbFkQ.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-7743769296542255019</id><published>2008-04-20T11:47:00.004+01:00</published><updated>2008-04-20T12:18:13.488+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-20T12:18:13.488+01:00</app:edited><title>Dilbert - probably the worst site redesign of all time.</title><content type="html">If you've been to the Dilbert site (&lt;a href="http://dilbert.com/"&gt;http://dilbert.com&lt;/a&gt;) recently you'll notice that they have redesigned it so that it has new features. Unfortunately while getting excited about all the new website toys they have completely forgotten about usability.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Faux pas include&lt;br /&gt;&lt;ul&gt;&lt;li&gt;having to scroll the Sunday strip (can you spot the arrow?)&lt;/li&gt;&lt;li&gt;Forcing the Sunday 8 box strip into 3 box format. &lt;/li&gt;&lt;li&gt;No way of easily getting to the previous or next strip without going through search.&lt;/li&gt;&lt;li&gt;Completely pointless flash tool&lt;/li&gt;&lt;li&gt;Even more pointless flash menu&lt;/li&gt;&lt;li&gt;Chewing the CPU&lt;/li&gt;&lt;li&gt;Crashes frequently on Ubuntu and IE 6 if you flip screens&lt;/li&gt;&lt;li&gt;Busy, busy screen.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It works so much better if you turn Javascript off.&lt;/p&gt;&lt;p&gt;Fortunately there is a workaround. Just look at the strips on Yahoo instead &lt;a href="http://news.yahoo.com/comics/dilbert"&gt;http://news.yahoo.com/comics/dilbert&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Oh and make a note never to hire the guys at &lt;a href="http://vpi.net/"&gt;vpi.net&lt;/a&gt; if you want a site that people can use on anything less than the latest Redmond specified supercomputer.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-7743769296542255019?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/7743769296542255019/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=7743769296542255019" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7743769296542255019?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7743769296542255019?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/04/dilbert-probably-worst-site-redesign-of.html" title="Dilbert - probably the worst site redesign of all time." /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;C0EDQ305eSp7ImA9WxZUGU8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-8505482588456475009</id><published>2008-04-11T14:27:00.007+01:00</published><updated>2008-04-11T14:47:52.321+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-11T14:47:52.321+01:00</app:edited><title>Rake quick tip - Getting your dates out into the right format</title><content type="html">Rails date formatting leaves a bit to be desired with only a few formats available. You can of course use strftime in all it's glory:&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span class="ident"&gt;my_record&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;created_at&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;strftime&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;%d-%b-%y&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;but it is hardly descriptive.&lt;br /&gt;&lt;br /&gt;So there are a couple of ways of getting dates to format as you want them in Rails. The first is to set your own key in the date format table, and select it explicitly.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;DATE_FORMATS&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:uk&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;%d-%b-%y&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;my_record&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;created_at&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:uk&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;But if you want this date format all the time, just overwrite the &lt;code&gt;:default&lt;/code&gt; key. Then &lt;code&gt;to_s&lt;/code&gt; will use your format by default.&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span class="constant"&gt;Time&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;DATE_FORMATS&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:default&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;%d-%b-%y&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;my_record&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;created_at&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;I stick the command in the &lt;code&gt;ApplicationHelper&lt;/code&gt;. It's always a global change.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-8505482588456475009?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/8505482588456475009/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=8505482588456475009" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8505482588456475009?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8505482588456475009?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/04/rake-quick-tip-getting-your-dates-out.html" title="Rake quick tip - Getting your dates out into the right format" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DkEHRX4yfSp7ImA9WxZUGEw.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-221524795693370292</id><published>2008-04-10T08:11:00.006+01:00</published><updated>2008-04-10T09:03:54.095+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-10T09:03:54.095+01:00</app:edited><title>Rails and git - clean branch and merge</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm3.static.flickr.com/2021/1516857444_a84038b416_o_d.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px;" src="http://farm3.static.flickr.com/2021/1516857444_a84038b416_o_d.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I've moved over to git recently to take advantage of the new distributed functionality and the various git repository engines that are springing up in the Rails world.&lt;br /&gt;&lt;br /&gt;One of the beauties of the new git regime is that creating and deleting test branches of your application is an absolute doddle. For every iteration you simply&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;neil@neil-laptop:~/test_git$ git checkout -b new_branch&lt;br /&gt;Switched to a new branch "new_branch"&lt;br /&gt;neil@neil-laptop:~/test_git$ *change something*&lt;br /&gt;neil@neil-laptop:~/test_git$ git commit -a -m "let's try this"&lt;br /&gt;Created commit cb3200f: let's try this&lt;br /&gt; 1 files changed, 0 insertions(+), 59 deletions(-)&lt;br /&gt;neil@neil-laptop:~/test_git$ *add something else*&lt;br /&gt;neil@neil-laptop:~/test_git$ git add .; git commit -a -m "That didn't work,&lt;br /&gt;let's try something else"&lt;br /&gt;Created commit 0c5f35e: That didn't work, let's try something else&lt;br /&gt; 1 files changed, 144 insertions(+), 0 deletions(-)&lt;br /&gt; create mode 100644 FOOBAR&lt;br /&gt;neil@neil-laptop:~/test_git$ *change something again*&lt;br /&gt;neil@neil-laptop:~/test_git$ git commit -a -m "Now we've cracked it"&lt;br /&gt;Created commit 3876936: Now we've cracked it&lt;br /&gt; 1 files changed, 0 insertions(+), 144 deletions(-)&lt;br /&gt; delete mode 100644 FOOBAR&lt;br /&gt;neil@neil-laptop:~/test_git$ &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Which gives you a nice branch with your shiny new functionality in it, but all the hacks and changes are in the log file.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;neil@neil-laptop:~/test_git$ git-log --pretty=oneline master..HEAD&lt;br /&gt;3876936d77f6963a5db461fbc013059c84a5e480 Now we've cracked it&lt;br /&gt;0c5f35e7a0386698e57eab0791f5897cb44a0266 That didn't work, let's try something e&lt;br /&gt;cb3200fd16de9bf4a14cbdba1a8abcfa0fcfeb71 let's try this&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And that means when you merge down all those log entries get merged as well&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;neil@neil-laptop:~/test_git$ git checkout try_merge&lt;br /&gt;Switched to branch "try_merge"&lt;br /&gt;neil@neil-laptop:~/test_git$ git merge new_branch&lt;br /&gt;Updating 1b63b7d..3876936&lt;br /&gt;&lt;br /&gt;Fast forward&lt;br /&gt; FRED   |  144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++&lt;br /&gt; README |   59 --------------------------&lt;br /&gt; 2 files changed, 144 insertions(+), 59 deletions(-)&lt;br /&gt; create mode 100644 FRED&lt;br /&gt;neil@neil-laptop:~/test_git$ git branch -d new_branch&lt;br /&gt;Deleted branch new_branch.&lt;br /&gt;neil@neil-laptop:~/test_git$ git-log --pretty=oneline master..HEAD&lt;br /&gt;3876936d77f6963a5db461fbc013059c84a5e480 Now we've cracked it&lt;br /&gt;0c5f35e7a0386698e57eab0791f5897cb44a0266 That didn't work, let's try something &lt;br /&gt;6182c9866e6f4972eb74e873f5d9eff1dd0a272d That didn't work try something else&lt;br /&gt;cb3200fd16de9bf4a14cbdba1a8abcfa0fcfeb71 let's try this&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now recording your twists and turns for posterity probably isn't what you'd want to do. Fortunately there is an alternative. Let's do that again.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;neil@neil-laptop:~/test_git$ git checkout try_merge&lt;br /&gt;Switched to branch "try_merge"&lt;br /&gt;neil@neil-laptop:~/test_git$ git-merge &lt;b&gt;--squash&lt;/b&gt; new_branch&lt;br /&gt;Updating 1b63b7d..766208c&lt;br /&gt;&lt;br /&gt;Fast forward&lt;br /&gt;Squash commit -- not updating HEAD&lt;br /&gt; README |   31 -------------------------------&lt;br /&gt; 1 files changed, 0 insertions(+), 31 deletions(-)&lt;br /&gt;neil@neil-laptop:~/test_git$ git commit -a -m 'Shiny new functionality as if by magic'&lt;br /&gt;Created commit 2940a71: Shiny new functionality as if by magic&lt;br /&gt; 1 files changed, 0 insertions(+), 31 deletions(-)&lt;br /&gt;neil@neil-laptop:~/test_git$ git-log --pretty=oneline master..&lt;br /&gt;2940a71686d0c618bf39c17d3dd12c8ee02248d7 Shiny new functionality as if by magic&lt;br /&gt;neil@neil-laptop:~/test_git$ &lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now all the twists and turns of your test branch are banished from history and you can pretend you created the perfect solution first time :-)&lt;br /&gt;&lt;br /&gt;The one wrinkle is that you have to force delete the test branch. If you do a normal delete it complains&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;neil@neil-laptop:~/test_git$ git branch -d new_branch&lt;br /&gt;error: The branch 'new_branch' is not a strict subset of your current HEAD.&lt;br /&gt;If you are sure you want to delete it, run 'git branch -D new_branch'.&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;However if you take the advice all is well&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;br /&gt;neil@neil-laptop:~/test_git$ git branch -D new_branch&lt;br /&gt;Deleted branch new_branch.&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;Git makes it really simple to launch a branch for every iteration you undertake and allows you to keep your mainline commit sequence clean.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-221524795693370292?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/221524795693370292/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=221524795693370292" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/221524795693370292?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/221524795693370292?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/04/rails-and-git-clean-branch-and-merge.html" title="Rails and git - clean branch and merge" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUcNQnk-eip7ImA9WxZVGUs.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-1142950619481043111</id><published>2008-03-31T13:28:00.003+01:00</published><updated>2008-03-31T13:38:13.752+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-31T13:38:13.752+01:00</app:edited><title>Rails Patch accepted!</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm1.static.flickr.com/17/21367593_c03780d433_m_d.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://farm1.static.flickr.com/17/21367593_c03780d433_m_d.jpg" alt="" border="0" /&gt;&lt;/a&gt;I came across a &lt;a href="http://dev.rubyonrails.org/ticket/11421"&gt;Rails problem&lt;/a&gt; last week while writing the VAT validation plugin. So based on the open source principle of 'he who finds fixes' I submitted a patch, and it has been &lt;a href="http://dev.rubyonrails.org/changeset/9115"&gt;accepted!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's nice to be part of the process.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-1142950619481043111?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/1142950619481043111/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=1142950619481043111" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1142950619481043111?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/1142950619481043111?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/03/rails-patch-accepted.html" title="Rails Patch accepted!" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CUcMQ3Yyeyp7ImA9WxZUEEo.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-7495894045067519925</id><published>2008-03-29T08:16:00.015Z</published><updated>2008-04-01T19:04:42.893+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-01T19:04:42.893+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="thevisionthing" /><title>Why IT is perennially irritating - and what we can do about it</title><content type="html">The levee of early adoption has been breached and the sea of banality is flooding in. It has been for a while, but now &lt;a href="http://visionthing.vagueware.com/"&gt;some of the pioneers&lt;/a&gt; are starting to notice a bit of a smell.&lt;br /&gt;&lt;br /&gt;Is it that Web 2.0 has matured like a fine, but overly strong, stilton and is ready to take its place next to dotcom, client-server, outsourcing, windows, PC terminals, 4GLs and probably several others I've forgotten in the pantheon of IT panaceas.&lt;br /&gt;&lt;br /&gt;I'm not sure whether I'm fortunate or unfortunate to have seen this process happen several times. Certainly it is very disheartening to see it happen all over again. But that is the way the economics of this business works - as it does for all service businesses. And that's due to a number of factors as I see it&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The customer and the consumer are very often, if not always, different people. You are writing the software for the person who wants 'Ebay with knobs on' and only superficially for the person who is going to use it. The marketing fluff builds to get the customer to sign. Delivery becomes a matter of doing the minimum possible to get the customer to sign the thing off and pay.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Nobody knows if you are any good or not. So customers don't go for the best solution, they go for the one with the least perceived risk. You reduce perceived risk by fluffing up your marketing - hire more PhDs to sit in a corner and twiddle their thumbs, up the impressive graphics, work on your brand, give lots of slick superficial presentations and bridge away from the difficult questions to "The Big Picture (tm)". To pay for this you cut corners at the back-end where nobody will look. After all you will have sold out before the first power cut won't you.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Your 'tool' is not as good as you think it is and frankly nobody but you gives a monkeys about it. Why are you so sure it can't be replicated by a keen script-kiddy in a couple of weekends? And if it can, why do you think you have a sustainable business charging £10 per month for the privilege? Fancy graphics? Force of ego?&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Most of the 'tools' out there are largely superficial. I got into this game to make people's lives easier by automating and eliminating drudgery. Yet the tools created seem to turn people either into Mrs Doyle ("some of us like drudgery"), or human versions of Pavlov's dogs - desperately waiting for the next IM or twitter to give meaning to their existence.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;Andy Mitchell makes the points well in &lt;a href="http://3dogsbark.com/2008/03/27/the-vision-thing-10-reasons-i-hate-where-the-web-is-at/"&gt;his blog post &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However the most insidious problem IMHO is The Flip - the standard way of investment and detailed in exquisite form &lt;a href="http://www.manojranaweera.com/2008/03/22/methodology-for-launching-under-25000/"&gt;here&lt;/a&gt;. Capitalism is driven by those who own the capital, and the bottom line is if you have an external investor then you work for them and they are looking for a profit on the sale of your business - quickly. To quote "The business must be able to generate significant value within 2 years to provide an exit for investor."&lt;br /&gt;&lt;br /&gt;There is no doubt it works, and as a side effect it actually does occasionally create something wonderful, but it is ultimately not fulfilling for those looking for a deeper meaning from what they do.  As &lt;a href="http://gettingreal.37signals.com/ch02_Fund_Yourself.php"&gt;37Signals point out&lt;/a&gt; - rightly in my view: "The sad fact is cashing in often begins to trump building a quality product."&lt;br /&gt;&lt;br /&gt;So what can we do about it?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Get away from the focus on the product. In a modern development world products are easily replicable. Any product is merely an enabler for creating a service - a set of people and connections - and it is these people and connections that have the value, not the product. Concentrate on the people and their philosophy not the product.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Try to automate the process. One of the disturbing trends I see is humans used as the ultimate flexible middleware between niche point web applications. Find a way of getting the machines to do the hard work.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Start charging for what you are actually selling. Why do we sell the products with free support? The product has an incremental cost of zero, and the support involves expensive people. So charge for the support and give the product away for free. That way you can move to 'branded' individuals or branded small teams of individuals and they can charge more. Any decent architect could have designed &lt;a href="http://en.wikipedia.org/wiki/30_St_Mary_Axe"&gt;The Gherkin&lt;/a&gt;, so why did they pay for Norman Foster?&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Merge your customer and consumer. Try and make sure the person laying out the cash (or at least making the buying decision) is the one using your services. Concentrate on those markets where this applies.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Build your FY fund. It worked for Humphrey Bogart, it can work for you. If you have to earn something today then you are not in control of your destiny. You have no capital in a capitalist society and once again those that own it will be telling you what you can and can't do - whether you are employed, freelance or whatever. So if you're in an area where there is a rich seam of cash to be mined, then grit your teeth and mine it. Then put it to one side. The world will wait until you are ready.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Get good with money. It's always amazed me the number of people who are quite happy to do several hours overtime, but won't spend fifteen minutes to change their utility suppliers to a vastly cheaper offering. If you are building a capital sum so you can control your destiny then obviously it builds faster if it doesn't leak. &lt;a href="http://www.moneysavingexpert.com/"&gt;Go learn how to plug your leaks&lt;/a&gt;.  You probably don't have to go as far as I did (by training in accountancy) and I admit I have a genetic advantage when it comes to cost efficiency :-), but if you remember one thing, remember this: £15 saved is as much as £25 earned when you account for tax. (£33 if you access tax credits - seriously!).&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Be the Investor. He who pays the piper calls the tune - always.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;Getting round The Flip is a harder problem to solve. There has to be a model of operation that gets away from the short-termism inherent in The Flip with its obsession about capital value. There has to be some way of getting back to concentrating on income, cash flow and customers and making equity patient again. Thoughts:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Founders as partners, where partner is more an ownership mindset than a legal structure.  In all other professional fields partnership is the primary model, where capital value is owned directly by the individual. Few in IT understand the partnership approach and the way capital value accrues in such a structure. Often what you find in IT is a pseudo partnership approach sat under a Limited Company.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Build one to throw away. Where you get involved in a capital project and use the proceeds of that to do what you really want to do - an income project. Ubuntu falls into this category.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Internal project. Where you build your product alongside your standard agency work and gradually convert over to an income business. 37Signals worked this way. I'm just not convinced that the 'tenner a month' software leasing model is sustainable in the medium term.&lt;br /&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;The one I like most at the moment is the Free Software network idea, where you get over the idea that you must hide the product from the world if you are to profit from it. Make it easy for those who are good at the partnering and branding thing to do their stuff in whatever niche they fancy. Sell the setup and the backup preferably on a branded individual basis; put development down as a marketing cost. White-Box Web 2 if you like.&lt;br /&gt;&lt;br /&gt;It may be that the Flip and the OTT marketing it generates is the only way that works in IT. In which case you've just got to put up with it, or get out. Unfortunately it is not any better anywhere else, so I rather hope that something will drop out of this debate.&lt;br /&gt;&lt;br /&gt;Let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-7495894045067519925?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/7495894045067519925/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=7495894045067519925" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7495894045067519925?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7495894045067519925?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/03/why-it-is-perennially-irritating-and.html" title="Why IT is perennially irritating - and what we can do about it" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0EAQnY8eyp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-7055227534646007970</id><published>2008-03-27T14:32:00.011Z</published><updated>2008-03-27T14:54:03.873Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:54:03.873Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="snippets" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Checking for Active EU Vat Numbers in Rails with SOAP and REST</title><content type="html">Rather than implementing checksums and the like for VAT numbers I've decided to go straight to the Internet database and check the number there. It is exposed as a soap service and the ActiveRecord code looks like this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote style=" margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;pre&gt;  &lt;span class="comment"&gt;#Use the SOAP checker on the Internet to see if the VAT number is live&lt;/span&gt;&lt;br /&gt;  &lt;span class="comment"&gt;#The driver is created on first use and cached &lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;active?&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;valid?&lt;/span&gt;&lt;br /&gt;      &lt;span class="attribute"&gt;@@vat_check_driver&lt;/span&gt; &lt;span class="punct"&gt;||=&lt;/span&gt; &lt;span class="ident"&gt;create_vat_check_driver&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="attribute"&gt;@@vat_check_driver&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;checkVat&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;br /&gt;        &lt;span class="symbol"&gt;:countryCode&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;country_code&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="symbol"&gt;:vatNumber&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;identifier&lt;/span&gt;&lt;br /&gt;      &lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="ident"&gt;result&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;valid&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="ident"&gt;private&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;soap/wsdlDriver&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;create_vat_check_driver&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;wsdl&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://ec.europa.eu/taxation_customs/vies/api/checkVatPort?wsdl&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="constant"&gt;SOAP&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;WSDLDriverFactory&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;wsdl&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;create_rpc_driver&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;'countrycode' and 'identifier' are the names of the ActiveRecord attributes containing respectively the 2 character ISO country code and the Vat number.&lt;br /&gt; &lt;br /&gt;For a bit of mild amusement I translated this into a REST based collection sat on &lt;a href="http://3accounts.co.uk/active_eu_vat_numbers"&gt;http://3accounts.co.uk/active_eu_vat_numbers&lt;/a&gt; so that you can get them using ActiveResource.&lt;br /&gt;&lt;br /&gt;&lt;blockquote style="margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;pre&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;ActiveEuVatNumber&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveResource&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;br /&gt; &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;site&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://3accounts.co.uk&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="constant"&gt;ActiveEuVatNumber&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;gb123456789&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;You'll get an ActiveResource exception if the record doesn't exist.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-7055227534646007970?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/7055227534646007970/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=7055227534646007970" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7055227534646007970?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7055227534646007970?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/03/checking-for-active-eu-vat-numbers-in.html" title="Checking for Active EU Vat Numbers in Rails with SOAP and REST" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0MFQ305fSp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-2519370341685505081</id><published>2008-03-26T12:08:00.006Z</published><updated>2008-03-27T14:50:12.325Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:50:12.325Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plugins" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Validates As EU VAT Number Rails plugin published</title><content type="html">I&amp;#39;ve extracted the validation routines into a plugin that checks an ActiveRecord attribute to see if it conforms to the correct format for a VAT number. It works with all the EU countries and is tested with real EU VAT numbers as harvested from the good ol&amp;#39; Interweb.&lt;br&gt; &lt;br&gt;&lt;span style="font-weight: bold;"&gt;Install&lt;/span&gt;&lt;br&gt;&lt;br&gt;Install via script/plugin&lt;br&gt;&lt;br&gt;&lt;blockquote style="margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;pre&gt;script/plugin install http://accounts4free.rubyforge.org/svn/plugins/validates_as_eu_vat_number&lt;/pre&gt;&lt;/blockquote&gt;&lt;br&gt; &lt;br&gt;or use piston&lt;br&gt;&lt;br&gt;&lt;blockquote style="margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;pre&gt;piston import http://accounts4free.rubyforge.org/svn/plugins/validates_as_eu_vat_number&lt;/pre&gt;&lt;/blockquote&gt;&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;Usage&lt;/span&gt;&lt;br&gt;&lt;br&gt;The plugin provides another validation helper &lt;span style="font-family: courier new,monospace;"&gt;validates_as_eu_vat_number &lt;/span&gt;which takes a set of attributes and an optional &lt;span style="font-family: courier new,monospace;"&gt;:with&lt;/span&gt; modifier that points to the attribute containing the country code, or a string containing the country code itself. If you don&amp;#39;t use the &lt;span style="font-family: courier new,monospace;"&gt;:with&lt;/span&gt; modifier then the routine expects the country code to be the first two characters of the attribute itself, e.g:&lt;br&gt; &lt;br&gt;&lt;blockquote style="margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;" class="gmail_quote"&gt;&lt;pre&gt;  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;VatNumber&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;validates_as_eu_vat_number&lt;/span&gt; &lt;span class="symbol"&gt;:full_vat_number&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;validates_as_eu_vat_number&lt;/span&gt; &lt;span class="symbol"&gt;:vat_number&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt;&lt;br /&gt;                               &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:country_code&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br&gt;In common with other validates plugins, this one takes the usual &lt;span style="font-family: courier new,monospace;"&gt;:if, :unless, :on, :message, :allow_ni&lt;/span&gt;l and &lt;span style="font-family: courier new,monospace;"&gt;:allow_blank&lt;/span&gt; options provided by the underlying validation mechanism.&lt;br&gt; &lt;br&gt;&lt;span style="font-weight: bold;"&gt;Documentation&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;The plugin has rdoc documentation included. Run &lt;span style="font-family: courier new,monospace;"&gt;rake &lt;/span&gt;within the plugin directory to create it.&lt;br&gt; &lt;br&gt;&lt;span style="font-weight: bold;"&gt;Testing&lt;/span&gt;&lt;br&gt;&lt;br&gt;ValidatesAsEuVatNumber has an extensive test suite created using &lt;a href="http://rspec.info/"&gt;Rspec&lt;/a&gt; and a lot of Googling for VAT numbers. The easiest way to run the test suite is to do rake spec:plugins from the root directory of the Rails application containing the plugin (and the rspec and rspec_on_rails plugins as well obviously).&lt;br&gt; &lt;br&gt;&lt;span style="font-weight: bold;"&gt;Freebies&lt;/span&gt;&lt;br&gt;&lt;br&gt;The plugin creates an EU module with a couple of constants in it. &lt;br&gt;&lt;br style="font-family: courier new,monospace;"&gt;&lt;span style="font-family: courier new,monospace;"&gt;EU::MEMBER_STATES_COUNTRY_CODES&lt;/span&gt; is an array containing the ISO code strings of all the EU member states.&lt;br&gt; &lt;span style="font-family: courier new,monospace;"&gt;EU::MEMBER_STATES_VAT_PICTURES&lt;/span&gt; is a hash indexed on the country code containing the Regular expression VAT pictures for every EU country .&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;Links&lt;br&gt; &lt;br&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;/span&gt;If you&amp;#39;re looking for a VAT validator but not working with Rails then you might want to try this &lt;a href="http://www.braemoor.co.uk/software/vat.shtml"&gt;Javascript validator&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt; &lt;br&gt; &lt;/span&gt;&lt;/span&gt;And if you just want to check a VAT number to see if it is live, then use the &lt;a href="http://ec.europa.eu/taxation_customs/vies/"&gt;online checker on Europa&lt;/a&gt;.&lt;br&gt;&lt;br&gt;&lt;span style="font-weight: bold;"&gt;Bugs/Comments/Faint Praise&lt;br&gt; &lt;br&gt;&lt;/span&gt;&lt;a href="mailto:aldursys@gmail.com?subject=ValidatesAsEuVatNumber%20Comment"&gt;Let me know&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-2519370341685505081?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/2519370341685505081/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=2519370341685505081" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/2519370341685505081?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/2519370341685505081?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/03/validates-as-eu-vat-number-rails-plugin.html" title="Validates As EU VAT Number Rails plugin published" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A08CRXc_eCp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-381104587570471257</id><published>2008-02-20T10:56:00.003Z</published><updated>2008-03-27T14:57:44.940Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:57:44.940Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="monit" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="capistrano" /><title>Using Monit to manage your app servers in Capistrano 2</title><content type="html">If you've gone to the trouble of setting up monit on your server (or you're using a &lt;a href="http://www.brightbox.co.uk/"&gt;Brightbox&lt;/a&gt; like I am), why not let it take the strain of starting and stopping your app servers during a Capistrano deployment.&lt;br /&gt;&lt;br /&gt;Just stick this code snippet at the bottom of the &lt;code&gt;deploy.rb&lt;/code&gt; file.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="comment"&gt;# Redefine the application server controls to use monit.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="ident"&gt;namespace&lt;/span&gt; &lt;span class="symbol"&gt;:deploy&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;  &lt;span class="punct"&gt;%W(&lt;/span&gt;&lt;span class="string"&gt;start stop restart&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;desc&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{event}&lt;/span&gt; using Monit&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;task&lt;/span&gt; &lt;span class="ident"&gt;event&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:except&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="symbol"&gt;:no_release&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;sudo&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;/usr/sbin/monit -g &lt;span class="expr"&gt;#{application}&lt;/span&gt; &lt;span class="expr"&gt;#{event}&lt;/span&gt; all&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-381104587570471257?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/381104587570471257/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=381104587570471257" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/381104587570471257?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/381104587570471257?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/02/using-monit-to-manage-your-app-servers.html" title="Using Monit to manage your app servers in Capistrano 2" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total></entry><entry gd:etag="W/&quot;A08MRH49cSp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-8630688486494210706</id><published>2008-02-04T19:17:00.001Z</published><updated>2008-03-27T14:58:05.069Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:58:05.069Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="reviews" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>The Rails Way - if you haven't got it, get it.</title><content type="html">I've been working through &lt;a href="http://www.amazon.co.uk/gp/product/0321445619?ie=UTF8&amp;tag=aldursystems-21&amp;linkCode=as2&amp;camp=1634&amp;creative=6738&amp;creativeASIN=0321445619"&gt;The Rails Way&lt;/a&gt; by Obie Fernandez and it is most definitely the best reference text for Rails I've come across so far. It's in depth, informative and even opinionated in places. &lt;br /&gt;&lt;br /&gt;It covers Rails 2.0 but I found that throughout the text there were strange omissions - no mention of &lt;a href="http://ryandaigle.com/articles/2007/5/6/what-s-new-in-edge-rails-bringin-sexy-back"&gt;Sexy Migrations&lt;/a&gt; for example even though they've been there for nine months now. Having said that keeping up with a fast moving target like Rails can't be easy when you have a hungry publisher breathing down your neck.&lt;br /&gt;&lt;br /&gt;Anyway if you're a Rails developer you need this book.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-8630688486494210706?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/8630688486494210706/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=8630688486494210706" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8630688486494210706?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8630688486494210706?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2008/02/rails-way-if-you-havent-got-it-get-it.html" title="The Rails Way - if you haven't got it, get it." /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A08AQ3s8fyp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-8071948062430699015</id><published>2007-09-27T21:16:00.001+01:00</published><updated>2008-03-27T14:57:22.577Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:57:22.577Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Restricting to_xml RESTfully</title><content type="html">If you want to restrict the XML representation of your model to just a few fields, use:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;to_xml&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;={})&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:only&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;super&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Replacing the array with whatever fields you want to restrict the representation to.&lt;br /&gt;&lt;br /&gt;A couple of the other examples out there break the &lt;code&gt;:index&lt;/code&gt; XML representation because they don't pass on the upstream &lt;code&gt;options&lt;/code&gt;. This one is kind to REST.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-8071948062430699015?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/8071948062430699015/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=8071948062430699015" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8071948062430699015?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8071948062430699015?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/09/restricting-toxml-restfully.html" title="Restricting to_xml RESTfully" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A08ER3szcSp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-6374749274545118850</id><published>2007-09-26T14:44:00.002+01:00</published><updated>2008-03-27T14:56:46.589Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:56:46.589Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rspec" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Checking response codes</title><content type="html">I'm getting up to full speed with Rspec at the moment. It's interesting how much is missing from Rspec_on_Rails compared to the standard test assertions - particularly when you start testing APIs.&lt;br /&gt;&lt;br /&gt;Anyway here's a few quick helper method which you stick in &lt;code&gt;spec_helper.rb&lt;/code&gt; within the &lt;code&gt;Spec::Runner.configure&lt;/code&gt; block so that they are available to all your specifications.&lt;br /&gt;&lt;br /&gt;The first set switches SSL on and off. I use them in the &lt;code&gt;before&lt;/code&gt; blocks.&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;deactivate_ssl&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;env&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;HTTPS&lt;/span&gt;&lt;span class="punct"&gt;']='&lt;/span&gt;&lt;span class="string"&gt;off&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;activate_ssl&lt;/span&gt;&lt;br /&gt;    &lt;span class="ident"&gt;request&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;env&lt;/span&gt;&lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;HTTPS&lt;/span&gt;&lt;span class="punct"&gt;']='&lt;/span&gt;&lt;span class="string"&gt;on&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;The next patches a hole in the Rspec on Rails matchers, which seems to lack a wrapper around &lt;code&gt;assert_response&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The helper function&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;status_code&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;is_a?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;Symbol&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span class="constant"&gt;ActionController&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;StatusCodes&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;SYMBOL_TO_STATUS_CODE&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;type&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;else&lt;/span&gt;&lt;br /&gt;      &lt;span class="ident"&gt;type&lt;/span&gt;&lt;br /&gt;    &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;  &lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Then you can write the following specifications, e.g:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;    &lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;response_code&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="ident"&gt;status_code&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:created&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;Of course this would be better in a custom matcher. Over to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-6374749274545118850?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/6374749274545118850/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=6374749274545118850" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6374749274545118850?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6374749274545118850?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/09/checking-response-codes.html" title="Checking response codes" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;DUMERXw9cSp7ImA9WB9TEko.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-3854357656619894071</id><published>2007-09-20T09:31:00.000+01:00</published><updated>2007-09-20T09:36:44.269+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-09-20T09:36:44.269+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><title>A momentous day</title><content type="html">I've tried to keep personal stuff out of this blog as much as I can simply to avoid boring my readers. After all everybody leads a life. However today is special - my eldest daughter, Amy, started school. &lt;br /&gt;&lt;br /&gt;One of the great benefits of having kids is that they help scope the seasons and make you realise how fast time flies when you're having fun.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-3854357656619894071?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/3854357656619894071/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=3854357656619894071" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/3854357656619894071?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/3854357656619894071?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/09/momentous-day.html" title="A momentous day" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A08GR3w5eyp7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-7057601824648909137</id><published>2007-09-16T13:26:00.001+01:00</published><updated>2008-03-27T14:57:06.223Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:57:06.223Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><title>Creating Static Home Pages in Rails</title><content type="html">One trick I've not seen anywhere in my Google searches is to have Rails generate your static html pages for you. &lt;br /&gt;&lt;br /&gt;However if you find that you have to build wrapper pages around the front of your application, then you can do a lot worse than use the tools of ERB, et al to reduce the duplication.&lt;br /&gt;&lt;br /&gt;What I've used is a HomeController that looks like this:&lt;br /&gt;&lt;blockquote&gt;&lt;pre&gt;&lt;span class="comment"&gt;# Static page generator&lt;/span&gt;&lt;br /&gt;&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;HomeController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;&lt;br /&gt;&lt;span class="ident"&gt;caches_page&lt;/span&gt; &lt;span class="symbol"&gt;:index&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:donation&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;br /&gt;with a couple of routes at the bottom of &lt;code&gt;routes.rb&lt;/code&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;PRE&gt;  &lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;home&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;home&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:action&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;index&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;br /&gt;  &lt;span class="ident"&gt;map&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;connect&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;/:action/:id&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:controller&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;home&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;&lt;/PRE&gt;&lt;/blockquote&gt;&lt;br /&gt;Now you merely create the views you require in &lt;code&gt;views/home&lt;/code&gt; and add the name to the &lt;code&gt;caches_page&lt;/code&gt; command.&lt;br /&gt;&lt;br /&gt;Rails will then generate the static pages on first access for anything that doesn't have a more specific controller and has a view, and a 404 error for anything else.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-7057601824648909137?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/7057601824648909137/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=7057601824648909137" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7057601824648909137?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/7057601824648909137?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/09/creating-static-home-pages-in-rails.html" title="Creating Static Home Pages in Rails" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;D0ANR3c7eCp7ImA9WB5bEkk.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-703507173887208456</id><published>2007-08-27T21:06:00.000+01:00</published><updated>2007-08-27T21:16:36.900+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-08-27T21:16:36.900+01:00</app:edited><title>The art of the leg up</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://railscasts.com/images/logo.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://railscasts.com/images/logo.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The first step with any piece of free software is to stand on the shoulders of as many other people as possible. &lt;a href="http://dev.3accounts.co.uk/"&gt;3accounts&lt;/a&gt; has to make use of as much stuff that is already in place if it is to make any headway.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;First and foremost I'm using Ruby and Rails. Both the language and the framework help get rid of the annoying plumbing you need to do to get web applications to work.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Secondly I'm using plugins and gems. I committed the basic structure of the login page today, and that is all plugins - specifically the restful_authentication and open_id_authentication plugins.&lt;/li&gt;&lt;li&gt;And finally I'm cribbing techniques. The Rails community delights in using screencasts and podcasts. Some are a waste of time, but the screencasts at &lt;a href="http://railscasts.com/"&gt;Railscasts&lt;/a&gt; are definitely worth viewing to get you up to speed with Rails development as quickly as possible.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-703507173887208456?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/703507173887208456/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=703507173887208456" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/703507173887208456?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/703507173887208456?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/08/art-of-leg-up.html" title="The art of the leg up" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;A0QERXc5fCp7ImA9WB5UGEQ.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-8308591352048575609</id><published>2007-08-23T20:29:00.000+01:00</published><updated>2007-08-23T21:01:44.924+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-08-23T21:01:44.924+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>The month in review</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.ubuntu.com/themes/ubuntu07/images/ubuntulogo.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 202px; height: 54px;" src="http://www.ubuntu.com/themes/ubuntu07/images/ubuntulogo.png" alt="" border="0" /&gt;&lt;/a&gt;Well I'm not quite sure where August has gone. It's the bank holiday here on Monday and that to me is the official end of summer. Not that there's been much of one in Britain this year.&lt;br /&gt;&lt;br /&gt;Anyway I've been busy on a couple of fronts. Firstly I've been squeezing a few packages into the upcoming Ubuntu Gutsy release. The 'apt' versions of 'sqlite-ruby' and 'mongrel' should be uploaded soon, to join the 'vim-rails' package which is already in there.&lt;br /&gt;&lt;br /&gt;I've also added bash-completion to the 'rubygems' package and got that committed.&lt;br /&gt;&lt;br /&gt;All this is part of my personal campaign to make Ubuntu ridiculously easy to develop Rails applications on. The 'rails-toolkit' will soon move to my &lt;a href="https://launchpad.net/%7Eneil-aldur/+archive"&gt;Personal Package Archive&lt;/a&gt; on Launchpad. 'rails-toolkit'  installs all the packages and gems for developing Rails applications without any messing around with scripts and lengthy instructions.&lt;br /&gt;&lt;br /&gt;However once the Ubuntu Universe moves into freeze at the end of the month it is time to start getting real with the main feature - &lt;a href="https://launchpad.net/3accounts"&gt;3accounts&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-8308591352048575609?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/8308591352048575609/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=8308591352048575609" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8308591352048575609?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/8308591352048575609?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/08/month-in-review.html" title="The month in review" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total></entry><entry gd:etag="W/&quot;A04FQH45fip7ImA9WxZVFk8.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-6868312352061487527</id><published>2007-07-30T16:37:00.001+01:00</published><updated>2008-03-27T14:58:31.026Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-27T14:58:31.026Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="personal" /><title>My coding silver anniversary</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/3/31/Sinclair_ZX81.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 200px;" src="http://upload.wikimedia.org/wikipedia/commons/3/31/Sinclair_ZX81.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;29th July 1982. A great time to be alive in the UK. We may have lost appalling in the World Cup but at least we'd beaten the Argies in a game of soldiers. But more importantly after about two months of waiting I finally received my first computer - &lt;a href="http://en.wikipedia.org/wiki/Sinclair_ZX81"&gt;the venerable ZX81&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In short order (a few hours - I had to work out how to type first!) I had my first program written&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;br /&gt;10 PRINT "HELLO"&lt;br /&gt;20 GOTO 10&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;Shortly  after that I ran out of memory... after all the thing only had 1KB :-)&lt;br /&gt;&lt;br /&gt;Yes, I've now been writing code for 25 years - a full quarter of a century.&lt;br /&gt;&lt;br /&gt;Time to do something special to celebrate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-6868312352061487527?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/6868312352061487527/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=6868312352061487527" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6868312352061487527?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6868312352061487527?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/07/my-coding-silver-anniversary.html" title="My coding silver anniversary" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry><entry gd:etag="W/&quot;CEIHQnwyeyp7ImA9WB5WFkQ.&quot;"><id>tag:blogger.com,1999:blog-1879770534244304287.post-6120125565089283551</id><published>2007-07-29T07:08:00.000+01:00</published><updated>2007-07-29T08:02:13.293+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-07-29T08:02:13.293+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="tax" /><title>A taxing time for couples</title><content type="html">When I was legal director of &lt;a href="http://www.pcg.org.uk/"&gt;PCG (Professional Contractors Group)&lt;/a&gt; back in the early days of the new millennium, a strange case crossed my desk. Apparently somebody in the Inland Revenue was trying to apply the settlements legislation to a couple of contractors, which meant that the higher earner would pay tax at over 45% on the lower earner's share of the business.&lt;br /&gt;&lt;br /&gt;I didn't spend much time on it because I was tied up with the judicial review against IR35, and I figured it would be sorted quite quickly once PCG's investigation team got involved. As every contractor knew at the time - a company run by a married couple is probably a settlement, but there is an 'outright gift' exception for married couples. That then puts them on a par with unmarried couples and normal partnerships.&lt;br /&gt;&lt;br /&gt;After some seven years the House of Lords finally agreed with the contractors. And then as soon as they won, the government decides it is going to change the law to stop what it calls 'income splitting'. Why they couldn't have done that in the first place rather than leading everybody a merry dance for seven years is something people ought to ponder the next time they are asked to put an X on a piece of paper.&lt;br /&gt;&lt;br /&gt;That the government is going to introduce one of their wonderfully effective 'targeted' pieces of legislation is not new of course. Taxation experts and lawyers are already rubbing their hands with glee at the extra fees this thing will generate. What worries me is that the government is conveniently avoiding a couple of other issues.&lt;br /&gt;&lt;br /&gt;If 'income splitting' is wrong and individuals should be taxed according to their contribution, then why is income based upon physical assets to be taxed differently.&lt;br /&gt;&lt;br /&gt;For example if a couple have a Buy-to-Let business then income (and capital gain!) from that business can be split 50/50 and nobody seems to get upset - regardless of where the money came from to purchase the houses and regardless of the effort put into running the business.&lt;br /&gt;&lt;br /&gt;Similarly if an individual pays into a spouse's ISA or a pension, or simply puts assets in the name of their spouse then the income from those assets is taxed as the spouse's income.&lt;br /&gt;&lt;br /&gt;Why is income from physical assets so different from that from intellectual assets? It makes no sense.&lt;br /&gt;&lt;br /&gt;And of course if you introduce the notion of 'income splitting' so that the exchequer can transfer money to the highest taxed individual on a whim, then surely it is only 'fair' (to use that appalling PR phrase the government is so fond of) to consider the opposite issue of 'income aggregation'.&lt;br /&gt;&lt;br /&gt;Is it 'fair' that when an individual sacrifices their earning potential so that their spouse can earn a higher wage, that the spouse is taxed on *all* the income generated? Often at a punitive marginal rate of up to 45%.&lt;br /&gt;&lt;br /&gt;Isn't it about time that unpaid carers and housekeepers and personal assistants received a wage for their efforts, and were taxed accordingly?&lt;br /&gt;&lt;br /&gt;If 'income splitting' isn't fair, then 'income aggregation' is an outright scandal.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1879770534244304287-6120125565089283551?l=www.3spoken.co.uk'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.3spoken.co.uk/feeds/6120125565089283551/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=1879770534244304287&amp;postID=6120125565089283551" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6120125565089283551?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1879770534244304287/posts/default/6120125565089283551?v=2" /><link rel="alternate" type="text/html" href="http://www.3spoken.co.uk/2007/07/on-taxation-of-couples.html" title="A taxing time for couples" /><author><name>Neil Wilson</name><uri>http://www.blogger.com/profile/18178155357632397049</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="02157711283556558102" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total></entry></feed>
