<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>David Chelimsky: Tag ruby</title>
    <link>http://blog.davidchelimsky.net/articles/tag/ruby?tag=ruby</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>on software in process and practice</description>
    <item>
      <title>RSpec-1.1.4</title>
      <description>&lt;p&gt;We released RSpec-1.1.4 today. It&amp;#8217;s mostly a maintenance release but there are a few of cool new features that you may want to know about and take advantage of.&lt;/p&gt;


	&lt;h3&gt;hash_including&lt;/h3&gt;


	&lt;p&gt;One thing that has always been a drag is having to specify every key/value pair in a hash that is received as an argument. This is especially painful in Rails controller examples because Rails adds some data to the hash and the examples really don&amp;#8217;t care about that extra data.&lt;/p&gt;


	&lt;p&gt;Enter &lt;code&gt;hash_including()&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;This is a mock argument matcher that let&amp;#8217;s you expect a hash including certain key/value pairs regardless of anything else that shows up in the hash. So instead of:&lt;/p&gt;


&lt;pre&gt;
account.should_receive(:deposit).with({:amount =&amp;gt; 37.42, :date =&amp;gt; anything()})
&lt;/pre&gt;

	&lt;p&gt;you can just say:&lt;/p&gt;


&lt;pre&gt;
account.should_receive(:deposit).with(hash_including(:amount =&amp;gt; 37.42))
&lt;/pre&gt;

	&lt;p&gt;and keep the example focused on what you&amp;#8217;re really interested in&lt;/p&gt;


	&lt;p&gt;Thanks to &lt;a href="http://talklikeaduck.denhaven2.com/"&gt;Rick DeNatale&lt;/a&gt; who submitted this feature request and the patch to implement it.&lt;/p&gt;


	&lt;h3&gt;The heckler returns&lt;/h3&gt;


	&lt;p&gt;RSpec wasn&amp;#8217;t correctly supporting heckle for a while but the spec-heckler is back in action. For those unfamiliar, you can read about heckle at &lt;a href="http://blog.zenspider.com/2007/06/heckle-version-141-has-been-re.html"&gt;zenspider&amp;#8217;s blog&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how you heckle your Animal model in your PetStore app:&lt;/p&gt;


