<?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>Simone Carletti&#039;s Blog &#187; ruby</title>
	<atom:link href="http://www.simonecarletti.com/blog/tags/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.simonecarletti.com/blog</link>
	<description>Simone Carletti&#039;s personal ramblings on programming, syndication, search engines &#38; marketing.</description>
	<lastBuildDate>Thu, 12 Jan 2012 09:16:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Eloquent Ruby Book Review</title>
		<link>http://www.simonecarletti.com/blog/2011/10/eloquent-ruby/</link>
		<comments>http://www.simonecarletti.com/blog/2011/10/eloquent-ruby/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 09:49:25 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[reviews]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1522</guid>
		<description><![CDATA[Eloquent Ruby by Russ Olsen is a book about the Ruby programming language that focuses on Ruby programming style by teaching you how to write your code as a real Rubyist.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.simonecarletti.com/blog/out/amzcom-eloquentruby"><img class="alignleft" title="Book Eloquent Ruby" src="http://share.weppos.net/simonecarletti/book-addison-eloquentruby-20110930-194837.png" alt="Book Eloquent Ruby" height="250" /></a> <a href="http://www.simonecarletti.com/blog/out/amzcom-eloquentruby"><em>Eloquent Ruby</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-eloquentruby">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-eloquentruby">UK</a>) by Russ Olsen is a book about the Ruby programming language that focuses on <strong>Ruby programming style</strong> by teaching you how to write your code as a real Rubyist.</p>
<p>This is the second Olsen&#8217;s book about Ruby. In 2007 he published <a title="Design Patterns in Ruby Book Review" href="http://www.simonecarletti.com/blog/2009/03/book-review-design-patterns-in-ruby/">Design Patterns in Ruby</a>, an other great example of how common programming practices like Design Patterns apply to the Ruby world.</p>
<p>Eloquent Ruby is a very lightweight and pleasant reading. The colloquial tone is friendly and engrossing. The books has plenty of code snippets and it requires only a few days to read it from start to end.</p>
<p>Be prepared, <strong>this is an unconventional Ruby book</strong>. To use author&#8217;s words</p>
<blockquote><p>This is a book about making that final leap, about absorbing the Ruby programming culture, about becoming truly fluent in Ruby.</p></blockquote>
<p>This is something I have been claiming for the last 5 years. Learning Ruby is not difficult, start thinking in Ruby and becoming a Rubyist is the real challenge.</p>
<blockquote><p>A formal understanding of the mechanics of Ruby isn&#8217;t the same as really looking at the programming world through Ruby-colored glasses. You need to absorb the cultural part of Ruby, to see how real Rubyist use the language to solve problems.</p></blockquote>
<p>This is one of the reasons that convinced me to <a href="http://www.simonecarletti.com/blog/2011/09/the-rubyist/">create the Rubyist</a>.</p>
<h2><span id="more-1522"></span>Structure</h2>
<p>The book is divided into 4 parts:</p>
<ol>
<li>The Basics</li>
<li>Classes, Modules, and Blocks</li>
<li>Metaprogramming</li>
<li>Pulling It All Together</li>
</ol>
<p>Each part is divided into chapters. The book counts 31 chapters and about 400 pages.</p>
<p>The first part covers some <strong>basic Ruby features</strong> in a way you normally won&#8217;t read in any other Ruby reference. Ah, if I only had the Symbol chapter available when I started learning Ruby!</p>
<p>The second part covers <strong>Classes, Modules and Blocks</strong> and it explains how to use modules successfully, how to deal with inheritance, equality and operators. This is by far my most favorite section.</p>
<p>The third part is about <strong>Metaprogramming</strong>. Whilst the name of the section is technically correct, it can be misleading. If you are looking for a complete Ruby and Metaprogramming course, check out <a href="http://www.simonecarletti.com/blog/out/amzcom-metaprogrammingruby"><em>Metaprogramming Ruby</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-metaprogrammingruby">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-metaprogrammingruby">UK</a>). This section covers common Ruby metaprogramming topic such as hooks, method_missing (a must read!) and monkey patching.</p>
<p>The forth part wraps several topics all together and talks about <strong>creating and implementing a DSL</strong> in Ruby.</p>
<p>The book ends with a <strong>rich list of books about Ruby and programming in general</strong>. The list contains amazing Ruby titles like <a href="http://www.simonecarletti.com/blog/out/amzcom-rubybestpractices"><em>Ruby Best Practices</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-rubybestpractices">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-rubybestpractices">UK</a>) or <a href="http://www.simonecarletti.com/blog/out/amzcom-rubyway"><em>The Ruby Way Second Edition</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-rubyway">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-rubyway">UK</a>), as well programming masterpieces like <a href="http://www.simonecarletti.com/blog/out/amzcom-elprogstyle"><em>The Elements of Programming Style</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-elprogstyle">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-elprogstyle">UK</a>). If you are looking for some inspiration about your next reading, you might probably find some there.</p>
<h3>Chapters</h3>
<ol>
<li>Write Code That Looks Like Ruby</li>
<li>Choose the Right Control Structure</li>
<li>Take Advantage of Ruby&#8217;s Smart Collections</li>
<li>Take Advantage of Ruby&#8217;s Smart Strings</li>
<li>Find The Right String With Regular Expressions</li>
<li>Use Symbols to Stand for Something</li>
<li>Treat Everything Like an Object &#8211; Because Everything Is</li>
<li>Embrace Dynamic Typing</li>
<li>Write Specs!</li>
<li>Construct Your Classes from Short, Focused Methods</li>
<li>Define Operators Respectfully</li>
<li>Create Classes That Understand Equality</li>
<li>Get The Behavior You Need with Singleton and Class Methods</li>
<li>Use Class Instance Variables</li>
<li>Use Modules as Name spaces</li>
<li>Use Modules as Mixins</li>
<li>Use Blocks to Iterate</li>
<li>Execute Around with a Block</li>
<li>Save Blocks to Execute Later</li>
<li>Use Hooks to Keep Your Program Informed</li>
<li>Use method_missing for Flexible Error Handling</li>
<li>Use method_missing for Delegation</li>
<li>Use method_missing to Build Flexible APIs</li>
<li>Update Existing Classes with Monkey Patching</li>
<li>Create Self-Modifying Classes</li>
<li>Create Classes That Modify Their Subclasses</li>
<li>Invent Internal DSLs</li>
<li>Build External DSLs for Flexible Syntax</li>
<li>Package Your Programs as Gems</li>
<li>Know Your Ruby Implementation</li>
<li>Keep An Open Mind to Go With Those Open Classes</li>
</ol>
<h2>Requirements</h2>
<p>This book assumes that you have a basic knowledge of the Ruby language. You don&#8217;t need to be a Ruby master, but some advanced sections such as Metaprogramming and DSL may require you to stop for a moment and refresh or improve your specific knowledge of Ruby on that topic.</p>
<p>Don&#8217;t expect this book to explain you the basic details of Ruby or its syntax, this is behind the scope of this publication. There are plenty of commented examples, but if you want to learn about a specific Ruby feature make sure you keep a reference like <a href="http://www.simonecarletti.com/blog/out/amzcom-programmingruby"><em>Programming Ruby</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-programmingruby">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-programmingruby">UK</a>) or <a href="http://www.simonecarletti.com/blog/out/amzcom-rubyway"><em>The Ruby Way</em></a> (<a href="http://www.simonecarletti.com/blog/out/amzcom-rubyway">US</a> | <a href="http://www.simonecarletti.com/blog/out/amzuk-rubyway">UK</a>) handy.</p>
<p>Another requirement is that you must be ready to read printed source code: this book is full or Ruby code. At least the 50% of the pages contain code, making this book a valuable practical reference.</p>
<h2>Plus</h2>
<p>Aside from being an excellent resource to help you thinking Ruby and programming in the Ruby way, this book constantly adopts a practical approach providing tons of examples to read. Every chapter ends with an <em>In the Wild</em> section containing examples extracted from real Ruby libraries, and a <em>Wrapping up</em> section that helps you to fix the concepts in mind.</p>
<p>As as long time Ruby developer I really loved the <em>Use Symbols to Stand for Something</em>, object and block chapters. Some of them didn&#8217;t necessary teach anything new, but the way used to present the concepts was very helpful and understandable.</p>
<p>I appreciate the focus on tests and the RSpec chapter. The most part of Ruby books dedicate a specific section about tests, then seem to forget them for the rest of the chapters. This is not the case of this book, where several examples are verified by tests.</p>
<p>Finally, the simple colloquial tone makes the book really friendly. It seems like a person you always worked with is now teaching you programming and thinking in the Ruby way.</p>
<h2>Minus</h2>
<p>It&#8217;s really hard to find some real negative in this book.</p>
<p>I found the Regular Expression chapter pretty boring and misplaced. In fact, it was the only chapter in the book where the main focus was teaching Regular Expression basics, instead of focusing on using Regular Expressions in the right way.</p>
<p>The same applies to the RubyGems sections. There have been several changes in the Gems community in the last years and the chapter appears to be slightly outdated. Again, I would have left this topic outside the book.</p>
<p>Finally, I would have appreciated a wider usage of Ruby 1.9 over 1.8 in order to discourage the adoption of Ruby 1.8.</p>
<h2>In Conclusion</h2>
<p>If you are a beginner to intermediate level Ruby programmer, this book is a must read that it&#8217;s likely to help you improving your Ruby skill and writing code in the Ruby way.</p>
<p>If you are completely new to Ruby, personally don&#8217;t recommend this book as a first reading. You might want to start with a Ruby reference to learn how programming in Ruby, then read Eloquent Ruby to learn how programming in the Ruby way. Also, don&#8217;t forget about <a href="http://rubyist.info/">the Rubyist</a>, you&#8217;ll find several Ruby common practices and coding conventions.</p>
<p>If you are a Ruby expert and you have been writing Ruby for the last 5 years, don&#8217;t be too self-confident. I&#8217;m quite sure the book will be able to provide you some valuable advice more than once.</p>
<h2>Where to Find Eloquent Ruby</h2>
<p>You can get a printed or Kindle copy at <a href="http://www.simonecarletti.com/blog/out/amzcom-eloquentruby">Amazon.com</a>, <a href="http://www.simonecarletti.com/blog/out/amzuk-eloquentruby">Amazon.co.uk</a>, or at your other favorite book seller.</p>
<h3>Kindle Preview</h3>
<div id="kindle-reader">.</div>
<p><script type="text/javascript" src="http://kindleweb.s3.amazonaws.com/app/KindleReader-min.js"></script><script type="text/javascript">// <![CDATA[
                            KindleReader.LoadSample({containerID: 'kindle-reader', asin: 'B004MMEJ36', width: '600', height: '599', assoctag: 'simonecarletti-20'});
