<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>James Wilding&#039;s Weblog &#187; ruby</title>
	<atom:link href="http://jameswilding.net/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://jameswilding.net</link>
	<description>Buddhist businessman, freelance web developer</description>
	<lastBuildDate>Wed, 28 Jul 2010 12:00:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Ruby&#8217;s OpenStruct: An Introduction</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2010%2F07%2F24%2Fruby-openstruct%2F&amp;seed_title=Ruby%26%238217%3Bs+OpenStruct%3A+An+Introduction</link>
		<comments>http://jameswilding.net/2010/07/24/ruby-openstruct/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 13:43:06 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Web Development]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=714</guid>
		<description><![CDATA[OpenStructs are magic &#8212; they&#8217;re like hashes, but far less fussy about what methods you throw at them. The key feature of OpenStructs is this: they allow you to arbitrarily set and access attributes for your models, on the fly. Here&#8217;s an example: require 'ostruct' s = OpenStruct.new s.name # =&#62; nil s.name = 'James' [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://ruby-doc.org/core/classes/OpenStruct.html">OpenStructs</a> are magic &#8212; they&#8217;re like hashes, but far less fussy about what methods you throw at them. The key feature of OpenStructs is this: they allow you to arbitrarily set and access attributes for your models, on the fly.</p>
<p>Here&#8217;s an example:</p>
<pre><code>require 'ostruct'

s = OpenStruct.new
s.name # =&gt; nil
s.name = 'James'
s.name # =&gt; 'James'
</code></pre>
<p>Note that we don&#8217;t need to initialise the &#8216;name&#8217; attribute: we just set the value and Ruby takes care of the rest. Want to add a new attribute? Easy.</p>
<pre><code>s.age # =&gt; nil
s.age = 29
s.age # =&gt; 29
</code></pre>
<p>We can add any attribute we want to our objects, on the fly, and <strong>different instances of the OpenStruct class can have different attributes</strong>. Importantly, we don&#8217;t have to worry about what methods we send to our OpenStructs, because anything that doesn&#8217;t have a value just returns nil <a class="simple-footnote" title="This can be a curse as well as a blessing, because you&#8217;ll often get nil when you&#8217;d expect Ruby to raise a NoMethodError. Checkout OpenStruct&#8217;s method_missing to see what&#8217;s going on behind the scenes." id="return-note-714-1" href="#note-714-1"><sup>1</sup></a>:</p>
<pre><code>s.location # =&gt; nil
s.hobbies # =&gt; nil
</code></pre>
<h3>Clearing Values</h3>
<p>To unset a value, we can do one of two things: in most cases, it&#8217;s the obvious&#8230;</p>
<pre><code>2.age # =&gt; 29
s.age = nil
s.age # =&gt; nil
</code></pre>
<p>&#8230;but to grab the value before setting the attribute back to nil, we can use delete_field <a class="simple-footnote" title="This is one of OpenStruct&#8217;s few built-in instance methods which don&#8217;t act as attribute accessors. Check the docs for details." id="return-note-714-2" href="#note-714-2"><sup>2</sup></a>:</p>
<pre><code># Returns 29, and sets 'age' to nil
age = s.delete_field('age')
age # =&gt; 29
s.age # =&gt; nil
</code></pre>
<h3>Initialising With Values</h3>
<p>We can create new OpenStruct objects with attribute/value pairs by providing a hash:</p>
<pre><code>s = OpenStruct.new(:name =&gt; 'James', :occupation =&gt; 'Rubyist')
s.name # =&gt; 'James'
s.occupation # =&gt; 'Rubyist'
</code></pre>
<h3>How It Works</h3>
<p>Behind the scenes, Ruby uses a hash to implement OpenStruct&#8217;s easy access so we get all the flexibility of a hash with a nice, clean, method-style access laid on top. Don&#8217;t worry about the details: just throw whatever you want into your OpenStructs, and let Ruby take care of your data.</p>
<h3>Advanced Initialization</h3>
<p>If you want object with the flexibility of OpenStructs but with default values for some attributes then something like the following would work:</p>
<pre><code>require 'ostruct'

class MyStruct &lt; OpenStruct
  # Hard-code age and status
  def initialize(hash = {})
    super hash.merge(:age =&gt; 29, :role =&gt; 'Manager')
  end
end

s = MyStruct.new(:name =&gt; 'Bob')
s.name # =&gt; 'Bob'
s.age # =&gt; 29
s.role # =&gt; 'Manager'

# We can override the default values
s = MyStruct.new(:age =&gt; 45)
s.age # =&gt; 45
</code></pre>
<h3>OpenStruct vs Struct</h3>
<p>Ruby&#8217;s Struct is subtly, but importantly, different to OpenStruct. How to use Struct is another blog post, but put simply Structs are less flexible. Check the <a href="http://ruby-doc.org/core/classes/Struct.html">Struct docs</a> for more info :)</p>
<div class="simple-footnotes"><p class="notes">Notes:</p><ol><li id="note-714-1">This can be a curse as well as a blessing, because you&#8217;ll often get nil when you&#8217;d expect Ruby to raise a NoMethodError. Checkout <a href="http://gist.github.com/488692">OpenStruct&#8217;s method_missing</a> to see what&#8217;s going on behind the scenes. <a href="#return-note-714-1">&#8617;</a></li><li id="note-714-2">This is one of OpenStruct&#8217;s few built-in instance methods which don&#8217;t act as attribute accessors. Check <a href="http://ruby-doc.org/core/classes/OpenStruct.html">the docs</a> for details. <a href="#return-note-714-2">&#8617;</a></li></ol></div>]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2010/07/24/ruby-openstruct/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby on the iPad</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2010%2F01%2F28%2Fruby-on-the-ipad%2F&amp;seed_title=Ruby+on+the+iPad</link>
		<comments>http://jameswilding.net/2010/01/28/ruby-on-the-ipad/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 10:59:43 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[apple]]></category>
		<category><![CDATA[ipad]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=483</guid>
		<description><![CDATA[Can you run Ruby on an iPad? Is the Pope a protestant?]]></description>
			<content:encoded><![CDATA[<p>Since I wrote <a href="http://jameswilding.net/2010/01/27/thoughts-on-the-ipad/">Thoughts on the iPad</a> yesterday, that article has been getting lots of hits from people searching for &#8220;ruby on ipad&#8221; &#8212; or variations thereof.</p>
<p>If you&#8217;ve reached this post by searching for something similar, I&#8217;m guessing you want to do one of two things: either 1) run Ruby on an iPad, or 2) develop for the iPad using Ruby.</p>
<h3>1) Run Ruby on the iPad</h3>
<p>Never going to happen.</p>
<p>Like the iPod and the iPhone, the iPad is a closed system. The only near-possible way to run Ruby on an iPad would, I&#8217;m guessing, be to create an app which bundled Ruby and provided a command-line interface to it. But that&#8217;s not going to happen either. Can you imagine Apple approving an app which allowed users to run any code they liked &#8212; even within a sandbox? Neither can I.</p>
<h3>2) Develop for the iPad using Ruby</h3>
<p>This is less clear-cut: there&#8217;s obviously no support for Ruby in the Objective-C iPad SDK, but we do have <a href="http://www.macruby.org/">MacRuby</a>: &#8220;a version of Ruby 1.9, ported to run directly on top of Mac OS X core technologies&#8221;. I think the key words there are &#8220;<em>Mac</em> OS X technologies (my emphasis)&#8221;; Mac OS X is different to iPhone/iPad OS X, and right now there&#8217;s about as much chance of using MacRuby to develop iPad apps as there is of Bill Gates coming to work at Apple.</p>
<p>That might change though (the MacRuby thing, not Bill Gates) &#8212; which change would depend on MacRuby becoming a popular way to develop for the Mac. If enough developers use it, Apple may &#8212; <em>may</em> &#8212; decide it&#8217;s worth their time an effort to port MacRuby to their other platforms.</p>
<p>So, Googler: there&#8217;s some small hope.</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2010/01/28/ruby-on-the-ipad/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lessons Learnt With Rails</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2010%2F01%2F21%2Flessons-learnt-with-rails%2F&amp;seed_title=Lessons+Learnt+With+Rails</link>
		<comments>http://jameswilding.net/2010/01/21/lessons-learnt-with-rails/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 13:14:02 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=423</guid>
		<description><![CDATA[Things I've learnt from working on a massive Rails application that needed tidying. Routes, simplicity, Ruby, REST -- all sorts of Rails goodness.]]></description>
			<content:encoded><![CDATA[<p>Some lessons I&#8217;ve learnt working on my latest Rails project, a piece of tidy-and-fix work on an existing Rails application. Working on this project has really taught me a lot about the right and wrong ways to use Rails.</p>
<h3>1. Routes are important</h3>
<p>The app that I was asked to rebuilt had no routes. Nothing.</p>
<p>That&#8217;s not to say that no URLs worked with the app, just that the mappings between URLs and controllers/actions was defined in the code itself &#8212; mostly using the old Rails convention:</p>
<p><script src="http://gist.github.com/282785.js?file=urlfor.rb"></script></p>
<p>This makes it very difficult to discover how a Rails app responds to a particular URL, without hunting through the controllers to find a corresponding action. It also makes working with REST a nightmare!</p>
<p><strong>Lesson learnt:</strong> use routes.rb</p>
<h3>2. Conventions are important</h3>
<p>Rails is all about convention over configuration, of course. But when you&#8217;re coding a Rails app &#8212; especially if you&#8217;re new to Rails &#8212; it&#8217;s easy to ignore those conventions, or just be plain unaware of them.</p>
<p>This leads to a lot of unnecessary work. I&#8217;ve spent a lot of time over the past few months translating unconventional code into code that more closely fits the Rails way of doing things: the result is code that&#8217;s easier to test, easier to maintain, and much, much faster.</p>
<p><strong>Lesson learnt: </strong>take some time to understand Rails&#8217; conventions</p>
<h3>3. Simplicity is important</h3>
<p>The more I write code, the more I find myself thinking: complicated code is a Bad Thing. Of course, as a kind pedant once told me, there&#8217;s a difference between <em>complicated</em> and <em>complex</em>.</p>
<p>(If you don&#8217;t have a dictionary handy, &#8220;complicated&#8221; roughly means messy, difficult to understand; &#8220;complex&#8221; means many interconnected parts, or a large system. The key difference is that complex systems can be well designed: <em>complicated</em> systems are not.)</p>
<p>OK, dictionary rant over :) Messy, complicated Rails applications come about when a developer doesn&#8217;t take the time to think things through. Simplicity is normally easy if you take some time to plan your work upfront &#8212; messy code happens when things are rushed or not thought through.</p>
<p><strong>Lesson learnt:</strong> think before you start coding</p>
<h3>4. Ruby is important</h3>
<p>Obvious, but very true: Ruby is important to Rails applications. If you&#8217;re new to coding, or new to Rails, then take some time to learn Ruby first: otherwise, you&#8217;ll miss out on the power (and beauty) of a great language and a great framework.</p>
<p><strong>Lesson learnt: </strong>learn Ruby <em>and</em> Rails, not just Ruby <em>on </em>Rails!</p>
<h3>You are important, too</h3>
<p>Conclusions? All of the above (and more) is important when you&#8217;re developing a Rails app. And you, the developer, are important too &#8212; have fun, keep learning, and don&#8217;t work too hard. Rails should be fun :)</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2010/01/21/lessons-learnt-with-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to use Ruby in place of PHP</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F17%2Fruby-php%2F&amp;seed_title=How+to+use+Ruby+in+place+of+PHP</link>
		<comments>http://jameswilding.net/2009/08/17/ruby-php/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 08:00:15 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=195</guid>
		<description><![CDATA[PHP has a great reputation as a hackers&#8217; language, a tool for putting together websites with minimum fuss. It&#8217;s pretty easy to add new features to PHP-based websites too, as you scale. But what if you&#8217;re a Ruby fanatic, or just plain lazy, like me? Ruby doesn&#8217;t have the built-in server-side support that PHP has [...]]]></description>
			<content:encoded><![CDATA[<p>PHP has a great reputation as a hackers&#8217; language, a tool for putting together websites with minimum fuss. It&#8217;s pretty easy to add new features to PHP-based websites too, as you scale. But what if you&#8217;re a Ruby fanatic, or just plain lazy, like me?</p>
<p><span id="more-195"></span>Ruby doesn&#8217;t have the built-in server-side support that PHP has (PHP code will run automatically on most hosts; Ruby code won&#8217;t) &#8212; but it&#8217;s still very easy to code a website using Ruby, and I think the long-term benefits in terms of maintenance and cool code tricks are definitely worth the effort.</p>
<h3>Yet another &#8216;Hello World!&#8217; example</h3>
<p>Ruby&#8217;s <a href="http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html">CGI class</a> will be the base of any attempt to serve web content with Ruby. It provides an easy way to access server environment variable and request headers, and just as importantly CGI objects allow you to output HTML (or anything else) very easily:</p>
<p>[ruby]<br />
require &#8216;cgi&#8217;</p>
<p>CGI.new.out(&#8216;text/html&#8217;) { &quot;Hello world!&quot; }<br />
[/ruby]</p>
<p>Simple enough for you? We create a new <code>CGI</code> object and call its <code>out</code> method with two arguments: the type of the content we&#8217;re sending, and a block which returns the content itself. Here I&#8217;m sending HTML, but I could also use &#8216;text/plain&#8217;, &#8216;text/xml&#8217;, etc &#8212; depending on what content I was sending.</p>
<p>The <code>out</code> method also lets you do various clever things to create HTML elements: check out the <a href="http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html">CGI documentation</a> for more details.</p>
<h3>Add more code and mix well</h3>
<p>I can send textual content, but what if I want to get more involved and start putting Ruby code into HTML files, like I could with PHP or Rails? ERB to the rescue:</p>
<p>[ruby]<br />
require &#8216;cgi&#8217;<br />
require &#8216;erb&#8217;</p>
<p>CGI.new.out(&#8216;text/html&#8217;) do<br />
  # everything between the &lt;% %&gt; tags is evaluated as ruby code<br />
  ERB.new(&quot;&lt;p&gt;1 + 1 = &lt;%= 1 + 1 %&gt;&lt;/p&gt;&quot;).result<br />
end<br />
[/ruby]</p>
<p>That should output:</p>
<p>[html]<br />
&lt;p&gt;1 + 1 = 2&lt;/p&gt;<br />
[/html]</p>
<p>From this point, it&#8217;s easy to build up more complicated ERB templates and mix complex Ruby methods and their results into your HTML. Before you know it, PHP is long forgotten and your website is running on Ruby!</p>
<h3>Brining it all back home</h3>
<p>There are a few more things you need to know before you can really use these techniques to get a webpage up and running: I hope to post a follow up article soon to run through deploying, creating helper methods, separating layout and content, and more. </p>
<p>For now, though, read the <a href="http://www.ruby-doc.org/stdlib/libdoc/cgi/rdoc/classes/CGI.html">CGI docs</a> and play around &#8212; it&#8217;s fun, honest :-)</p>
<p style="color: rgb(100,100,100);">My <a href="http://jameswilding.net/extras/random-password-generator/" title="Random password generator">random password generator</a> is a ruby-powered web page: check it out for an example of what Ruby can do.</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/17/ruby-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Method Missing &amp; Proxies in Ruby</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F13%2Fmethod-missing-proxies-in-ruby%2F&amp;seed_title=Method+Missing+%26amp%3B+Proxies+in+Ruby</link>
		<comments>http://jameswilding.net/2009/08/13/method-missing-proxies-in-ruby/#comments</comments>
		<pubDate>Thu, 13 Aug 2009 08:00:04 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=201</guid>
		<description><![CDATA[Great article from John Nunemaker explaining how to create proxies &#8212; objects that act like other objects &#8212; in Ruby, using a little bit of method_missing magic. If you need to seriously extend the functionality of existing Ruby classes, it&#8217;s much cleaner and safer to use proxies, so this article is a must-read.]]></description>
			<content:encoded><![CDATA[<p><a href="http://railstips.org/2009/8/7/patterns-are-not-scary-method-missing-proxy">Great article</a> from John Nunemaker explaining how to create proxies &#8212; objects that act like other objects &#8212; in Ruby, using a little bit of <code>method_missing</code> magic.</p>
<p>If you need to seriously extend the functionality of existing Ruby classes, it&#8217;s much cleaner and safer to use proxies, so this article is a must-read.</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/13/method-missing-proxies-in-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Learn Ruby!</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F12%2Flearn-ruby%2F&amp;seed_title=Learn+Ruby%21</link>
		<comments>http://jameswilding.net/2009/08/12/learn-ruby/#comments</comments>
		<pubDate>Wed, 12 Aug 2009 08:00:54 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=180</guid>
		<description><![CDATA[Ruby is a beautiful language: easy to write, simple to read, and powerful as hell. It&#8217;s also pretty easy to pick up the basics of Ruby without too much trouble &#8212; but save yourself some time by checking out the following resources that have helped me loads. Ruby-Lang.org: Ruby&#8217;s website has some great tutorials for [...]]]></description>
			<content:encoded><![CDATA[<p>Ruby is a beautiful language: easy to write, simple to read, and powerful as hell. It&#8217;s also pretty easy to pick up the basics of Ruby without too much trouble &#8212; but save yourself some time by checking out the following resources that have helped me loads.</p>
<p><span id="more-180"></span></p>
<ol>
<li><a href="http://ruby-lang.org/">Ruby-Lang.org</a>: Ruby&#8217;s website has some <a href="http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/">great tutorials</a> for developers coming from other languages. They&#8217;ll help you to take your first steps as a Ruby programmer.</li>
<li><a href="http://ruby-doc.org/">Ruby-Doc.org</a>: here you&#8217;ll learn what Ruby is capable of. RubyDoc has documentation for all of Ruby&#8217;s classes and modules: you&#8217;ll always learn something new.</li>
<li><a href="http://poignantguide.net/ruby/">why&#8217;s poignant guide</a>: a cartoon guide to Ruby. Funny and informative!</li>
<li><a href="http://www.rubyinside.com/">Ruby Inside</a>: this Ruby blog is a great way to discover new code created by the Ruby community.</li>
</ol>
<p>And of course, if you&#8217;re bored, you can always browse <a href="http://github.com/jameswilding">Github</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/12/learn-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clone TinyURL (and friends) with Rails</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F11%2Ftinyurl-rails%2F&amp;seed_title=Clone+TinyURL+%28and+friends%29+with+Rails</link>
		<comments>http://jameswilding.net/2009/08/11/tinyurl-rails/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 13:28:58 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=170</guid>
		<description><![CDATA[tr.im is closing down, and the blogs are a-chatter about why URL-shortening services are probably a bad idea if you care about your links, and why you should roll your own service if you can. Which is where Rails comes in. It&#8217;s possible to clone TinyURL using Sinatra, but I&#8217;m more interested in Rails (I [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tr.im/">tr.im is closing down</a>, and the blogs are a-chatter about why URL-shortening services are probably a <a href="http://www.zeldman.com/2009/08/10/shorten-this/">bad idea</a> if you care about your links, and why you should <a href="http://daringfireball.net/linked/2009/08/10/trim">roll your own service</a> if you can.</p>
<p>Which is where Rails comes in.</p>
<p><span id="more-170"></span><br />
It&#8217;s possible to clone TinyURL <a href="http://blog.saush.com/2009/04/13/clone-tinyurl-in-40-lines-of-ruby-code/">using Sinatra</a>, but I&#8217;m more interested in Rails (I think Rails probably scales better). The basic setup is so simple, it doesn&#8217;t take long to write the code, and with Rails you can always add extras like an admin interface later without much fuss.</p>
<h3>The code</h3>
<p>(If you&#8217;re feeling lazy, the entire URL-shortening app is <a href="http://github.com/jameswilding/shrink/">available on Github</a>)</p>
<p>My TinyURL-like Rails app &#8212; I call it &#8220;Shrink&#8221; &#8212; has three main components: routes, controller, and model. Routes first:</p>
<p>[ruby]<br />
ActionController::Routing::Routes.draw do |map|</p>
<p>  map.resources :locations, :only =&gt; [:new, :create]</p>
<p>  map.with_options :controller =&gt; &#8216;locations&#8217; do |map|<br />
    map.root :action =&gt; &#8216;new&#8217;<br />
    map.preview   &#8216;/:shrunken/preview&#8217;, :action =&gt; &#8216;preview&#8217;<br />
    map.location  &#8216;/:shrunken&#8217;, :action =&gt; &#8216;redirect&#8217;<br />
  end</p>
<p>end<br />
[/ruby]</p>
<p>&#8220;Locations&#8221; are the web pages we&#8217;ll be redirecting people to when they click on a short URL.</p>
<p>As you can probably tell, this routes file gives us RESTful routes for creating new locations, along with a catch-all <code>shrunken</code> route which we&#8217;ll use to intercept our short URLs and redirect them. There&#8217;s also a <code>preview</code> route (more on this in a bit), and I&#8217;ve mapped the root path (&#8216;/&#8217;) to the <code>new</code> action on <code>LocationsController</code> &#8212; this will expose the form for shortening URLs on our site&#8217;s home page.</p>
<h3>The Controller</h3>
<p>We only need one controller, with just a few short methods:</p>
<p>[ruby]<br />
class LocationsController &lt; ApplicationController</p>
<p>  def new<br />
    @location = Location.new<br />
  end</p>
<p>  def preview<br />
    @location = Location.find_by_short_url(params[:shrunken])<br />
  end</p>
<p>  def redirect<br />
    @location = Location.find_by_short_url(params[:shrunken])<br />
    redirect_to @location.url<br />
  end</p>
<p>  def create<br />
    @location = Location.new(params[:location])</p>
<p>    if @location.save<br />
      redirect_to preview_path(@location)<br />
    else<br />
      flash[:notice] = &#8216;Invalid URL&#8217;<br />
      render :action =&gt; &quot;new&quot;<br />
    end<br />
  end</p>
<p>end<br />
[/ruby]</p>
<p>That&#8217;s simple enough &#8212; the only thing to note is that we&#8217;re using <code>Location. find_by_short_url</code> instead of <code>Location.find</code>, so we can use slugs like &#8216;a1b3c&#8217; instead of database record IDs in our URLs.</p>
<p>The preview action, by the way, just renders a view which shows the user the shortened version of their URL so they can copy and paste it into Twitter (or whatever).</p>
<h3>The Model</h3>
<p>[ruby]<br />
class Location &lt; ActiveRecord::Base</p>
<p>  validates_presence_of :url<br />
  before_create         :validate_url</p>
<p>  class &lt;&lt; self<br />
    def find_by_short_url(shrunk)<br />
      find(shrunk.to_i(36))<br />
    end<br />
  end</p>
<p>  def to_param<br />
    id.to_s(36)<br />
  end</p>
<p>  private<br />
  def validate_url<br />
    false unless url_valid?(URI.parse(self.url))<br />
  end</p>
<p>  def url_valid?(url)<br />
    url.kind_of?(URI::HTTP) || url.kind_of?(URI::HTTPS)<br />
  end</p>
<p>end<br />
[/ruby]</p>
<p>The model implements our <code>find_by_short_url method</code>, implements some validations, and overrides Rails&#8217; default <code>to_param</code> to provide TinyURL-like short URLs. <code>to_param</code> is used in <code>url_for</code>; the method normally returns an object&#8217;s database ID, for URLs like /people/1, but here we return a short string like &#8216;a1c&#8217; instead.</p>
<p>Note the calls to to_s(36) and to_i(36): these convert record IDs into shorter URL slugs, and back again, using base 36 numbering. By using base 36, we can keep our URLs as short as possible: 10000 in base 10 is &#8217;7ps&#8217; in base 36. Read more about this useful feature of Ruby at <a href="http://www.ruby-doc.org/core/classes/String.html#M000787">ruby-doc.org</a>.</p>
<h3>Putting it all together</h3>
<p>The code for this app is open-source and is <a href="http://github.com/jameswilding/shrink">available on Github</a>; download, run script/server, and go to http://0.0.0.0:3000/ and you&#8217;ll see it in action. Proof that you can clone TinyURL using Rails in less than an hour!</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/11/tinyurl-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>iPhone on Rails</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F10%2Fiphone-on-rails%2F&amp;seed_title=iPhone+on+Rails</link>
		<comments>http://jameswilding.net/2009/08/10/iphone-on-rails/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 09:27:41 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[iphone]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=153</guid>
		<description><![CDATA[It&#8217;s really simple to get a Rails application to serve custom views to an iPhone or iPod touch: so simple, in fact, that in a spare half-an-hour I wrapped the necessary code up into a tiny plugin, which will do all the work for you! Update: if you&#8217;re using the plugin, have questions, or have [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s really simple to get a Rails application to serve custom views to an iPhone or iPod touch: so simple, in fact, that in a spare half-an-hour I wrapped the necessary code up into <a href="http://github.com/jameswilding/iphoneification">a tiny plugin</a>, which will do all the work for you!</p>
<p><strong>Update:</strong> if you&#8217;re using the plugin, have questions, or have found this post useful, take a moment to <a title="My Github profile" href="http://github.com/jameswilding">send me a message on Github</a>, or email me (james at this domain). It&#8217;s always great to know how people are using my work :)</p>
<p><span id="more-153"></span></p>
<p>If you just want to get up and running as fast as possible, skip to the <strong>Plugin</strong> section at the end of the article. Feedback is always appreciated; if you use the plugin, or have questions, feel free to email me (james at this domain).</p>
<p>If you want to understand how the plugin works, read the full article.</p>
<h3>Three Simple Steps</h3>
<p>There are basically three steps to serving custom iPhone content from Rails:</p>
<ol>
<li>Register a custom <code>iphone</code> format</li>
<li>Tell Rails how to recognize an iPhone request</li>
<li>Tell Rails to use the custom format for iPhone requests</li>
</ol>
<h3>Registering a custom iPhone format</h3>
<p>Rails already knows about formats like HTML and XML, and all iPhones actually need from a Rails app is plain old HTML &#8212; but we need a way to distinguish our iPhone HTML from the HTML we send to other browsers.</p>
<p>To do this, we register a mime type alias &#8212; just a way of telling Rails that when we say &#8216;iphone&#8217;, we mean &#8216;HTML&#8217;. This is done in config/initializers/mime_types.rb:</p>
<p>[ruby]<br />
Mime::Type.register_alias &#8220;text/html&#8221;, :iphone<br />
[/ruby]</p>
<p>Now we can do something like <code>format.iphone</code> and Rails will know we want it to serve our views as HTML.</p>
<h3>Tell Rails how to recognize an iPhone request</h3>
<p>In order to serve custom views to iPhones, we need a way of recgonizing when someone is viewing our website on an iPhone. This is easy:</p>
<p>[ruby]<br />
class ApplicationController &lt; ActionController::Base</p>
<p># other code here</p>
<p>private<br />
# detect iphone requests<br />
def iphone_request?<br />
(agent = request.env["HTTP_USER_AGENT"]) &amp;&amp;<br />
agent[/(Mobile\/.+Safari)/]<br />
end<br />
end<br />
[/ruby]</p>
<p>The <code> iphone_request?</code> method looks for MobileSafari&#8217;s <a href="http://en.wikipedia.org/wiki/User_agent">user agent</a> string in the incoming HTTP request. Because <a href="http://www.apple.com/iphone/iphone-3gs/safari.html">MobileSafari</a> runs on the iPod Touch as well as on the iPhone, this method will ensure that we serve our custom views to both devices.</p>
<p>Now we can identify iPhone requests, we just need to put everything together and&#8230;</p>
<h3>Tell Rails to use our custom format for iPhone requests</h3>
<p>Normally, when Rails receives a request from a browser, it determines what sort of response the browser is looking for (XML, HTTP, JSON, etc). Then it looks for corresponding templates &#8212; index.html.erb, index.xml.erb, etc. This behaviour is customizable using ActionController&#8217;s <code>respond_to</code> method.</p>
<p>In order to serve custom views to the iPhone, we need to tell Rails to switch to our custom :iphone format whenever an iPhone visits our website. This sounds complicated, but is easy:</p>
<p>[ruby]<br />
class ApplicationController &lt; ActionController::Base</p>
<p>before_filter :adjust_format_for_iphone_requests</p>
<p>private<br />
def adjust_format_for_iphone_requests<br />
request.format = :iphone if iphone_request?<br />
end<br />
end<br />
[/ruby]</p>
<p>This little snippet calls our <code>iphone_request?</code> method and tells Rails to use our iphone format where appropriate.</p>
<p>That&#8217;s really all there is to it. You can now create index.iphone.erb, show.iphone.erb, etc, alongside your standard HTML views and layouts, and Rails will serve them up to iPhone users. Bon appetit!</p>
<h3>The Plugin</h3>
<p>Serving custom iPhone content is something I want to do from many Rails apps, so I wrapped the functionality outlined above into <a href="http://github.com/jameswilding/iphoneification">a plugin for quick and easy iphoneification</a>. Install thus:</p>
<p>[bash]<br />
script/plugin install git://github.com/jameswilding/iphoneification.git<br />
[/bash]</p>
<p>To use the plugin, just add one line to your application controller:</p>
<p>[ruby]<br />
class ApplicationController<br />
responds_to_iphone<br />
end<br />
[/ruby]</p>
<p>If there&#8217;s a particular controller or action that you don&#8217;t want to serve iPhone content from, use</p>
<p>[ruby]<br />
class NotAnIPhoneController<br />
skip_iphone_response<br />
end<br />
[/ruby]</p>
<p>The plugin does most of the work: all you need to do is name your custom iPhone template <code>{template_name}.iphone.erb</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/10/iphone-on-rails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Bowline: Desktop Apps with Ruby</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F07%2Fbowline%2F&amp;seed_title=Bowline%3A+Desktop+Apps+with+Ruby</link>
		<comments>http://jameswilding.net/2009/08/07/bowline/#comments</comments>
		<pubDate>Fri, 07 Aug 2009 18:13:21 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=149</guid>
		<description><![CDATA[Bowline is a Ruby GUI framework that allows you to build desktop applications using Ruby, HTML, CSS, and JQuery. Sounds interesting? I thought so too! Bowline works in combination with Titanium, which lets you: Use Web technologies to create rich applications for Windows, Mac and Linux from a single code base. I think Bowline looks [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://leadthinking.com/191-bowline-a-ruby-gui-framework">Bowline</a> is a Ruby GUI framework that allows you to build desktop applications using Ruby, HTML, CSS, and JQuery. Sounds interesting? I thought so too!</p>
<p><span id="more-149"></span></p>
<p>Bowline works in combination with <a href="http://www.appcelerator.com/products/titanium-desktop/">Titanium</a>, which lets you:</p>
<blockquote><p>Use Web technologies to create rich applications for Windows, Mac and Linux from a single code base.</p></blockquote>
<p>I think Bowline looks awesome. Desktop apps using Ruby, WebKit, HTML 5 &#8212; all the best stuff if you&#8217;re a web development geek like me.</p>
<p>It&#8217;s difficult to summarise how Bowline works (although it&#8217;s a little like <a href="http://rubyonrails.org/">Rails</a>), so I recommend that you read <a title="Bowline - A Ruby GUI Framework" href="http://leadthinking.com/191-bowline-a-ruby-gui-framework">the author&#8217;s blog post introducing the framework</a>. Let&#8217;s hope Bowline grows into a stable, mature framework that does for desktop apps what Rails has done for the web.</p>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/07/bowline/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 3</title>
		<link>http://jameswilding.net/feeder/?FeederAction=clicked&amp;feed=Posts+%28RSS2%29&amp;seed=http%3A%2F%2Fjameswilding.net%2F2009%2F08%2F05%2Frails-3%2F&amp;seed_title=Rails+3</link>
		<comments>http://jameswilding.net/2009/08/05/rails-3/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 15:34:26 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jameswilding.net/?p=140</guid>
		<description><![CDATA[Well, I&#8217;ve been away from WordPress for a while thanks to flu (swine? maybe), and I thought a good way to break the silence would be with a post on the upcoming release of Rails: version 3. As you may know, Rails 3 is a major re-working of the Rails internals &#8212; and &#8216;internals&#8217; is [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I&#8217;ve been away from WordPress for a while thanks to flu (swine? maybe), and I thought a good way to break the silence would be with a post on the upcoming release of Rails: version 3.</p>
<p><span id="more-140"></span></p>
<p>As you may know, Rails 3 is a major re-working of the Rails internals &#8212; and &#8216;internals&#8217; is the important word. Rails 3 will <em>not</em> introduce any major changes the the way Rails works for the normal Rails developer. If you compare Rails 3 application code to Rails 2 application code, you won&#8217;t see much difference.</p>
<p>Where you will see differences is in the Rails framework code &#8211; the stuff that implements features like routes, <code>respond_to</code>, <code>render</code>, and resources. Its fair to say that this code has undergone major changes &#8212; the guts have been ripped out and the whole framework has been put back together in a new way.</p>
<p>Of course it&#8217;s a testament to Rail&#8217;s strengths as a framework that a major refactoring of its code base is possible. It&#8217;s also testament to the skill of the people who are working on the code &#8212; the original Rails core team, plus new members from Merb. I&#8217;ve been following <a href="http://yehudakatz.com/">Yehuda Katz&#8217;s blog</a> (he&#8217;s one of the guys who developed <a href="http://merbivore.com/">Merb</a>) and the things he&#8217;s written about his work on Rails 3 have been really interesting.</p>
<p>In particular, Katz&#8217;s approach focuses more on the benefits of a well-organised Rails code base, and less on the pragmatic &#8220;make it cool as fast as possible&#8221; approach which seems to have characterised Rails up to now. That&#8217;s not to knock the later &#8212; Rails wouldn&#8217;t be where it is today if people hadn&#8217;t been willing to turn a blind eye to overly-complicated code or poor internal structures.</p>
<p>But these new changes are good: Rails will be as easy and as fun to use for serious developers (of plugins, for instance) as it always has been for front-end designers and application builders. It really feels like we&#8217;re getting the best of both worlds.</p>
<p>If you&#8217;re interested in learning more about the philosophy behind Rails 3, I recommend the following:</p>
<ul>
<li>Yehuda Katz&#8217;s <strong><a href="http://yehudakatz.com/tags/ruby/ruby-on-rails/">posts about his work refactoring Rails</a></strong></li>
<li><strong><a href="http://railsconf.blip.tv/file/2081411/">DHH&#8217;s RailsConf keynote</a></strong></li>
<li><strong><a href="http://skillsmatter.com/podcast/ajax-ria/yehuda-katz-interfaces-and-the-future-of-ruby-keynote">This presentation</a></strong> from a London Rails conference, which explains more about the thinking behind the Rails refactor. Treat the video like a radio show, because the picture quality is pretty bad.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://jameswilding.net/2009/08/05/rails-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