&lt;pre&gt;
spec spec/models/animal_spec.rb --heckle Animal
&lt;/pre&gt;

	&lt;p&gt;Thanks to &lt;a href="http://tarvainen.wordpress.com/"&gt;Antti Tarvainen&lt;/a&gt; for resurrecting this one.&lt;/p&gt;


	&lt;h3&gt;stub_model&lt;/h3&gt;


	&lt;p&gt;This is for rails developers who like writing view examples with &lt;code&gt;mock_model()&lt;/code&gt; but are sick and tired of having to stub every single attribute that gets referenced in a view.&lt;/p&gt;


	&lt;p&gt;Instead of creating a mock object like &lt;code&gt;mock_model()&lt;/code&gt; does, &lt;code&gt;stub_model()&lt;/code&gt; creates an instance of a real model class, but cuts off it&amp;#8217;s connection to the database, raising an error any time it tries to connect to the database.&lt;/p&gt;


	&lt;p&gt;This is inspired by projects like &lt;a href="http://www.dcmanges.com/blog/rails-unit-record-test-without-the-database"&gt;unit_record&lt;/a&gt; and &lt;a href="http://agilewebdevelopment.com/plugins/nulldb"&gt;NullDB&lt;/a&gt;, but let&amp;#8217;s you do things at a more granular level &amp;#8211; allowing you to hit the db in some cases (where you think you really need it) and not in others.&lt;/p&gt;


	&lt;p&gt;Of course, you may prefer to the sort of &amp;#8220;protection&amp;#8221; you get from those projects, which ensure that no code touches the DB at all. If you do, have at it. This is just another option for you.&lt;/p&gt;


	&lt;h3&gt;All this and more&lt;/h3&gt;


	&lt;p&gt;These are just a few of the issues addressed in 1.1.4. For more information, check out the &lt;a href="http://rspec.info/changes.html"&gt;changelog&lt;/a&gt; and &lt;a href="http://rspec.lighthouseapp.com/projects/5645"&gt;lighthouse&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Tue, 27 May 2008 01:07:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:9e423c98-ab13-4d7e-84ec-a3b8eac1620a</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/05/27/rspec-1-1-4</link>
      <category>rspec</category>
      <category>ruby</category>
      <category>railsconf</category>
    </item>
    <item>
      <title>Presenting at RailsConf 2008</title>
      <description>&lt;p&gt;I&amp;#8217;m going to be presenting at &lt;a href="http://en.oreilly.com/rails2008/public/content/home"&gt;RailsConf 2008&lt;/a&gt; on &lt;a href="http://rspec.info"&gt;RSpec&amp;#8217;s&lt;/a&gt; Story Runner. I&amp;#8217;ll be talking about how I approach writing for the Story Runner and address several related issues including:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;plain text stories vs pure Ruby (when is which appropriate?)&lt;/li&gt;
		&lt;li&gt;extending the RailsStory with custom helpers&lt;/li&gt;
		&lt;li&gt;testing forms using &lt;a href="http://agilewebdevelopment.com/plugins/webrat"&gt;webrat&lt;/a&gt; within the Story Runner&lt;/li&gt;
		&lt;li&gt;finding a balance of domain and UI scenarios&lt;/li&gt;
		&lt;li&gt;duplication between stories/scenarios and model/view/controller/helper examples&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;That&amp;#8217;s probably already more than I can cover fairly in a 45 minute presentation, but feel free to make other suggestions if you have them.&lt;/p&gt;


	&lt;p&gt;See you in Portland!&lt;/p&gt;</description>
      <pubDate>Sat, 26 Jan 2008 12:15:59 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:6056951a-8987-4b51-a49b-62397ec2e1af</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/01/26/presenting-at-railsconf-2008</link>
      <category>rails</category>
      <category>ruby</category>
      <category>railsconf</category>
      <category>conferences</category>
    </item>
    <item>
      <title>Presenting at QCon London</title>
      <description>&lt;p&gt;I&amp;#8217;m pleased to report that I&amp;#8217;m going to be presenting at &lt;a href="http://qcon.infoq.com/london/conference/"&gt;QCon London&lt;/a&gt; in March. &lt;a href="http://aslakhellesoy.com"&gt;Aslak Helles&amp;oslash;y&lt;/a&gt;, &lt;a href="http://drnicacademy.com/who"&gt;Dr. Nic Williams&lt;/a&gt;, &lt;a href="http://glu.ttono.us/"&gt;Kevin Clark&lt;/a&gt; and I have been invited to present about various aspects of &lt;a href="http://qcon.infoq.com/london/tracks/show_track.jsp?trackOID=90"&gt;The Rise of Ruby&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;We&amp;#8217;ll also be running &lt;a href="http://qcon.infoq.com/london/schedule/monday.jsp"&gt;tutorials on Monday&lt;/a&gt;. Aslak and I will present &lt;a href="http://qcon.infoq.com/london/presentation/Ruby+for+Java+%26+C%23+programmers"&gt;Ruby for Java and C# Programmers&lt;/a&gt; and Dr. Nic will present on &lt;a href="http://qcon.infoq.com/london/presentation/Rails"&gt;Rails&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Wed, 09 Jan 2008 18:29:30 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:0541d164-42ed-4d31-a43e-65f35c2dea7c</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/01/09/presenting-at-qcon-london</link>
      <category>ruby</category>
      <category>qcon</category>
      <category>conferences</category>
    </item>
    <item>
      <title>Advanced Rails Recipes</title>
      <description>&lt;p&gt;I&amp;#8217;m pleased to announce that my contribution to &lt;a href="http://www.clarkware.com/about.html"&gt;Mike Clark&amp;#8217;s&lt;/a&gt; new &lt;a href="http://www.pragprog.com/titles/fr_arr"&gt;Advanced Rails Recipes&lt;/a&gt; book has been accepted and released. &lt;a href="http://www.pragprog.com/titles/fr_arr"&gt;The book&lt;/a&gt; is available right now as a Beta &lt;span class="caps"&gt;PDF&lt;/span&gt; and includes dozens of delicious and nutritious recipes for enhancing your Rails applications and the process of developing them.&lt;/p&gt;


	&lt;p&gt;This is my first formal publication in the software world [1], and I couldn&amp;#8217;t be more pleased than to have it be a &lt;a href="http://www.pragprog.com/titles"&gt;Pragmatic Bookshelf&lt;/a&gt; [2] publication.&lt;/p&gt;


	&lt;p&gt;My recipe is entitled Describing Behaviour from the Outside-In With RSpec and it demonstrates the &lt;span class="caps"&gt;BDD&lt;/span&gt; approach to Rails apps starting with the view and working your way down to the controllers, models and database.&lt;/p&gt;


	&lt;p&gt;There is currently one other &lt;span class="caps"&gt;BDD&lt;/span&gt; recipe: Getting Started with &lt;span class="caps"&gt;BDD&lt;/span&gt;, which uses &lt;a href="http://thoughtbot.com/projects/shoulda"&gt;shoulda&lt;/a&gt;. There are also recipes for cooking up mocks, code coverage and html validity. And that&amp;#8217;s just the testing related recipes.&lt;/p&gt;


	&lt;p&gt;There are also dozens of recipes dealing with UI, search, email, console, &lt;span class="caps"&gt;REST&lt;/span&gt;, db enhancements and even more general design improvements.&lt;/p&gt;


	&lt;p&gt;Like the first &lt;a href="http://www.pragprog.com/titles/fr_rr"&gt;Rails Recipes&lt;/a&gt; book, this one is a must-have for any serious Rails developer who wants to take it up a notch in creating great web applications with Rails.&lt;/p&gt;