// ]]&gt;</script></p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/03/book-review-design-patterns-in-ruby/' rel='bookmark' title='Design Patterns in Ruby Book Review'>Design Patterns in Ruby Book Review</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/03/book-review-learning-jquery/' rel='bookmark' title='Learning jQuery 1.3 Book Review'>Learning jQuery 1.3 Book Review</a></li>
<li><a href='http://www.simonecarletti.com/blog/2011/03/book-review-getting-real/' rel='bookmark' title='Getting Real Book Review'>Getting Real Book Review</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/10/eloquent-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Sprockets without a Rails/Rack project</title>
		<link>http://www.simonecarletti.com/blog/2011/09/using-sprockets-without-a-railsrack-project/</link>
		<comments>http://www.simonecarletti.com/blog/2011/09/using-sprockets-without-a-railsrack-project/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 15:28:56 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[coffeescript]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sprockets]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1485</guid>
		<description><![CDATA[An example of using Sprockets to preprocess and bundle CSS and JavaScript files without a Rails application.]]></description>
			<content:encoded><![CDATA[<p><a href="http://getsprockets.org/">Sprockets</a> is a Ruby library for compiling and serving web assets. It features declarative dependency management for JavaScript and CSS assets and a vert powerful preprocessor pipeline that allows you to write assets in languages like CoffeeScript, Sass or SCSS.</p>
<p>Sprockets is now integrated in Rails 3.1 and is the core library behind the new <strong>Rails 3.1 asset pipeline</strong>. What about if you want to use Sprockets outside a Rails project?</p>
<p>Sprockets exposes a very powerful Rack interface to serve assets over HTTP. <a href="http://www.metabates.com/2011/08/31/using-sprockets-without-rails/">Integrating Sprockets in a Rack application</a>, such as a Sinatra project, turns out to be a very straightforward task.</p>
<p>But in my case, I wanted to use Sprockets preprocessing and bundling feature outside an HTTP application. And it turned out Sprockets is very good at doing this as well.</p>
<p><span id="more-1485"></span>I have a custom shared template I created several months ago called docss. I use this for several projects such as <a href="http://www.ruby-whois.org/">Ruby Whois</a> and <a href="http://www.robowhois.com/">RoboWhois</a>. The template is composed of several CSS files. I have a Ruby <code>rake</code> script that merges these files and packages them into a single asset, then compress it and publish the result to <a href="http://aws.amazon.com/cloudfront/">Amazon CloudFront</a>.</p>
<p>Instead of processing and merging the files using file system tasks I&#8217;m now delegating this task to Sprockets. The project directory structure looks like this</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">.<br />
├── Gemfile<br />
├── Gemfile.lock<br />
├── Rakefile<br />
├── build<br />
│   ├── javascripts<br />
│   │   └── all.js<br />
│   └── stylesheets<br />
│   &nbsp; &nbsp; ├── <span style="color: #000000;">960</span>.css<br />
│   &nbsp; &nbsp; ├── alignments.css<br />
│   &nbsp; &nbsp; ├── all.css<br />
│   &nbsp; &nbsp; ├── reset.css<br />
│   &nbsp; &nbsp; ├── screen.css<br />
│   &nbsp; &nbsp; └── syntax.css<br />
├── lib<br />
│   └── yuicompressor-2.4.2.jar<br />
└── src<br />
&nbsp; &nbsp; ├── javascripts<br />
&nbsp; &nbsp; │   └── all.js<br />
&nbsp; &nbsp; └── stylesheets<br />
&nbsp; &nbsp; &nbsp; &nbsp; ├── <span style="color: #000000;">960</span>.css<br />
&nbsp; &nbsp; &nbsp; &nbsp; ├── alignments.css<br />
&nbsp; &nbsp; &nbsp; &nbsp; ├── all.css<br />
&nbsp; &nbsp; &nbsp; &nbsp; ├── reset.css<br />
&nbsp; &nbsp; &nbsp; &nbsp; ├── screen.css.scss<br />
&nbsp; &nbsp; &nbsp; &nbsp; └── syntax.css</div></td></tr></tbody></table></div>
<p>And here&#8217;s my <code>compile</code> task</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'bundler'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'pathname'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'logger'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'fileutils'</span><br />
<br />
Bundler.<span style="color:#CC0066; font-weight:bold;">require</span><br />
<br />
ROOT &nbsp; &nbsp; &nbsp; &nbsp;= <span style="color:#CC00FF; font-weight:bold;">Pathname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
LOGGER &nbsp; &nbsp; &nbsp;= <span style="color:#CC00FF; font-weight:bold;">Logger</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>STDOUT<span style="color:#006600; font-weight:bold;">&#41;</span><br />
BUNDLES &nbsp; &nbsp; = <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span> all.<span style="color:#9900CC;">css</span> all.<span style="color:#9900CC;">js</span> <span style="color:#006600; font-weight:bold;">&#41;</span><br />
BUILD_DIR &nbsp; = ROOT.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;build&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
SOURCE_DIR &nbsp;= ROOT.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;src&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<br />
task <span style="color:#ff3333; font-weight:bold;">:compile</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:cleanup</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; sprockets = <span style="color:#6666ff; font-weight:bold;">Sprockets::Environment</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>ROOT<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>env<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; env.<span style="color:#9900CC;">logger</span> = LOGGER<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; sprockets.<span style="color:#9900CC;">append_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>SOURCE_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'javascripts'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; sprockets.<span style="color:#9900CC;">append_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>SOURCE_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'stylesheets'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<br />
&nbsp; BUNDLES.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>bundle<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; assets = sprockets.<span style="color:#9900CC;">find_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span>bundle<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; prefix, basename = assets.<span style="color:#9900CC;">pathname</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'/'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">2</span>..<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><br />
&nbsp; &nbsp; <span style="color:#CC00FF; font-weight:bold;">FileUtils</span>.<span style="color:#9900CC;">mkpath</span> BUILD_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>prefix<span style="color:#006600; font-weight:bold;">&#41;</span><br />
<br />
&nbsp; &nbsp; assets.<span style="color:#9900CC;">write_to</span><span style="color:#006600; font-weight:bold;">&#40;</span>BUILD_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>prefix, basename<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; assets.<span style="color:#9900CC;">to_a</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>asset<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># strip filename.css.foo.bar.css multiple extensions</span><br />
&nbsp; &nbsp; &nbsp; realname = asset.<span style="color:#9900CC;">pathname</span>.<span style="color:#9900CC;">basename</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>..<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; asset.<span style="color:#9900CC;">write_to</span><span style="color:#006600; font-weight:bold;">&#40;</span>BUILD_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>prefix, realname<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>First I create a new <code>Sprockets::Environment</code> instance passing some configurations, such as a custom logger.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sprockets = <span style="color:#6666ff; font-weight:bold;">Sprockets::Environment</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>ROOT<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>env<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; env.<span style="color:#9900CC;">logger</span> = LOGGER<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>Then I append the asset paths.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">sprockets.<span style="color:#9900CC;">append_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>SOURCE_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'javascripts'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
sprockets.<span style="color:#9900CC;">append_path</span><span style="color:#006600; font-weight:bold;">&#40;</span>SOURCE_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'stylesheets'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></td></tr></tbody></table></div>
<p>Finally, I process and package the assets to the build directory.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">assets.<span style="color:#9900CC;">write_to</span><span style="color:#006600; font-weight:bold;">&#40;</span>BUILD_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>prefix, basename<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></td></tr></tbody></table></div>
<p>Because sometimes I need to reference a single CSS file (e.g. <code>alignments.css</code>) instead of the entire bundle, I also build a standalone package for each CSS source. You might not want to do that.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">assets.<span style="color:#9900CC;">to_a</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>asset<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; <span style="color:#008000; font-style:italic;"># strip filename.css.foo.bar.css multiple extensions</span><br />
&nbsp; realname = asset.<span style="color:#9900CC;">pathname</span>.<span style="color:#9900CC;">basename</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span>..<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;.&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; asset.<span style="color:#9900CC;">write_to</span><span style="color:#006600; font-weight:bold;">&#40;</span>BUILD_DIR.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>prefix, realname<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>Please keep in mind that if you want to use processors you must include the corresponding libraries. For example, if you want to support <code>SASS</code> processor you need to add the <code>sass</code> gem.</p>
<p>Here&#8217;s my <code>Gemfile</code>.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">source <span style="color:#996600;">&quot;http://rubygems.org&quot;</span><br />
<br />
gem <span style="color:#996600;">'sass'</span><br />
gem <span style="color:#996600;">'sprockets'</span></div></td></tr></tbody></table></div>
<p>That&#8217;s all.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2010/07/the-way-to-rails-3/' rel='bookmark' title='The Road to Rails 3: make your Rails 2.3 project more Rails 3 oriented'>The Road to Rails 3: make your Rails 2.3 project more Rails 3 oriented</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/09/using-sprockets-without-a-railsrack-project/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>the Rubyist</title>
		<link>http://www.simonecarletti.com/blog/2011/09/the-rubyist/</link>
		<comments>http://www.simonecarletti.com/blog/2011/09/the-rubyist/#comments</comments>
		<pubDate>Wed, 07 Sep 2011 14:42:39 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1479</guid>
		<description><![CDATA[the Rubyist is a collection of conventions and standards for Ruby programmers.]]></description>
			<content:encoded><![CDATA[<p>Several years ago I started keeping track of Ruby coding conventions that my team and I were using in-house. The purpose was to document the most important guidelines we employ in order to keep our libraries and source code consistent, regardless the maintainer.</p>
<p>The result of this effort is <a title="the Rubyist" href="http://rubyist.info/">the Rubyist</a>, a collection of conventions and standards for Ruby programmers. The project is now <a href="http://github.com/weppos/rubyist">open source</a>, you can fork it and contribute.</p>
<div class="wp-caption aligncenter" style="width: 510px"><img title="the Rubyist Homepage" src="http://share.weppos.net/simonecarletti/skitched-20110907-164017.png" alt="the Rubyist Homepage" width="500" height="195" /><p class="wp-caption-text">the Rubyist Homepage</p></div>
<p><span id="more-1479"></span>When I first started learning Ruby, several years ago, there was a very nice project called <strong>RubyGarden</strong>. This project was a real treasure for those learning Ruby because it was full of resources and information about the Ruby world. If you have been developing in Ruby for a long time, I&#8217;m sure you&#8217;ll remember it.</p>
<p>But most of all, the RubyGarden has been extremely helpful to me (and many others) in learning about Ruby conventions and the most notable Ruby best practices. One page in particular, the <strong>RubyStyleGuide</strong>, was a collection of Ruby coding standard and naming conventions that every Ruby developer ought to have been familiar with.</p>
<div class="wp-caption aligncenter" style="width: 510px"><img title="RubyGarde Ruby Style Guide " src="http://share.weppos.net/simonecarletti/skitched-20110907-163554.png" alt="" width="500" height="379" /><p class="wp-caption-text">RubyGarde Ruby Style Guide</p></div>
<p>A lot has changed since then.</p>
<p>The RubyGarden project was shut down a few years ago. As far I remember, the wiki was invaded by spam and the <code>www.rubygarden.org</code> domain has now been hijacked.</p>
<p>The Ruby language has evolved. Ruby 1.8 and Ruby 1.9 have introduced several new syntax changes and conventions. Moreover, the adoption of the Ruby programming language has increased over the years and several new common programming patterns have arisen.</p>
<p><a href="https://github.com/">GitHub</a> was born. If you are in the habit of <a href="http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-reading-source-code/">read the source code</a>, GitHub is like a chocolate factory for a child. You can find an countless number of Ruby projects, filter them, sort them and read the source code to learn from it. Just pick some random accounts owned by notable Ruby developers, explore their programming habits and learn new exciting best practices and patterns.</p>
<p>Even with these newly available resources, there are many times when an quick reference can come in most handy.</p>
<p>Whether you are a Ruby master or a newbie, I hope you&#8217;ll find <a href="rubyist.info">the Rubyist</a> to be a source of inspiration.</p>
<p>No related posts.</p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/09/the-rubyist/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>RSpec Rails doesn&#8217;t render Rails views by default</title>
		<link>http://www.simonecarletti.com/blog/2011/04/rspec-rails-doesnt-render-rails-views-by-default/</link>
		<comments>http://www.simonecarletti.com/blog/2011/04/rspec-rails-doesnt-render-rails-views-by-default/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 07:54:23 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1433</guid>
		<description><![CDATA[RSpec (actually the RSpec Rails gem) doesn't render the content of the action by default, like the common Rails functional tests do.]]></description>
			<content:encoded><![CDATA[<p>If you are using <strong>RSpec</strong> and <strong>RSpec Rails</strong> to test your Rails application, I strongly encourage you to keep reading this post because there&#8217;s a gotcha in the default configuration you might not expect, especially if you ever used the default Rails test framework before.</p>
<p>A couple of days ago I was notified about a but in a Rails application. The application crashed when trying to create a new record.</p>
<p>I changed the <code>new</code> action the day before, but I was sure all the tests passed and the action was covered with a pretty reasonable RSpec test suite. Moreover, the action method was one of the most simplest methods I have ever written.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> new<br />
&nbsp; <span style="color:#0066ff; font-weight:bold;">@record</span> = Model.<span style="color:#9900CC;">new</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>I run the test suite, all green. I executed the page in the browser, it crashed.</p>
<div id="attachment_1434" class="wp-caption aligncenter" style="width: 384px"><img class="size-full wp-image-1434" title="WTF Monkey" src="http://www.simonecarletti.com/blog/wp-content/uploads/2011/04/wtf.jpg" alt="" width="374" height="300" /><p class="wp-caption-text">My face when I discovered all tests passed but the action kept crashing.</p></div>
<p>After several minutes of debugging I discovered the culprit: RSpec (actually the RSpec Rails gem) doesn&#8217;t render the content of the action by default, like the common Rails functional tests do. In fact, <code>@response.body</code> always resulted in an empty string.<span id="more-1433"></span></p>
<p>The view contained a statement like the following</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#006600; font-weight:bold;">&lt;%</span>= f.<span style="color:#9900CC;">collection_select</span> Model.<span style="color:#9900CC;">all</span>, <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></div></td></tr></tbody></table></div>
<p>that was misspelled and crashed when the template was rendered. But because RSpec doesn&#8217;t render the Rails views, the view was not covered by the tests at all.</p>
<p>The solution is simple and is called <a href="http://relishapp.com/rspec/rspec-rails/v/2-5/dir/controller-specs/render-views">render_views</a>.</p>
<p>To tell a controller to render the content of the view, simply call <code>render_views</code>.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;spec_helper&quot;</span><br />
<br />
describe RecordsController <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; render_views<br />
<br />
&nbsp; describe <span style="color:#996600;">&quot;GET index&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># ...</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>You can also enable <code>render_views</code> globally, in your <code>spec_helper.rb</code> file.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">RSpec.<span style="color:#9900CC;">configure</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>config<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; config.<span style="color:#9900CC;">render_views</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>The reason behind this choice is because RSpec Rails actually provides a special RSpec group called &#8220;view specs&#8221;.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">describe <span style="color:#996600;">&quot;events/index.html.erb&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; it <span style="color:#996600;">&quot;renders _event partial for each event&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; assign<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:events</span>, <span style="color:#006600; font-weight:bold;">&#91;</span>stub_model<span style="color:#006600; font-weight:bold;">&#40;</span>Event<span style="color:#006600; font-weight:bold;">&#41;</span>, stub_model<span style="color:#006600; font-weight:bold;">&#40;</span>Event<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; render<br />
&nbsp; &nbsp; view.<span style="color:#9900CC;">should</span> render_template<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:partial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;_event&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:count</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">2</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>According to the documentation, this is the right way to test Rails templates in RSpec. Honestly, I never really liked this feature and I tend to keep using controller specs — the RSpec equivalent of functional tests — (or alternative test tools) to test the views.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2010/12/get-the-currently-described-class-in-rspec/' rel='bookmark' title='Get the currently described class in RSpec'>Get the currently described class in RSpec</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/08/user-profile-permalinks-with-ruby-on-rails-and-authlogic/' rel='bookmark' title='User profile permalinks with Ruby on Rails (and Authlogic)'>User profile permalinks with Ruby on Rails (and Authlogic)</a></li>
<li><a href='http://www.simonecarletti.com/blog/2011/02/new-in-whois-gem-testers/' rel='bookmark' title='New in Whois: Gem Testers'>New in Whois: Gem Testers</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/04/rspec-rails-doesnt-render-rails-views-by-default/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Understanding Ruby and Rails: Lazy load hooks</title>
		<link>http://www.simonecarletti.com/blog/2011/04/understanding-ruby-and-rails-lazy-load-hooks/</link>
		<comments>http://www.simonecarletti.com/blog/2011/04/understanding-ruby-and-rails-lazy-load-hooks/#comments</comments>
		<pubDate>Thu, 07 Apr 2011 08:22:54 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[activesupport]]></category>
		<category><![CDATA[lazy-load]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1426</guid>
		<description><![CDATA[With Rails 3 you can now register specific hooks to be lazy-executed when the corresponding library is loaded.]]></description>
			<content:encoded><![CDATA[<div class="flash-message info target-rails">
<p>This article targets <strong>Rails 3</strong>. The information contained in this page might not apply to different versions.</p>
</div>
<p><em>This is article is part of my series Understanding Ruby and Rails. Please see the <a href="http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-reading-source-code/">table of contents</a> for the series to view the list of all posts.</em></p>
<p>A small-but-interesting feature introduced in <strong>Rails 3</strong> is the built-in support for <strong>lazy loading</strong>.</p>
<p>Lazy loading is a very common <strong>design pattern</strong>. The concept is to defer initialization of an object until the point at which it is needed. This design pattern decreases the time required by an application to boot by distributing the computation cost during the execution. Also, if a specific feature is never used, the computation won&#8217;t be executed at all.</p>
<p>With Rails 3 you can now register specific hooks to be lazy-executed when the corresponding library is loaded.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span><br />
<br />
&nbsp; initializer <span style="color:#996600;">&quot;active_record.include_plugins&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; ActiveSupport.<span style="color:#9900CC;">on_load</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:active_record</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">MyApp::ActivePlugins</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>In this case we register the block to be executed when the <code>ActiveRecord</code> library is loaded. If you read the <a href="https://github.com/rails/rails/blob/v3.0.6/activerecord/lib/active_record/base.rb">ActiveRecord::Base source code</a>, the very last line is a call to</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ActiveSupport.<span style="color:#9900CC;">run_load_hooks</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:active_record</span>, <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span><span style="color:#006600; font-weight:bold;">&#41;</span></div></td></tr></tbody></table></div>
<p>This line of code executes all the hooks previously registered for <code>ActiveRecord</code>.<span id="more-1426"></span></p>
<h2>lazy-load hooks in the wild</h2>
<p>Perhaps one of the most frequent usage of the lazy-load hooks is in Rails plugins.</p>
<p>For example, if your plugin needs to register some helpers, you can write a hook to include the helpers in <code>ActionView</code> only when <code>ActionView</code> is loaded. If the environment is loaded from a rake task (which doesn&#8217;t necessary need <code>ActionView</code>), then your plugin hook won&#8217;t be executed and the Rails application will boot faster.</p>
<p>Here&#8217;s an example from the <code>will_paginate</code> gem.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'will_paginate'</span><br />
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'will_paginate/collection'</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">module</span> WillPaginate<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">class</span> Railtie <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">Rails::Railtie</span><br />
&nbsp; &nbsp; initializer <span style="color:#996600;">&quot;will_paginate.active_record&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>app<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:active_record</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'will_paginate/finders/active_record'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#6666ff; font-weight:bold;">WillPaginate::Finders::ActiveRecord</span>.<span style="color:#9900CC;">enable</span>!<br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; &nbsp; initializer <span style="color:#996600;">&quot;will_paginate.action_dispatch&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>app<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:action_controller</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#6666ff; font-weight:bold;">ActionDispatch::ShowExceptions</span>.<span style="color:#9900CC;">rescue_responses</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'WillPaginate::InvalidPage'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#ff3333; font-weight:bold;">:not_found</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
&nbsp; &nbsp; initializer <span style="color:#996600;">&quot;will_paginate.action_view&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>app<span style="color:#006600; font-weight:bold;">|</span><br />
&nbsp; &nbsp; &nbsp; ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:action_view</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'will_paginate/view_helpers/action_view'</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">WillPaginate::ViewHelpers::ActionView</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; &nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<h2>Using lazy load in your libraries</h2>
<p>So far, we only discussed about using lazy-loading to hook Rails core library. Because lazy-loading is an <code>ActiveSupport</code> feature, you can use it in your Rails applications but also in your own Ruby classes.</p>
<p>First, make sure to add a call to <code>ActiveSupport.run_load_hooks</code> at the end of your Ruby class.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> HttpClient<br />
&nbsp; <span style="color:#008000; font-style:italic;"># ...</span><br />
<br />
&nbsp; ActiveSupport.<span style="color:#9900CC;">run_load_hooks</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:http_client</span>, <span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>Now you can register on_load hooks everywhere passing the name of the library used in <code>run_load_hooks</code>.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> Request<br />
&nbsp; <span style="color:#008000; font-style:italic;"># ...</span><br />
<br />
&nbsp; ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:http_client</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># do something</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#9966CC; font-weight:bold;">class</span> Response<br />
&nbsp; <span style="color:#008000; font-style:italic;"># ...</span><br />
<br />
&nbsp; ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:http_client</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># do something</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<h2>Hook context</h2>
<p>The <code>run_load_hooks</code> method takes a second parameter representing the context within the hook will be executed. It&#8217;s a common pattern to pass the class/instance the hooks refer to.</p>
<p>For instance, the <code>ActiveRecord</code> library mentioned at the beginning of the article passes <code>self</code>. In that context, <code>self</code> references the <code>ActiveRecord::Base</code> class.</p>
<p>This is useful because, if you want to include some custom methods into ActiveRecord, you can use the following block</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:active_record</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">MyPlugin::Extensions</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>instead of</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:active_record</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">send</span> :<span style="color:#9966CC; font-weight:bold;">include</span>, <span style="color:#6666ff; font-weight:bold;">MyPlugin::Extensions</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span></div></td></tr></tbody></table></div>
<p>There&#8217;s also an other interesting use case for this feature. If you want to perform some kind of lazy-initialization when an instance of a class is created, just pass the instance itself.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">class</span> Color<br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#0066ff; font-weight:bold;">@name</span> = name<br />
<br />
&nbsp; &nbsp; ActiveSupport.<span style="color:#9900CC;">run_load_hooks</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:instance_of_color</span>, <span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
ActiveSupport.<span style="color:#9900CC;">on_load</span> <span style="color:#ff3333; font-weight:bold;">:instance_of_color</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;The color is #{@name}&quot;</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
Color.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;yellow&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; &quot;The color is yellow&quot;</span></div></td></tr></tbody></table></div>
<h2>Source Code</h2>
<p>The source code of the lazy-loading feature is available in the <a href="https://github.com/rails/rails/blob/v3.0.6/activesupport/lib/active_support/lazy_load_hooks.rb">lazy_load_hooks.rb</a> file.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-reading-source-code/' rel='bookmark' title='Understanding Ruby and Rails: Reading Source Code'>Understanding Ruby and Rails: Reading Source Code</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/12/inside-ruby-on-rails-rescuable-and-rescue_from/' rel='bookmark' title='Understanding Ruby and Rails: Rescuable and rescue_from'>Understanding Ruby and Rails: Rescuable and rescue_from</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/09/inside-ruby-on-rails-extract_options-from-arrays/' rel='bookmark' title='Understanding Ruby and Rails: extract_options! from Arrays'>Understanding Ruby and Rails: extract_options! from Arrays</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/04/understanding-ruby-and-rails-lazy-load-hooks/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Whois 2.0</title>
		<link>http://www.simonecarletti.com/blog/2011/03/whois-2-0/</link>
		<comments>http://www.simonecarletti.com/blog/2011/03/whois-2-0/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 20:58:19 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Hosting / Domains]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubywhois]]></category>
		<category><![CDATA[whois]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1417</guid>
		<description><![CDATA[I'm very proud to announce the immediate availability of Whois 2.0.]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-606" title="Whois" src="http://www.simonecarletti.com/blog/wp-content/uploads/2009/09/whois-150x150.png" alt="" width="150" height="150" />One year after the <a title="Ruby Whois 1.0 is here!" href="http://www.simonecarletti.com/blog/2010/02/ruby-whois-1-0-is-here/">first major release</a>, almost 2 years after the first commit, 1k commits and 59 versions after, I&#8217;m very proud to announce the immediate availability of <strong>Whois 2.0</strong>.</p>
<p><a title="Ruby Whois - Ruby Whois Gem" href="http://www.ruby-whois.org/">Whois</a> is an intelligent, pure Ruby, <strong>WHOIS client and parser</strong>. It provides a flexible and programmable API to query WHOIS servers and look up IP, TLD, and domain WHOIS information. It also offers command-line interface to run WHOIS queries from the console.</p>
<p>This second major release, the 60th since I released the gem, is a very important milestones. I started working on this project with the idea of <strong>creating a Ruby parser for each TLD available and it took me two years and countless hours to reach this goal</strong>.<span id="more-1417"></span></p>
<h2>Some stats</h2>
<p>To give you a rough idea about the complexity of this project, here&#8217;s a few numbers about Whois 2.0.</p>
<ul>
<li>866,706 different WHOIS records (~3.3 GB of data) analyzed as of March 16th, 2011</li>
<li>425 RSpec test files</li>
<li>444 fixture files extracted from real WHOIS records</li>
<li>3787 RSpec examples and an unknown number of matches (sorry, I stopped keeping track of them when they reached 15k assertions) that probably makes this project one of the gems with the largest RSpec test suite</li>
<li>~20.000 lines of code, including the test files</li>
<li>168 different WHOIS parsers</li>
</ul>
<p>Oh, man. You can&#8217;t believe the amount of work required to cover all the existing WHOIS servers, their features and especially their whims.</p>
<h2>New and Notable</h2>
<p>The increasing support for all existing TLD servers is probably one of the most important changes for this milestone. But the CHANGELOG is very huge and there are a few other changes that are worth a mention.</p>
<p>I already blogged about a few of them.</p>
<ul>
<li>The <a href="http://www.simonecarletti.com/blog/2011/03/new-in-whois-nameservers-are-now-nameserver/"><code>#nameservers</code> property now returns a Nameserver object</a>. This change allows the parser to also extract name server IPv4 and IPv6 addresses.</li>
<li>A <a href="http://www.simonecarletti.com/blog/2011/02/new-in-whois-improved-caching/">new caching mechanism</a> reduces the number of instance variables created.</li>
<li>The library now supports the <a href="http://www.simonecarletti.com/blog/2011/02/new-in-whois-gem-testers/">Gem Testers project</a>.</li>
<li>You can now bind a different address or port to the WHOIS socket request.</li>
</ul>
<p>Last but not least, the <code>Whois::Answer</code> class has been renamed to <code>Whois::Record</code>.</p>
<p>There are a couple of backwards-incompatible changes to the API. These changes were necessary to evolve the API to better reflect the representation of the existing WHOIS responses.</p>
<h2>What&#8217;s Next?</h2>
<p>The Whois library is pretty stable. It is now used in production for several big projects.</p>
<p>The API is mature. A few changes have been made in this major release to support additional WHOIS properties, however I don&#8217;t expect big changes in the future.</p>
<p>The following releases will focus on increasing the list of supported properties for each parser, as well closing some of the <a href="https://github.com/weppos/whois/issues">existing issues</a>.</p>
<p>The biggest change in the API in the near future is likely to be the <a href="https://github.com/weppos/whois/issues#issue/2">standardization of the status property</a>.</p>
<p>In the last months I received some great feedback from people using my library with other platforms, such as Java and .NET. This is amazing.</p>
<p>If you have any case study, case history or feedback, please let me know. I would love to learn more about how you use the library.</p>
<h2>How to Upgrade</h2>
<p>To upgrade to Whois 2.0 please follow the instructions in the <a href="http://www.ruby-whois.org/manual/upgrading.html">documentation page</a>.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/12/whois-0-9-0/' rel='bookmark' title='Whois 0.9.0: WHOIS parsers, CLI and performances'>Whois 0.9.0: WHOIS parsers, CLI and performances</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/01/new-in-whois-principle-of-least-surprise/' rel='bookmark' title='New in Whois: Applying the Principle of Least Surprise'>New in Whois: Applying the Principle of Least Surprise</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/01/new-in-whois-property-is-set/' rel='bookmark' title='New in Whois: property is set?'>New in Whois: property is set?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/03/whois-2-0/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Ruby 4 Rails &#8211; Learning Ruby, with Rails in mind</title>
		<link>http://www.simonecarletti.com/blog/2011/03/ruby-4-rails/</link>
		<comments>http://www.simonecarletti.com/blog/2011/03/ruby-4-rails/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 09:47:30 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[showoff]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1353</guid>
		<description><![CDATA[Ruby 4 Rails is a presentation about the most essential features of the Ruby programming language, created to provide the necessary Ruby knowledge to start with Rails.]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-1363" title="Ruby Logo" src="http://www.simonecarletti.com/blog/wp-content/uploads/2011/03/ruby-icon-150x150.png" alt="" width="100" height="100" />A few weeks ago, a friend of mine told me he wanted to learn Rails. He asked me to prepare a private course about Rails and to teach him the basics of the framework.</p>
<p>After a brief discussion, we ultimately agreed that he couldn&#8217;t effectively use Rails without <em>being a Rubyist</em>. For this reason, I offered him to start with a Ruby concentrate, carefully prepared keeping an eye on Rails.</p>
<p>The presentation is called <strong>Ruby 4 Rails</strong> and <a href="https://github.com/weppos/ruby-4-rails.showoff">is now available on GitHub</a>. It is based on <a href="https://github.com/schacon/showoff">ShowOff</a>, a Markdown-to-HTML presentation tool created by Scott Chacon. Make sure to read the <code>README</code> to learn how it works.</p>
<p>The initial part of the README is largely inspired by <a href="http://www.engineyard.com/blog/2011/ruote-and-flow/">John&#8217;s post about Ruote</a>.</p>
<p><a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/"><img class="alignleft" src="http://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" alt="Creative Commons License" /></a> Ruby 4 Rails is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/">Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License</a>. Based on a work at <a rel="dct:source" href="https://github.com/weppos/ruby-4-rails.showoff">github.com</a>.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2009/08/ruby-on-rails-and-canonical-link-tag/' rel='bookmark' title='Ruby on Rails and Canonical link tag'>Ruby on Rails and Canonical link tag</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/04/tabsonrails/' rel='bookmark' title='TabsOnRails: creating and managing Tabs with Ruby on Rails'>TabsOnRails: creating and managing Tabs with Ruby on Rails</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/08/user-profile-permalinks-with-ruby-on-rails-and-authlogic/' rel='bookmark' title='User profile permalinks with Ruby on Rails (and Authlogic)'>User profile permalinks with Ruby on Rails (and Authlogic)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/03/ruby-4-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>New in Whois: #nameservers are now Nameserver</title>
		<link>http://www.simonecarletti.com/blog/2011/03/new-in-whois-nameservers-are-now-nameserver/</link>
		<comments>http://www.simonecarletti.com/blog/2011/03/new-in-whois-nameservers-are-now-nameserver/#comments</comments>
		<pubDate>Mon, 07 Mar 2011 08:58:51 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubywhois]]></category>
		<category><![CDATA[whois]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1368</guid>
		<description><![CDATA[In the new Whois version the property #nameservers returns an array of Nameserver object, containing DNS name, ipv4 and ipv6 addresses.]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s time for another update on Ruby <a href="http://www.ruby-whois.org/">Whois library</a>. Let&#8217;s talk about <a title="Name server - Wikipedia, the free encyclopedia" href="http://en.wikipedia.org/wiki/Name_server">name servers</a>.</p>
<p>The most part of WHOIS servers follow the &#8220;convention&#8221; to include the name server list of a domain in the WHOIS record.</p>
<p>A name server is represented by a DNS name, which is a string.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ns1.google.com<br />
ns2.google.com</div></td></tr></tbody></table></div>
<p>The DNS name resolves to an IPv4 IP address.</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ns1.google.com =&gt; 216.239.32.10<br />
ns2.google.com =&gt; 216.239.34.10</div></td></tr></tbody></table></div>
<p>Optionally, the DNS name can resolve to an IPv6 IP address.git</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ns1.nic.fr =&gt; 2001:660:3003:2::4:1<br />
ns2.nic.fr =&gt; 2001:660:3005:1::1:2</div></td></tr></tbody></table></div>
<p>Each WHOIS server arbitrary choses the amount of information to store and return in a WHOIS record. Some registries returns only the DNS name, other registries include IP addresses as well.<span id="more-1368"></span></p>
<p>In the current WHOIS version, the list of name servers is accessible through the <code>#nameservers</code> property.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">r = Whois.<span style="color:#9900CC;">query</span> <span style="color:#996600;">&quot;google.com&quot;</span><br />
r.<span style="color:#9900CC;">nameservers</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; [&quot;ns1.google.com&quot;, &quot;ns2.google.com&quot;]</span></div></td></tr></tbody></table></div>
<p>The method returns an <code>Array</code> of <code>String</code>. This is a lossy implementation because it completely ignores the IPv4 and IPv6 details.</p>
<p>The new Whois version solves this problem by introducing a new <code>Whois::Answer::Nameserver</code> object. This object is a <code>Struct</code> composed by three attributes: <code>name</code>, <code>ipv4</code> and <code>ipv6</code>.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ns = Nameserver.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><br />
&nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;ns1.nic.fr&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:ipv4</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;192.134.4.1&quot;</span>,<br />
&nbsp; &nbsp; <span style="color:#ff3333; font-weight:bold;">:ipv6</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;2001:660:3003:2::4:1&quot;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#41;</span><br />
<br />
ns.<span style="color:#9900CC;">name</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; &quot;ns1.nic.fr&quot;</span><br />
ns.<span style="color:#9900CC;">ipv4</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; &quot;192.134.4.1&quot;</span><br />
ns.<span style="color:#9900CC;">ipv6</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; &quot;2001:660:3003:2::4:1&quot;</span></div></td></tr></tbody></table></div>
<p>In the new Whois version, the <code>#nameservers</code> implementation has been changed to return an array of <code>Nameserver</code> instead of a simple <code>String</code>.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">r = Whois.<span style="color:#9900CC;">query</span> <span style="color:#996600;">&quot;nic.fr&quot;</span><br />
r.<span style="color:#9900CC;">nameservers</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; [</span><br />
<span style="color:#008000; font-style:italic;"># &nbsp; &nbsp; #&lt;struct Whois::Answer::Nameserver name=&quot;ns1.nic.fr&quot;, ipv4=&quot;192.134.4.1&quot;, ipv6=&quot;2001:660:3003:2::4:1&quot;&gt;,</span><br />
<span style="color:#008000; font-style:italic;"># &nbsp; &nbsp; #&lt;struct Whois::Answer::Nameserver name=&quot;ns2.nic.fr&quot;, ipv4=&quot;192.93.0.4&quot;, ipv6=&quot;2001:660:3005:1::1:2&quot;&gt;,</span><br />
<span style="color:#008000; font-style:italic;"># &nbsp; &nbsp; ...</span><br />
<span style="color:#008000; font-style:italic;"># &nbsp; &nbsp;]</span></div></td></tr></tbody></table></div>
<p>It&#8217;s important to know that this change can break backwards compatibility. In order to minimize the impact, <code>Nameserver#to_s</code> returns the <code>String</code> value of the <code>name</code> attribute.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Nameserver.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;ns1.nic.fr&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:ipv4</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;192.134.4.1&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; &quot;ns1.nic.fr&quot;</span></div></td></tr></tbody></table></div>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2010/02/ruby-whois-1-0-is-here/' rel='bookmark' title='Ruby Whois 1.0 is here!'>Ruby Whois 1.0 is here!</a></li>
<li><a href='http://www.simonecarletti.com/blog/2011/03/whois-2-0/' rel='bookmark' title='Whois 2.0'>Whois 2.0</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/08/ruby-has-a-new-whois-library/' rel='bookmark' title='Ruby has a new WHOIS library'>Ruby has a new WHOIS library</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/03/new-in-whois-nameservers-are-now-nameserver/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>New in Whois: improved caching</title>
		<link>http://www.simonecarletti.com/blog/2011/02/new-in-whois-improved-caching/</link>
		<comments>http://www.simonecarletti.com/blog/2011/02/new-in-whois-improved-caching/#comments</comments>
		<pubDate>Tue, 15 Feb 2011 11:15:45 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubywhois]]></category>
		<category><![CDATA[whois]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1279</guid>
		<description><![CDATA[Today, I'm very happy to report that this week I introduced a completely new caching system for the Whois::Answer::Parser.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working very hard to include some of the most important features in the new version of the <a title="Ruby Whois - Ruby Whois Gem" href="http://www.ruby-whois.org/">Ruby Whois library</a>.</p>
<p>Today, I&#8217;m very happy to report that this week I closed the <a href="https://github.com/weppos/whois/issues/18">issue #18</a> which introduces a completely new caching system for the <code>Whois::Answer::Parser</code>.</p>
<p>The way <code>Whois</code> parsers currently work, is to extract a property only the very first time it is requested.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">r = Whois.<span style="color:#9900CC;">query</span> <span style="color:#996600;">&quot;weppos.it&quot;</span><br />
<br />
<span style="color:#008000; font-style:italic;"># the property has never been requested before</span><br />
<span style="color:#008000; font-style:italic;"># the value is computed, cached and returned</span><br />
r.<span style="color:#9900CC;">status</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; :ok</span><br />
<br />
<span style="color:#008000; font-style:italic;"># the property has been requested before</span><br />
<span style="color:#008000; font-style:italic;"># the value is returned without further elaborations</span><br />
r.<span style="color:#9900CC;">status</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; :ok</span></div></td></tr></tbody></table></div>
<p>So far, so good.</p>
<p>The way the system works under the hood, is to create a parser instance variable for every single requested property.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">r = Whois.<span style="color:#9900CC;">query</span> <span style="color:#996600;">&quot;weppos.it&quot;</span><br />
<br />
<span style="color:#008000; font-style:italic;"># get the first parser</span><br />
<span style="color:#008000; font-style:italic;"># because</span><br />
<span style="color:#008000; font-style:italic;"># &nbsp; r.status relies on</span><br />
<span style="color:#008000; font-style:italic;"># a</span><br />
<span style="color:#008000; font-style:italic;"># &nbsp; r.parser.parsers.first.status</span><br />
<span style="color:#CC0066; font-weight:bold;">p</span> = r.<span style="color:#9900CC;">parser</span>.<span style="color:#9900CC;">parsers</span>.<span style="color:#9900CC;">first</span><br />
<br />
<span style="color:#008000; font-style:italic;"># value is not cached</span><br />
<span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">instance_variable_get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;@status&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; nil</span><br />
<br />
<span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">status</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; :ok</span><br />
<br />
<span style="color:#008000; font-style:italic;"># value is cached</span><br />
<span style="color:#CC0066; font-weight:bold;">p</span>.<span style="color:#9900CC;">instance_variable_get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;@status&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
<span style="color:#008000; font-style:italic;"># =&gt; :ok</span></div></td></tr></tbody></table></div>
<p>So far, quite good. This approach has a couple of drawbacks.</p>
<p><span id="more-1279"></span>First, it creates an instance variable for every single property. Because of the large (and increasing) <a href="http://www.ruby-whois.org/manual/parser-properties.html">number of properties</a>, the parser object space counts a large number of instance variables. This makes it hard, for instance, to sweep the cache because you have to loop through all instance variables and remove each one.</p>
<p>Second, there&#8217;s a small inefficiency here. Because in Ruby you don&#8217;t have to define variables, an undefined instance variable is <code>nil</code>. But <code>nil</code> is actually a value and properties can have a <code>nil</code> value. In this implementation, you don&#8217;t have a way to distinguish when a value is nil and when it hasn&#8217;t been elaborated yet, thus <code>nil</code> properties will never hit the cache.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> created_on<br />
&nbsp; <span style="color:#0066ff; font-weight:bold;">@created_on</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#9966CC; font-weight:bold;">if</span> very_expensive_scan<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>created_on<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; <span style="color:#008000; font-style:italic;"># ... set the value</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#008000; font-style:italic;"># calling #created_on several times will continue to perform</span><br />
<span style="color:#008000; font-style:italic;"># the very_expensive_scan as long as the value != nil.</span></div></td></tr></tbody></table></div>
<p>The new approach uses a single instance variable called <code>@cached_properties</code> as cache. The variable contains a <code>Hash&lt;:key =&gt; value&gt;</code>, where the key is the property and the value the cached result.</p>
<p>If the cache doesn&#8217;t contain any key for given property, then the method hasn&#8217;t been executed yet. Cached <code>nil</code> properties will return <code>nil</code> without further elaboration.</p>
<p>The method <code>#cached_properties_fetch</code> takes care of everything.</p>
<div class="codecolorer-container ruby default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="ruby codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color:#9966CC; font-weight:bold;">def</span> created_on<br />
&nbsp; cached_properties_fetch<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:created_on</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span><br />
&nbsp; &nbsp; <span style="color:#0000FF; font-weight:bold;">nil</span><br />
&nbsp; <span style="color:#9966CC; font-weight:bold;">end</span><br />
<span style="color:#9966CC; font-weight:bold;">end</span><br />
<br />
<span style="color:#008000; font-style:italic;"># value is cached and returned</span><br />
created_on<br />
<span style="color:#008000; font-style:italic;"># =&gt; nil</span><br />
<br />
<span style="color:#008000; font-style:italic;"># the request hits the cache</span><br />
created_on<br />
<span style="color:#008000; font-style:italic;"># =&gt; nil</span></div></td></tr></tbody></table></div>
<p>If you need to sweep the cache, reset <code>@cached_properties</code> to an empty <code>Hash</code>.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2010/01/new-in-whois-property-is-set/' rel='bookmark' title='New in Whois: property is set?'>New in Whois: property is set?</a></li>
<li><a href='http://www.simonecarletti.com/blog/2010/01/new-in-whois-principle-of-least-surprise/' rel='bookmark' title='New in Whois: Applying the Principle of Least Surprise'>New in Whois: Applying the Principle of Least Surprise</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/10/ruby-whois-0-8-1/' rel='bookmark' title='Ruby Whois 0.8.1'>Ruby Whois 0.8.1</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/02/new-in-whois-improved-caching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New in Whois: Gem Testers</title>
		<link>http://www.simonecarletti.com/blog/2011/02/new-in-whois-gem-testers/</link>
		<comments>http://www.simonecarletti.com/blog/2011/02/new-in-whois-gem-testers/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 16:18:37 +0000</pubDate>
		<dc:creator>Simone Carletti</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubywhois]]></category>
		<category><![CDATA[test]]></category>

		<guid isPermaLink="false">http://www.simonecarletti.com/blog/?p=1283</guid>
		<description><![CDATA[The new Whois version now includes support for gem test.]]></description>
			<content:encoded><![CDATA[<p>At the beginning of February, <a title="Introducing Gem Testers | Engine Yard Ruby on Rails Blog" href="http://www.engineyard.com/blog/2011/introducing-gem-testers/">Engine Yard announced</a> a very interesting project called <a title="Gem Testers" href="http://gem-testers.org/">Gem Testers</a>.</p>
<blockquote><p>Gem Testers was built to make it easier for gem developers to write gems that run everywhere. This is split into two pieces:</p>
<ol>
<li><a title="rubygems-test | RubyGems.org | your community gem host" href="http://rubygems.org/gems/rubygems-test">rubygems-test</a> is a Rubygems plugin which automatically runs the test suite of a specified gem on install.</li>
<li><a title="Gem Testers" href="http://gem-testers.org/">Gem-testers.org</a> is a central repository for test data. Test results are organized primarily by Ruby version and operating system.</li>
</ol>
</blockquote>
<p>I believe this is a wonderful project and it can have a very good impact on the quality of the available Ruby gems.</p>
<p><a href="http://www.ruby-whois.org/">Whois</a> currently counts <strong>211 RSpec examples</strong> and <strong>1899 tests</strong> with <strong>8674 assertions</strong>. This is a very huge test suite which is able to provide an immediate feedback on existing bugs.</p>
<p><span id="more-1283"></span>The new Whois version now includes support for <code>gem test</code>. You can decide to run the tests automatically when installing the gem or run them later by executing</p>
<div class="codecolorer-container bash default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666;">$ </span>gem <span style="color: #7a0874; font-weight: bold;">test</span> <span style="color: #c20cb9; font-weight: bold;">whois</span></div></td></tr></tbody></table></div>
<p>Read <a href="https://github.com/rubygems/rubygems-test/blob/master/README.txt">rubygems-test README</a> for further information.</p>
<p>Unfortunately, this feature forced me to re-include all the test fixtures and files into the packaged <code>.gem</code>. It means the size of <code>.gem</code> file will be bigger than previous releases.</p>
<p>Related posts<ol>
<li><a href='http://www.simonecarletti.com/blog/2011/03/whois-2-0/' rel='bookmark' title='Whois 2.0'>Whois 2.0</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/08/ruby-has-a-new-whois-library/' rel='bookmark' title='Ruby has a new WHOIS library'>Ruby has a new WHOIS library</a></li>
<li><a href='http://www.simonecarletti.com/blog/2009/09/ruby-whois-preview-answer-and-parser/' rel='bookmark' title='Ruby Whois preview: WHOIS answer and parser'>Ruby Whois preview: WHOIS answer and parser</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.simonecarletti.com/blog/2011/02/new-in-whois-gem-testers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

