<?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>Jan Varwig &#187; Ruby</title>
	<atom:link href="http://jan.varwig.org/archive/tag/ruby/feed" rel="self" type="application/rss+xml" />
	<link>http://jan.varwig.org</link>
	<description>Somewhere between Hello World and HAL9000</description>
	<lastBuildDate>Wed, 17 Mar 2010 11:12:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>REST in Place: Major update ahead</title>
		<link>http://jan.varwig.org/archive/rest-in-place-major-update-ahead</link>
		<comments>http://jan.varwig.org/archive/rest-in-place-major-update-ahead#comments</comments>
		<pubDate>Mon, 25 Jan 2010 00:08:44 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[inplace editor]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rest in place]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/?p=237</guid>
		<description><![CDATA[This week, I&#8217;ll roll out a major update to REST in Place. I have completely restructured the code and made the Plugin much more object-oriented, modular and maintainable. Existing installations should be able to upgrade without a hitch. The most important change for users will be the jQuery 1.4 support and support for different editors [...]]]></description>
			<content:encoded><![CDATA[<p>This week, I&#8217;ll roll out a major update to <a href="http://github.com/janv/rest_in_place/">REST in Place</a>. I have completely restructured the code and made the Plugin much more object-oriented, modular and maintainable. Existing installations should be able to upgrade without a hitch. The most important change for users will be the jQuery 1.4 support and support for different editors (such as textarea, checkbox, etc.).</p>

<p>In November I got some pull requests for REST in Place which I didn&#8217;t get to really have a look at until last week. I haven&#8217;t really touched REST in Place in ages and wasn&#8217;t really aware that it was that popular. It has 72 followers and 11 forks on github and who knows how many other people are just silently using it! So, I merged in the contributions and dealt with some issues in the tracker and thought about how to go on.</p>

<p>REST in Place originally was a mere proof of concept and one of my first projects in JavaScript and jQuery. I have since written a lot more complicated applications and even a diploma thesis on JavaScript and the old code just isn&#8217;t up to my standards anymore. Additionally I have received several pull requests for textarea support which all couldn&#8217;t be merged because they were just copypasted and modified a little from the input-tag version. The only solution was a complete rewrite and that&#8217;s what I did. While the plugin still works the same way, the code is properly split up and more modular now. This enables easy extension and maintenance from now on and hopefully quicker development from me and better patches from all users.</p>

<p>This new development has some drawbacks too, unfortunately. This massive improvement will only go to the jQuery version of REST in Place. Since I don&#8217;t know much about Prototype or mootools, I can&#8217;t support both versions anymore. If someone is willing to work with me on this, I&#8217;ll happily accept their contributions but I can&#8217;t do this on my own. If anyone is willing to do so, please reply in the comments, so we can work out a plan. I want to keep all three versions as similar as possible, this means the Prototype and mootools versions should follow the same object-oriented structure as the jQuery version.</p>

<p>One last thing: I will support jQuery &lt; 1.4 until 1.4.1 comes out. 1.4 introduced some very nice changes which I&#8217;d like to make use of but since 1.4 seems a little buggy still, I&#8217;ll continue to support the older versions for a little while.</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/rest-in-place-major-update-ahead/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails Extremcrashkurs</title>
		<link>http://jan.varwig.org/archive/ruby-on-rails-extremcrashkurs</link>
		<comments>http://jan.varwig.org/archive/ruby-on-rails-extremcrashkurs#comments</comments>
		<pubDate>Fri, 27 Mar 2009 01:05:56 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[crashkurs]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/?p=155</guid>
		<description><![CDATA[(Sorry, content in german only for this post)

Ende 2007 habe ich bei 9elements einen Crashkurs zu Ruby on Rails gegeben.
Da mich inzwischen schon mehrere Leute gefragt haben ob ich die Folien nicht mal rausgeben möchte, tue ich das jetzt.
Die Folien sind absichtlich so gestaltet, dass sie auch ausserhalb des Vortrags als Nachschlagewerk für Ruby dienen [...]]]></description>
			<content:encoded><![CDATA[<p>(Sorry, content in german only for this post)</p>

<p>Ende 2007 habe ich bei <a href="http://www.9elements.com/">9elements</a> einen Crashkurs zu Ruby on Rails gegeben.
Da mich inzwischen schon mehrere Leute gefragt haben ob ich die Folien nicht mal rausgeben möchte, tue ich das jetzt.
Die Folien sind absichtlich so gestaltet, dass sie auch ausserhalb des Vortrags als Nachschlagewerk für Ruby dienen können.
Der Rails-Teil ist ein wenig arg knapp gehalten und kann vor allem einen groben Überblick in den Aufbau des Frameworks geben.</p>

<p><a href='http://jan.varwig.org/wp-content/uploads/2009/03/ruby-rails.pdf'>Ruby &amp; Rails Extremcrashkurs</a> (PDF-Link) v1.0 27.03.09</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/ruby-on-rails-extremcrashkurs/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting started with Ruby on Rails</title>
		<link>http://jan.varwig.org/archive/getting-started-with-ruby-on-rails</link>
		<comments>http://jan.varwig.org/archive/getting-started-with-ruby-on-rails#comments</comments>
		<pubDate>Fri, 20 Mar 2009 10:43:23 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[rubyonrails]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/?p=144</guid>
		<description><![CDATA[Today Smashing Magazine published an article I wrote last week about Ruby on Rails.
Instead of just doing another tutorial, I gave a rough overview of how Rails works,
together with a lot of praise of the language and the framework.

I tried to spark interest in Rails and Ruby and judging from the first comments I think [...]]]></description>
			<content:encoded><![CDATA[<p>Today Smashing Magazine published an <a href="http://smashingmagazine.com/2009/03/19/getting-started-with-ruby-on-rails/">article I wrote last week about Ruby on Rails</a>.
Instead of just doing another tutorial, I gave a rough overview of how Rails works,
together with a lot of praise of the language and the framework.</p>

<p>I tried to spark interest in Rails and Ruby and judging from the first comments I think it worked :)</p>

<p>The text released today is only the first part, covering just enough Ruby to understand the second part coming out next week. If you like the article, please digg it or promote it on reddit/delicious/slashdot.</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/getting-started-with-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>REST in Place now Rails 2.0 compatible</title>
		<link>http://jan.varwig.org/archive/rest-in-place-now-rails-20-compatible</link>
		<comments>http://jan.varwig.org/archive/rest-in-place-now-rails-20-compatible#comments</comments>
		<pubDate>Fri, 27 Jun 2008 17:41:27 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[on Rails]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[rest in place]]></category>
		<category><![CDATA[rubyonrails]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/?p=86</guid>
		<description><![CDATA[Ever since Rails 2.0 came out, my REST in Place Plugins stopped working because of the request forgery protecting introduced into ActiveController. The AJAX request didn&#8217;t submit the rails authenticity token and the requests weren&#8217;t answered.

I fixed that problem yesterday in both the jQuery and the Prototype version (both included in the plugin.)

Check it out [...]]]></description>
			<content:encoded><![CDATA[<p>Ever since Rails 2.0 came out, my REST in Place Plugins stopped working because of the request forgery protecting introduced into ActiveController. The AJAX request didn&#8217;t submit the rails authenticity token and the requests weren&#8217;t answered.</p>

<p>I fixed that problem yesterday in both the <a href="http://www.jquery.com/">jQuery</a> and the <a href="http://www.prototypejs.org/">Prototype</a> version (both included in the plugin.)</p>

<p>Check it out on the <a href="/projects/rest-in-place">REST in Place</a> project page.</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/rest-in-place-now-rails-20-compatible/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails: Determine the association collection size through joins</title>
		<link>http://jan.varwig.org/archive/rails-association-collection-size-though-joins</link>
		<comments>http://jan.varwig.org/archive/rails-association-collection-size-though-joins#comments</comments>
		<pubDate>Sun, 01 Jun 2008 15:25:21 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[on Rails]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[associations]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[joins]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[rubyonrails]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/?p=82</guid>
		<description><![CDATA[Rails association collections know two ways to determine their size:


Through a dumb count as soon as you query the collection for its size.
This doesn&#8217;t require any additional work but puts quite a load on the database as soon as you have a large list of objects and want to know the size of an associated [...]]]></description>
			<content:encoded><![CDATA[<p>Rails association collections know two ways to determine their size:</p>

<ol>
<li><strong>Through a dumb count as soon as you query the collection for its size.</strong><br />
This doesn&#8217;t require any additional work but puts quite a load on the database as soon as you have a large list of objects and want to know the size of an associated collection for each object. For 100 posts with comments, this approach would query the database 100 times with <code>SELECT count(*) AS count_all FROM</code>comments<code>WHERE (comments.post_id = 1234)</code>. This might be okay for single objects which are queried from time to time but not for collections that need to be displayed frequently.</li>
<li><strong>Through counter caches that are a bit of a pain in the ass to set up correctly and gave me the fishy impression that they are easily corrupted.</strong>
Now, I admit that I didn&#8217;t spend too long investigating the implementation of the counter cache but after fiddling around with it for an hour before I finally found out how to properly initialize the cache in my migration and after discovering that the cache can only be changed relative to its current content, I left with a bad feeling.<br />
All this hassle is absolutely unavoidable if you need maximum performance. In this article I&#8217;ll use blogposts and comments as an example, though only because this is familiar to many people. A real blog with a bunch of posts on its index page, receiving any considerable amount of hits per day is a bad candidate for the trick I describe here.</li>
</ol>

<p>In raw SQL, if you want to find out the amount of associated rows in a different table, you use a <code>JOIN</code>, combined with <code>COUNT()</code> and <code>GROUP BY</code>, like this:</p>

<div class="dean_ch" style="white-space: wrap;"><span class="kw1">SELECT</span> posts.*, COUNT<span class="br0">&#40;</span>comments.id<span class="br0">&#41;</span> <span class="kw1">AS</span> comments_count<br />
<span class="kw1">FROM</span> posts<br />
<span class="kw1">LEFT</span> <span class="kw1">OUTER</span> <span class="kw1">JOIN</span> comments <span class="kw1">ON</span> posts.id = comments.post_id<br />
<span class="kw1">GROUP</span> <span class="kw1">BY</span> posts.id</div>

<p>Admittedly, this is slower than a counter cache but is not as difficult to set up, doesn&#8217;t risk errors due to a corrupt cache and if you chose your database keys wisely it is a pretty nice compromise.
When you ask an association collection for its <code>size()</code>, rails checks for the presence of a counter cache attribute in the current ActiveRecord object. If it finds one, it uses its content to return the collection size, otherwise the database is queried.</p>

<p>The catch is now, that in the above example, we inserted a perfectly valid counter cache column into our posts without specifying caching in the association declaration in the class. ActiveRecord inserts that columns content into a <code>comments_count</code> attribute in our Posts but since it doesn&#8217;t know exactly what to do with it, it doesn&#8217;t cast it into an integer but leaves it in there as a String. That makes <code>size()</code>, or to be more precise, the <code>count_records()</code> method trip with a &#8220;String can&#8217;t be coerced into Fixnum&#8221; error.</p>

<p>To fix this, I wrote an extension for the has_many Association:</p>

<div class="dean_ch" style="white-space: wrap;"><span class="kw1">module</span> OptionalJoinCounter<br />
&nbsp; <span class="kw1">def</span> count_records<br />
&nbsp; &nbsp; count = <span class="kw1">if</span> has_cached_counter?<br />
&nbsp; &nbsp; &nbsp; <span class="re1">@owner</span>.<span class="me1">send</span><span class="br0">&#40;</span><span class="re3">:read_attribute</span>, cached_counter_attribute_name<span class="br0">&#41;</span>.<span class="me1">to_i</span><br />
&nbsp; &nbsp; <span class="kw1">elsif</span> <span class="re1">@reflection</span>.<span class="me1">options</span><span class="br0">&#91;</span><span class="re3">:counter_sql</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re1">@reflection</span>.<span class="me1">klass</span>.<span class="me1">count_by_sql</span><span class="br0">&#40;</span>@counter_sql<span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; <span class="re1">@reflection</span>.<span class="me1">klass</span>.<span class="me1">count</span><span class="br0">&#40;</span><span class="re3">:conditions</span> =&gt; <span class="re1">@counter_sql</span>, <span class="re3">:include</span> =&gt; <span class="re1">@reflection</span>.<span class="me1">options</span><span class="br0">&#91;</span><span class="re3">:include</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="re1">@target</span> = <span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="kw1">and</span> loaded <span class="kw1">if</span> count == <span class="nu0">0</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="re1">@reflection</span>.<span class="me1">options</span><span class="br0">&#91;</span><span class="re3">:limit</span><span class="br0">&#93;</span><br />
&nbsp; &nbsp; &nbsp; count = <span class="br0">&#91;</span> <span class="re1">@reflection</span>.<span class="me1">options</span><span class="br0">&#91;</span><span class="re3">:limit</span><span class="br0">&#93;</span>, count <span class="br0">&#93;</span>.<span class="me1">min</span><br />
&nbsp; &nbsp; <span class="kw1">end</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw2">return</span> count<br />
&nbsp; <span class="kw1">end</span><br />
<span class="kw1">end</span></div>

<p>Uh, well, yeah, the only change here is the <code>.to_i</code> at the end of line 4 but hey, what did you expect?</p>

<p>Save that in <code>lib/optional_join_counter.rb</code> and extend your association with <code>has_many :whatevers, :extend =&gt; OptionalJoinCounter</code></p>

<p>Now, to get back to the example, imagine we want to use this trick to count our comments.
The above SQL can either be written by hand, or with Rails finder options:</p>

<div class="dean_ch" style="white-space: wrap;">Post.<span class="me1">find</span> <span class="re3">:all</span>,<br />
&nbsp; <span class="re3">:select</span> =&gt; <span class="st0">&#8216;posts.*, count(comments.id) as comments_count&#8217;</span>,<br />
&nbsp; <span class="re3">:joins</span> =&gt; <span class="st0">&#8216;LEFT JOIN comments ON posts.id = comments.post_id&#8217;</span>,<br />
&nbsp; <span class="re3">:group</span> =&gt; <span class="st0">&#8216;posts.id&#8217;</span></div>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/rails-association-collection-size-though-joins/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Language design philosophy: more than one way?</title>
		<link>http://jan.varwig.org/archive/language-design-philosophy-more-than-one-way</link>
		<comments>http://jan.varwig.org/archive/language-design-philosophy-more-than-one-way#comments</comments>
		<pubDate>Tue, 04 Mar 2008 09:40:03 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Tumblecontent]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/archiv/language-design-philosophy-more-than-one-way</guid>
		<description><![CDATA[Ola Bini manages to express my feelings about the difference between Ruby and Python:


  So what&#8217;s the point? Well, the point is Ruby. In fact, Ruby has almost all of the flexibility of Perl to do things in different ways. But at the end of the day, none of the Perl problems tend to [...]]]></description>
			<content:encoded><![CDATA[<p>Ola Bini manages to express my feelings about the difference between Ruby and Python:</p>

<blockquote>
  <p>So what&#8217;s the point? Well, the point is Ruby. In fact, Ruby has almost all of the flexibility of Perl to do things in different ways. But at the end of the day, none of the Perl problems tend to show up. Why is this? And why do I feel so comfortable in Ruby&#8217;s &#8220;There is more than one way to do it&#8221; philosophy, while the Perl one scares me?</p>
  
  <p>I think it comes down to language design. The Python approach is impossible for the simple reason that what the language designer chooses is going to be the &#8220;one way&#8221;, by fiat. Some people will agree, and some will not. But what I&#8217;m seeing in Ruby is that the many ways have been transformed into idioms and guidelines. There are no hard rules, but the community have evolutionary evolved idioms that work and found out many of the ways that doesn&#8217;t work. This seems to be the right way &#8211; if you do the choice as a language designer, you have actually chosen the people that will use your language: that&#8217;s going to be the persons who doesn&#8217;t dislike the language designers choices. But if you leave it open enough for evolutionary community design to happen you can actually get the best of both world: both a best way to do things, and something that works for a much larger percentage of the programmer world.</p>
</blockquote>

<p>&#8211; <a href="http://ola-bini.blogspot.com/2008/02/language-design-philosophy-more-than.html">http://ola-bini.blogspot.com/2008/02/language-design-philosophy-more-than.html</a></p>

<p>I like constraints, they can be liberating, but I also want to be treated as a grownup when it comes to breaking them. So Ruby&#8217;s socially suggested guidelines are much more comfortable to work with than Python&#8217;s enforced style.</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/language-design-philosophy-more-than-one-way/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One of those nights</title>
		<link>http://jan.varwig.org/archive/one-of-those-nights</link>
		<comments>http://jan.varwig.org/archive/one-of-those-nights#comments</comments>
		<pubDate>Thu, 03 Jan 2008 14:27:31 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[on Rails]]></category>
		<category><![CDATA[avi bryant]]></category>
		<category><![CDATA[evan phoenix]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[randal schwartz]]></category>
		<category><![CDATA[rubinius]]></category>
		<category><![CDATA[seaside]]></category>
		<category><![CDATA[smalltalk]]></category>
		<category><![CDATA[zed shaw]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/archiv/one-of-those-nights</guid>
		<description><![CDATA[Last night Zed Shaws Rails is a Ghetto Shitstorm was brought to my attention.
Zeds rant provides enough meat for a post of its own but it&#8217;s not what I want to write about today.
Following some comments on Zed article on Technorati I stumbled (again) into one of those evenings full of great discoveries.

Git

Shortly before Git [...]]]></description>
			<content:encoded><![CDATA[<p>Last night Zed Shaws <a href="http://www.zedshaw.com/rants/rails_is_a_ghetto.html">Rails is a Ghetto</a> Shitstorm was brought to my attention.
Zeds rant provides enough meat for a post of its own but it&#8217;s not what I want to write about today.
Following some comments on Zed article on Technorati I stumbled (again) into one of those evenings full of great discoveries.</p>

<h2>Git</h2>

<p>Shortly before <a href="http://git.or.cz/">Git</a> became really popular some months ago, I had become interested in <a href="http://www.darcs.net/">darcs</a> and distributed revision control systems in general.
The topic is kinda difficult though and none of the texts I was reading at the time could really communicate the benefits of DRCS to me.
I always had some gripes about svn but it wasn&#8217;t clear to me how DRCS were able to solve them.</p>

<p>I lost interest, following posts about git only loosely until last night a colleague pointed me to <a href="http://video.google.com/videoplay?docid=1251251453592758541">Randal Schwartz&#8217; Git presentation at Google Tech Talks</a>. Holy crap, I need to check this out. What appeals most to me:</p>

<ul>
<li><strong>The ability to have the entire repository available locally</strong><br />
I was extremely sceptical when I first heard about this, but when Schwartz claimed that the entire repository of the linux kernel is half the size of a checkout I was sold.</li>
<li><strong>Subversion interoperability</strong><br />
Didn&#8217;t know about this before. Makes the transition much easier.</li>
<li><strong>Having local-only repositories inside your working dir</strong><br />
I have many smaller projects that I&#8217;d love to keep locally contained. In Subversion I always had to create a repository on my server for everything.</li>
<li><strong>Other small things</strong><br />
High compression, the simple database system behind git, the optimization for speed, staged commits, the ability to completely erase files from a repository (e.g. stuff not intended for publication, something that was very hard to do on subversion), the placement of <em>all</em> metadata in a single directory (opposed to littering every dir in the working copy with <code>.svn</code> directories)</li>
</ul>

<p>Despite some shortcomings that was enough to make me install git on my mac (<code>sudo port install git-core</code>). I&#8217;m eager to check it out later today.</p>

<h2>Smalltalk and Seaside</h2>

<p>Ever since watching Evan Phoenix <a href="http://rubyconf2007.confreaks.com/d2t1p3_rubinius.html">Rubinius Presentation</a> at RubyConf 2007 and listening to Avi Bryants <a href="http://itc.conversationsnetwork.org/shows/detail3432.html">Smalltalk&#8217;s Lessons for Ruby</a> Keynote from RailsConf 2007 I&#8217;ve been curious about Smalltalk. I mean, I was curious about it before, after all it&#8217;s probably the language that has the most influence on what I&#8217;m doing today (through its promotion of object-orientation and through providing key principles behind ruby), but since listening to Avi and Evan I&#8217;ve become really interested in VM implementations (see <a href="http://users.ipa.net/~dwighth/smalltalk/bluebook/bluebook_imp_toc.html">Smalltalk-80: The Language and Its Implementation</a> for an excellent in-depth description of the orignal Smalltalk-80 interpreter) and real world usage of smalltalk.</p>

<p>To be honest, as much as I love Ruby as a language, its implementations all suck. And Evan explained why: Implementing most of the base language on another Platform (C for MRI, Java for JRuby) turns out to be a leaky abstraction when you want to extend the language. Additionally, as pure and beautiful the Ruby language is in concept, as ugly is its implementation. On the one hand, what I like so much about Ruby is its conceptual purity, its very limited set of axioms, syntax and exceptions from its own rules, on the other hand, this purity is not present in the interpreter when high-level data structures (like arrays and hashes) are implemented in C for performance reasons. Smalltalk has always had a strong philosophy of implementing as much as possible in Smalltalk itself and only resorting to C for a minimal subset (<a href="http://www.cincomsmalltalk.com/userblogs/avi/blogView?showComments=true&amp;entry=3284695382">&#8220;Turtles all the way down&#8221;</a>).</p>

<p><a href="http://www.rubini.us/">Rubinius</a> aims to implement a Ruby interpreter on the design principles of smalltalk. I love the project and there seem to be only the most brilliant people working on it (Evan Phoenix, Eric Hodel, Ryan Davis and others, full time). As many others have said already, Rubinius is likely to become the main Ruby implementation if they manage to take off (and they will undoubtedly).</p>

<p>Yet, something was bugging me: If Ruby and Smalltalk are so similar, if Smalltalk has been around, specified and stable for 25 years in many different, <em>compatible</em> implementations, commercial <em>and</em> open source, why take the long route and bend Ruby to look like Smalltalk? Why not use Smalltalk directly? These questions became even more nagging after reading Randal Schwartz&#8217; (yeah, the guy who sold me on Git earlier) <a href="http://methodsandmessages.vox.com/library/post/transcript-show-hello-world-cr.html">Transcript show: &#8216;Hello, world!&#8217;, cr</a>
and <a href="http://www.akitaonrails.com/">Fabio Akita</a>s excellent Interview with Avi Bryant (<a href="http://www.akitaonrails.com/2007/12/15/chatting-with-avi-bryant-part-1">part 1</a>, <a href="http://www.akitaonrails.com/2007/12/22/chatting-with-avi-bryant-part-2">part 2</a>).
Listening to yet <em>another</em> chat with Avi (linked in the second part of Fabio&#8217;s interview) at <a href="http://twit.tv/floss21">Floss Weekly</a> (with Randal Schwartz again, highly recommended) before falling asleep I finally decided to check out <a href="http://www.squeak.org/">Squeak</a>, the (most popular?) opensource Smalltalk implementation. I was amazed at the simplicity of the installation: Download the VM, Download the Squeak image, load the image into the VM, done.</p>

<p>I have read about <a href="http://www.seaside.st/">Seaside</a>, Avi&#8217;s web development framework, before, mainly in reagard to it&#8217;s clever use of continuations, but some of the stuff he described at Floss sound almost too good to be true. Live debugging of your app <em>in the browser</em> ? With hot code swapping over the wire? And I thought Rails&#8217; rdebug integration was great.</p>

<p>Well, at 2am I was finally falling asleep but the stuff I&#8217;ve been discovering will probably keep me occupied for quite some time.
As I explore and discover more about the topics mentioned, I&#8217;ll report my findings here on my blog.</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/one-of-those-nights/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Avi Bryant on Smalltalk</title>
		<link>http://jan.varwig.org/archive/avi-bryant-on-smalltalk</link>
		<comments>http://jan.varwig.org/archive/avi-bryant-on-smalltalk#comments</comments>
		<pubDate>Wed, 02 Jan 2008 21:16:39 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Tumblecontent]]></category>
		<category><![CDATA[avi bryant]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[smalltalk]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/archiv/avi-bryant-on-smalltalk</guid>
		<description><![CDATA[  What clicked about Smalltalk was a few things: one was simply the maturity, both of the community and of the technology. Smalltalk implementations have been refined over the last 25 years, and they’ve really benefited from it.
  
  One of the major benefits, in my opinion, is that Smalltalk VMs are [...]]]></description>
			<content:encoded><![CDATA[<blockquote>
  <p>What clicked about Smalltalk was a few things: one was simply the maturity, both of the community and of the technology. Smalltalk implementations have been refined over the last 25 years, and they’ve really benefited from it.</p>
  
  <p>One of the major benefits, in my opinion, is that Smalltalk VMs are fast enough that it’s reasonable to implement all of the standard libraries – Array, Hash, Thread, and so on – in Smalltalk itself. So there’s no barrier where you switch from your Ruby code to the underlying C implementation; it’s “turtles all the way down”. This may not seem like a big deal but once you have it, it’s really hard to give it up.</p>
</blockquote>

<p>&#8230;</p>

<blockquote>
  <p>In Smalltalk, you don’t have to choose one file layout or order of methods and classes in your code; you’re constantly switching views on what’s basically a database of code.</p>
  
  <p>My friend Brian Marick hates this, because you lose any “narrative” that might have existed by putting the code in a certain order in the file, and it’s hard to get used to, but for me, it’s the ultimate power tool for hacking on a large code-base.</p>
</blockquote>

<p>&#8211; <a href="http://www.akitaonrails.com/2007/12/15/chatting-with-avi-bryant-part-1">http://www.akitaonrails.com/2007/12/15/chatting-with-avi-bryant-part-1</a><br />
&#8211; <a href="http://www.akitaonrails.com/2007/12/22/chatting-with-avi-bryant-part-2">http://www.akitaonrails.com/2007/12/22/chatting-with-avi-bryant-part-2</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/avi-bryant-on-smalltalk/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>REST in Place</title>
		<link>http://jan.varwig.org/archive/rest-in-place</link>
		<comments>http://jan.varwig.org/archive/rest-in-place#comments</comments>
		<pubDate>Sun, 23 Dec 2007 13:57:01 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[on Rails]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[inplace editor]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rest]]></category>
		<category><![CDATA[ror]]></category>
		<category><![CDATA[rubyonrails]]></category>
		<category><![CDATA[web-2.0]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/archiv/rest-in-place</guid>
		<description><![CDATA[In Ajax vs. REST I wrote about my ideas for a RESTful inplace editor.

Well, after a day playing around with jQuery, I present REST in Place
]]></description>
			<content:encoded><![CDATA[<p>In <a href="/archiv/ajax-vs-rest">Ajax vs. REST</a> I wrote about my ideas for a RESTful inplace editor.</p>

<p>Well, after a day playing around with jQuery, I present <a href="/projects/rest-in-place">REST in Place</a></p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/rest-in-place/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>AJAX vs. REST</title>
		<link>http://jan.varwig.org/archive/ajax-vs-rest</link>
		<comments>http://jan.varwig.org/archive/ajax-vs-rest#comments</comments>
		<pubDate>Fri, 14 Dec 2007 23:30:09 +0000</pubDate>
		<dc:creator>Jan</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[on Rails]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[inplace editor]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rest]]></category>

		<guid isPermaLink="false">http://jan.varwig.org/archiv/ajax-vs-rest</guid>
		<description><![CDATA[A small shop I&#8217;ve been writing for for fathers pharmacy was a welcome playground for modeling my domain RESTful.
During my ventures, two big issues had me thinking quite hard for a while and there&#8217;s still no proper solution available. One of them was a DRY implementation of controllers for nested resources which I&#8217;ll describe later, [...]]]></description>
			<content:encoded><![CDATA[<p>A small shop I&#8217;ve been writing for for fathers pharmacy was a welcome playground for modeling my domain RESTful.
During my ventures, two big issues had me thinking quite hard for a while and there&#8217;s still no proper solution available. One of them was a DRY implementation of controllers for nested resources which I&#8217;ll describe later, the other one was the outdated <a href="http://svn.rubyonrails.org/rails/plugins/in_place_editing/">inplace editor plugin</a> in Rails.</p>

<p><span id="more-70"></span>
<h3>In-Place editing RESTful resources</h3></p>

<p>Writing applications in <a href="http://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm">REST</a>-style encourages an even stricter separation of view and controller logic than the usual Rails&#8217; stack.
A key principle is that the client alone should provide the user means to manipulate and PUT/POST data to the server. This is easier said than done in current browsers and with the HTML format (which just wasn&#8217;t made for building GUIs, but that&#8217;s a topic for another post). AJAX is the closest we can come to this ideal, enabling a seamless transition from a plain view of a resource to a editable form without going through too much pain.</p>

<p>A widely used way to achieve these transitions are inplace editors, made popular by Flickr and supported through nice helper methods in rails. The probem now is that these helper methods were written around, or even before Rails 1.0 with not the slightest hint of REST in them. Planting <code>in_place_edit_for :object, :attribute</code> in your controller creates a <code>set_object_attribute</code>  action that finds an object by id, updates only <code>attribute</code> and renders <code>attribute</code>s new value as a plain, short string to the client. The client, in this case the XMLHttpRequest, takes that response and puts it in the appropriate place in the HTML document.</p>

<p>There are several problems with this approach:</p>

<ol>
<li>The generated actions are extremely simple and devoid of any form of sophisticated flow control (authorization, exception handling)</li>
<li>The generated actions perform a task that can be done in the good old <code>update</code> action and are thusly redundant.</li>
<li>Those new actions aren&#8217;t at all RESTful.</li>
<li>Ideally, no special server side code should be necessary.</li>
</ol>

<p>While problem 1 can be easily countered by implementing your own version of <code>in_place_edit_for</code>, the real point are the other issues. The <code>update</code> action already performs the task of updating one or more attributes and is equipped with whatever authorization checks are necessary (does object belong to the logged in user?). The <code>update</code> action corresponds to the REST-verb <code>POST</code> and doesn&#8217;t violate REST principles.</p>

<p>A solution that solves all these problems would have to look like this (client-side Javascript only):</p>

<ul>
<li>The inplace editor posts to the objects url (something like <code>/object/123</code>), passing the attribute to be updated as a HTTP parameter.</li>
<li>The server sends a response when the update is completed successfully or unsuccessfully.</li>
<li>In case of an unsuccessful update some form of status could be transferred in the response</li>
<li>In case of a successful update, the server doesn&#8217;t send the updated attributes value, instead the client should GET
the object requesting a <em>text/json</em> content-type, extract the desired attribute from the json and update the HTML with its value.</li>
</ul>

<p>I already tried building my own inplace editor Javascript helper but since much of the functionality of the rails inplace editor depends on the the editor defined in script.aculo.us I gave up. On the one hand the problem wasn&#8217;t so pressing that I could justify spending a weekend digging through the source, on the other hand I&#8217;d really like to see a good jQuery integration in rails and think maybe I could hit two birds with one stone if I try to go this direction one day.</p>
]]></content:encoded>
			<wfw:commentRss>http://jan.varwig.org/archive/ajax-vs-rest/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