&lt;hr&gt;

	&lt;p&gt;[1] My first publication of any kind was back around 1980 when I was a young professional magician. The book is called, simply, &lt;a href="http://www.magicproshop.com/coin-magic-book-richard-kaufman-p-4654.html"&gt;Coin Magic&lt;/a&gt;, and is a must have for any serious coin magician who wants to take it up a notch (see a trend here?) in presenting awesome feats of magic with ordinary coins. Back then I went by my first and middle name, David Arthur.&lt;/p&gt;


	&lt;p&gt;[2] The &lt;a href="http://www.pragprog.com/"&gt;Pragmatic Programmers&lt;/a&gt; are also publishing my upcoming book with co-author &lt;a href="http://blog.aslakhellesoy.com/"&gt;Aslak Helles&amp;oslash;y&lt;/a&gt;, tentatively entitled Behaviour Driven Development in Ruby with RSpec.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Jan 2008 12:04:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:47fbc809-4446-40d7-91d5-0773963d7b4d</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2008/01/04/advanced-rails-recipes</link>
      <category>rails</category>
      <category>ruby</category>
      <category>rspec</category>
      <category>bdd</category>
    </item>
    <item>
      <title>rspec and autotest</title>
      <description>&lt;p&gt;At &lt;a href="http://conferences.oreillynet.com/rails/"&gt;RailsConf 2007&lt;/a&gt; in Portland, I had the privilege of sitting down w/ &lt;a href="http://zenspider.com"&gt;Ryan Davis&lt;/a&gt; and working with him to improve the runtime relationship between &lt;a href="http://rspec.rubyforge.org"&gt;RSpec&lt;/a&gt; and &lt;a href="http://zentest.rubyforge.org/ZenTest/"&gt;Autotest&lt;/a&gt;. David Goodlad was at the table as well, and helped me work out some of the mappings so autotest runs the right examples when you change application code.&lt;/p&gt;


	&lt;p&gt;The result is that with RSpec &amp;gt;= 1.0.3 and ZenTest &amp;gt;= 3.6.0, you can now use Autotest with RSpec on your Ruby projects, Rails or otherwise, simply by typing &amp;#8220;autotest&amp;#8221; in the project root. No additional plugins necessary. Sweet.&lt;/p&gt;


	&lt;p&gt;One gotcha: Some have reported that when an example fails, autotest keeps running it over and over again until you get it to pass. This is due to a conflict between RSpec&amp;#8217;s and autotest&amp;#8217;s mechanisms for narrowing down the set of files to run. This is easily resolved by removing the following lines from spec/spec.opts:&lt;/p&gt;


&lt;pre&gt;
--format
failing_examples:previous_failures.txt
--example
previous_failures.txt
&lt;/pre&gt;

	&lt;p&gt;If you run &amp;#8216;script/generate rspec&amp;#8217;, these lines will not be included in the generated spec.opts file. Otherwise you can just delete them yourself.&lt;/p&gt;</description>
      <pubDate>Tue, 29 May 2007 08:19:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:aa4bc473-d7ab-40e1-9c17-4ca3aeb12409</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2007/05/29/rspec-and-autotest</link>
      <category>rspec</category>
      <category>ruby</category>
      <category>autotest</category>
    </item>
    <item>
      <title>RSpec-0.9 is finally released</title>
      <description>&lt;p&gt;We finally released RSpec-0.9 today. We had a little trouble w/ 0.9.0, so we skipped ahead to 0.9.1.&lt;/p&gt;


To get the gem:
&lt;pre&gt;gem install rspec&lt;/pre&gt;

To install the Spec::Rails plugin:
&lt;pre&gt;ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/REL_0_9_1/rspec
ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/REL_0_9_1/rspec_on_rails&lt;/pre&gt;

	&lt;p&gt;This release comprises myriad improvements and changes, some of which I&amp;#8217;ve blogged about here, the rest of which you can &lt;a href="http://rspec.rubyforge.org/changes.html"&gt;read about&lt;/a&gt; on the &lt;a href="http://rspec.rubyforge.org"&gt;rspec website&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Of special note is our growing list of &lt;a href="http://rspec.rubyforge.org/team.html"&gt;contributors&lt;/a&gt;. It is very exciting to be involved with a project that has such an active user group filled with imaginative people who have contributed some of RSpec&amp;#8217;s most exciting new features.&lt;/p&gt;


	&lt;p&gt;Thank you, thank you, thank you to all who participate whether it is through patches, feature requests, bug reports, or simply interacting on the mailing lists. You&amp;#8217;ve all had an important impact on RSpec&amp;#8217;s growth.&lt;/p&gt;</description>
      <pubDate>Tue, 01 May 2007 08:45:36 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:413f44e4-babc-41b3-a67d-5f3eb28e5858</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2007/05/01/rspec-0-9-is-finally-released</link>
      <category>rspec</category>
      <category>ruby</category>
      <category>bdd</category>
      <trackback:ping>http://blog.davidchelimsky.net/articles/trackback/236</trackback:ping>
    </item>
    <item>
      <title>RSpec-0.9.1 and Autotest (ZenTest-3.5.2)</title>
      <description>&lt;p&gt;&lt;a href="http://zentest.rubyforge.org/ZenTest/classes/Autotest.html"&gt;Autotest&lt;/a&gt; (part of &lt;a href="http://zentest.rubyforge.org"&gt;ZenTest&lt;/a&gt;) now supports &lt;a href="http://rspec.rubyforge.org"&gt;RSpec&lt;/a&gt;. This is fantastic news! For those of you who do not know about autotest, it is a program that runs in the background while you are writing your tests and code. Each time you make a change it automatically reruns your tests &amp;#8211; and now your specs, too! This is a powerful addition to the &lt;span class="caps"&gt;TDD&lt;/span&gt;/BDD experience.&lt;/p&gt;


	&lt;p&gt;Recent releases of both tools overlapped a bit so there are changes in &lt;a href="http://rubyforge.org/frs/shownotes.php?release_id=11423"&gt;RSpec-0.9.1&lt;/a&gt; that are not reflected yet in ZenTest. Also, while ZenTest-3.5.2 supports &lt;a href="http://rspec.rubyforge.org/documentation/rails/index.html"&gt;Spec::Rails&lt;/a&gt;, RSpec&amp;#8217;s &lt;a href="http://rubyonrails.com"&gt;Ruby on Rails&lt;/a&gt; plugin, it does not support non-Rails Ruby projects.&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve submitted a patch to the ZenTest project which addresses both of these issues. Until the patch is applied, or the issues are addressed in some other way, you can apply it yourself to get autotest working with RSpec for Rails and other projects. These steps work on a mac. I assume that the commands are quite similar for Linux and Cygwin users.&lt;/p&gt;


&lt;ol&gt;
&lt;li&gt;Go to http://rubyforge.org/frs/?group_id=419 and download ZenTest-3.5.2.tgz&lt;/li&gt;
&lt;li&gt;Unpack the tar and 
&lt;pre&gt;tar zxvf ZenTest-3.5.2.tgz
cd ZenTest-3.5.2
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Get and install the patch
&lt;pre&gt;curl -O http://blog.davidchelimsky.net/files/ZenTest-3.5.2-rspec.patch
patch -p0 &amp;lt; ZenTest-3.5.2-rspec.patch
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Build and install the gem
&lt;pre&gt;rake gem
sudo gem install pkg/ZenTest-3.5.2.gem
&lt;/pre&gt;
&lt;/ol&gt;

	&lt;p&gt;Once you&amp;#8217;ve built and installed the patched gem, you run autotest as normal. Stand in the root of your project and say:&lt;/p&gt;


&lt;pre&gt;autotest&lt;/pre&gt;

	&lt;p&gt;If you have a &lt;code&gt;spec&lt;/code&gt; directory at the root of your project, autotest will load up rspec_rails_autotest for Rails projects and rspec_autotest for everything else.&lt;/p&gt;


	&lt;p&gt;To quote &lt;a href="http://joshknowles.com/2007/4/13/zentest-3-5-rspec-0-9-autospec"&gt;Josh Knowles&lt;/a&gt;, Happy (Auto)Specing!&lt;/p&gt;</description>
      <pubDate>Tue, 01 May 2007 08:27:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:81ac858d-b9ec-4f5f-ae2a-9c30a13e2ee8</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2007/05/01/rspec-0-9-1-and-autotest-zentest-3-5-2</link>
      <category>rspec</category>
      <category>ruby</category>
      <category>autotest</category>
      <category>bdd</category>
      <enclosure type="text/x-patch" url="http://blog.davidchelimsky.net/files/ZenTest-3.5.2-rspec.patch" length="7548"/>
      <trackback:ping>http://blog.davidchelimsky.net/articles/trackback/235</trackback:ping>
    </item>
    <item>
      <title>predicate_matchers</title>
      <description>&lt;p&gt;&lt;span style="color:red;font-weight:bold;"&gt;Updated on 5/2/2007&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;In RSpec-0.8 if you say &amp;#8230;&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;File.should_exist(path)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;... the expectation passes if File.exist?(path). Here&amp;#8217;s how that should look in RSpec-0.9, with the underscore removed:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;File.should exist(path)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Supporting this for any arbitrary predicate would require more method_missing magic than we were willing to stomach, so we added a means of easily declaring methods like this yourself. We&amp;#8217;ve supplied #exist out of the box, but you can add your own with a simple declaration.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how you do this for an individual behaviour:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;describe Fish do
  predicate_matchers[:swim] = :can_swim?
  it "should swim" do
    Fish.new.should swim
  end
end
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And here&amp;#8217;s how you define them globally, so they are available in every example in your suite:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;Spec::Runner.configure do |config|
  config.predicate_matchers[:swim] = :can_swim?
end
&lt;/code&gt;&lt;/pre&gt;</description>
      <pubDate>Mon, 30 Apr 2007 20:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:dbb0644c-b518-4e11-b0b3-100cb47293f3</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2007/04/30/predicate_matchers</link>
      <category>rspec</category>
      <category>ruby</category>
      <trackback:ping>http://blog.davidchelimsky.net/articles/trackback/233</trackback:ping>
    </item>
    <item>
      <title>rspec.should use_a_little_less_magic</title>
      <description>&lt;p&gt;&lt;span style="color:red;"&gt;Updated on 21 Jan&lt;/span&gt;&lt;/p&gt;


	&lt;p&gt;One of the great things about Ruby is that it allows common folk like you and me to perform all sorts of magic that would dazzle and amaze the more statically typed of our neighbors.&lt;/p&gt;


	&lt;p&gt;One of the terrible things about Ruby is that, as the secret gets out, the various magic potions we mix begin to conflict with each other, creating the foul stench of bugs that don&amp;#8217;t reveal themselves until someone &lt;span class="caps"&gt;ELSE&lt;/span&gt; does some of their own magic.&lt;/p&gt;


	&lt;p&gt;The most visible conflict has been between RSpec and Ruby on Rails, both of which usurp method_missing to support some devilishly sexy run-time method creation. The problem comes when RoR follows good guidelines like late-binding, and adds its version of method_missing later in the stack than RSpec does, rendering RSpec&amp;#8217;s use of method_missing a bit futile, forcing RSpec to monkey patch Rails in order to work.&lt;/p&gt;


	&lt;p&gt;Well, this conflict may soon see its end.&lt;/p&gt;&lt;p&gt;We&amp;#8217;ve just added support for a new way of setting expectations in RSpec that should support all of the existing expectations &lt;span class="caps"&gt;AND&lt;/span&gt; make it very easy to add custom expectations with no method_missing magic or monkey patching. Thanks to Dan North for this )&lt;strong&gt;&amp;#38;)(&lt;/strong&gt;&amp;#38;ing brilliant idea.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s how it looks:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
result.should equal(3)
light.should be_red
newspaper.should be_read
rspec.should use_a_little_less_magic
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;And here&amp;#8217;s how simple it is to add a custom expectation:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
module HotelExpecations
  class BeBookedSolidOn
    def initialize(date)
      @date = date
    end

    def matches?(hotel)
      hotel.booked_solid_on?(@date)
    end

    def failure_message
      "expected hotel to be booked solid on #{@date}" 
    end

    def negative_failure_message
      "expected hotel to not be booked solid on #{@date}" 
    end
  end

  def be_booked_solid_on(date)
    BeBookedSolidOn.new(date)
  end
end

context "Hotel behaviour" do
  include HotelExpectations

  specify "should be considered booked solid with 100 reservations" do
    #given
    @hotel = Hotel.new

    #when
    (1..100).each { @hotel.reserve_room_for(2).on("12/31/2007")

    #then
    @hotel.should be_booked_solid_on("12/31/2007")
  end

  specify "should NOT be considered booked solid with 99 reservations" do
    #given
    @hotel = Hotel.new

    #when
    (1..99).each { @hotel.reserve_room_for(2).on("12/31/2007")

    #then
    @hotel.should_not be_booked_solid_on("12/31/2007")
  end
end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;How easy is that?&lt;img src="?" alt="" /&gt;?!&lt;/p&gt;


	&lt;p&gt;As of this writing, this is only available in the trunk, however it will be quietly released in 0.7.6, and perhaps with a bit more fanfare in 0.8. Those of you who make a habit of using the latest and greatest can do this &lt;span class="caps"&gt;RIGHT NOW&lt;/span&gt;, though beware that until the fanfare is sounded, the details may change a bit.&lt;/p&gt;</description>
      <pubDate>Wed, 10 Jan 2007 06:12:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:db906366-cdc3-4515-bdaa-0522d443d12a</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2007/01/10/rspec-should-use_a_little_less_magic</link>
      <category>rspec</category>
      <category>ruby</category>
      <category>bdd</category>
      <category>rails</category>
    </item>
    <item>
      <title>Fighting the Urge to Ask</title>
      <description>&lt;p&gt;ActiveRecord provides a lot of magic methods that let us get at the properties of a given AR subclass. This is absolutely fantastic news!&lt;/p&gt;


	&lt;p&gt;Except for one thing.&lt;/p&gt;&lt;p&gt;Because the resulting getters are public, the entire world of Rails applications (including those that I have written) is infested with violations of encapsulation, &lt;span class="caps"&gt;TDA&lt;/span&gt; (Tell, Don&amp;#8217;t Ask), Feature Envy and Inappropriate Intimacy. Wow. That&amp;#8217;s some stinky &amp;#38;^#(.&lt;/p&gt;


	&lt;p&gt;So what can be done about this? We don&amp;#8217;t want to encourage the Rails core team to make all the getters private for two reasons. One, there are so many apps in existence already that would break, the entire community would rightfully have my head for even joking about it! Two, it&amp;#8217;s not &lt;span class="caps"&gt;THEIR&lt;/span&gt; responsibility. It&amp;#8217;s &lt;span class="caps"&gt;OURS&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;Think of Ruby and the awesome power that we&amp;#8217;ve been granted by open classes. If you want to screw up the coding world you live in by abusing this ability, then have at it. We&amp;#8217;ve done that in RSpec, and are learning the lessons from having done so (don&amp;#8217;t invade other people&amp;#8217;s classes so much in a framework!).&lt;/p&gt;


	&lt;p&gt;The responsibility is ours, as users of the Rails framework, to use it in responsible ways, adhering to the principles of Object Oriented Design that have guided us through the morass of java and .NET applications that have come before.&lt;/p&gt;


	&lt;p&gt;One example comes from a recent discussion on the RSpec list. The names here have been changed to protect the innocent. Imagine you&amp;#8217;re writing an app for a Veterinarian&amp;#8217;s office in which each Pet belongs to a Person. When you&amp;#8217;re registering a new Pet you want to be able to create the Pet and the Person (pet owner) in one action. So you might have something like this:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
def create
  @person = Person.new(params[:person])
  @pet = Pet.new(params[:pet])
  @person.pets &amp;lt;&amp;lt; @pet
  @person.save
end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Anybody see the violation of &lt;span class="caps"&gt;TDA&lt;/span&gt;? Anybody smell any Feature Envy? For those who don&amp;#8217;t, the problem is in this line:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
  @person.pets &amp;lt;&amp;lt; @pet
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The problem is that this controller code now depends on the internal structure of the Person &amp;#8211; the fact that it keeps a collection of Pets. Now imagine that as this app evolved, we realized that we had the relationship backwards. That, since we are a Pet Health Clinic, after all, everything should revolve around the animal, not the owner. This code (and all the other code in the application like it) will have to change.&lt;/p&gt;


	&lt;p&gt;We can avoid that change, or any other change to how the Person and Pet relate to each other, by adding an add_pet method to Person:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
  @person.add_pet @pet
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now, if we decided to reverse the relationship, we could do by having the implementation of add_pet to turn around and add the Person to the Pet:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
  class Person &amp;lt; ActiveRecord::Base
    def add_pet pet
      pet.add_person(self)
    end
  end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Now you could argue that the code that deals w/ People and Pets &lt;strong&gt;should&lt;/strong&gt; change to correctly reflect the new model. But by applying Tell, Don&amp;#8217;t Ask in this case, we can decide when to make that change based on priorities, not based on urgency.&lt;/p&gt;


	&lt;p&gt;So I urge you to pay attention to these little traps that AR provides for us, and fight the urge to Ask. Just Tell the Other Guy. It&amp;#8217;ll save your ass some day.&lt;/p&gt;</description>
      <pubDate>Mon, 27 Nov 2006 15:19:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:86413593-37d8-46f0-9465-f79b75ec604b</guid>
      <author>David</author>
      <link>http://blog.davidchelimsky.net/articles/2006/11/27/fighting-the-urge-to-ask</link>
      <category>ruby</category>
      <category>rails</category>
      <category>ood</category>
    </item>
  </channel>
</rss>
