<?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>RubyLearning Blog &#187; Steve Klabnik</title>
	<atom:link href="http://rubylearning.com/blog/author/steveklabnik/feed/" rel="self" type="application/rss+xml" />
	<link>http://rubylearning.com/blog</link>
	<description>Helping Ruby Programmers become Awesome</description>
	<lastBuildDate>Tue, 07 May 2013 00:13:02 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>All about Struct</title>
		<link>http://rubylearning.com/blog/2012/09/06/all-about-struct/</link>
		<comments>http://rubylearning.com/blog/2012/09/06/all-about-struct/#comments</comments>
		<pubDate>Thu, 06 Sep 2012 02:19:16 +0000</pubDate>
		<dc:creator>Steve Klabnik</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby programming]]></category>
		<category><![CDATA[struct]]></category>

		<guid isPermaLink="false">http://rubylearning.com/blog/?p=6791</guid>
		<description><![CDATA[Send to Kindle All about Struct This guest post is by Steve Klabnik. Steve is a Rubyist, writer, and teaches Ruby and Rails classes with Jumpstart Lab. He maintains Draper, Hackety Hack, and Shoes, and contributes to Rails from time to time. One of my favorite classes in Ruby is&#160;Struct, but I feel like many [...]<p><a href="http://www.launchbit.com/az/113-209/"><img width="468" height="60" src="http://www.launchbit.com/az-images/113-209/" /></a><br />
<small>(Powered by <a href="http://www.launchbit.com/lb/113-209/">LaunchBit</a>)</small></p>
]]></description>
				<content:encoded><![CDATA[<div class='kindleWidget kindleLight' ><img src="http://rubylearning.com/blog/wp-content/plugins/send-to-kindle/media/black-25.png" /><span>Send to Kindle</span></div><p></p>
<div class="topsy_widget_data topsy_theme_brick-red" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frubylearning.com%252Fblog%252F2012%252F09%252F06%252Fall-about-struct%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FTkmLgm%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22All%20about%20Struct%22%20%7D);"></div>
<div>
<h3>All about Struct</h3>
<p class="update">This guest post is by <strong><a href="https://github.com/steveklabnik">Steve Klabnik</a></strong>. Steve is a Rubyist, writer, and teaches Ruby and Rails classes with Jumpstart Lab. He maintains Draper, Hackety Hack, and Shoes, and<br />
contributes to Rails from time to time.</p>
<p class="block"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright" src="http://rubylearning.com/images/steve_cropped.jpg" alt="Steve Klabnik" /> <span class="drop_cap">O</span>ne of my favorite classes in Ruby is&nbsp;<code>Struct</code>, but I feel like many Rubyists don&#8217;t know when to take advantage of it. The standard library has a lot of junk in it, but&nbsp;<code>Struct</code>&nbsp;and&nbsp;<code>OStruct</code>&nbsp;are super awesome.</p>
<h3 id="struct">Struct</h3>
<p>If you haven&#8217;t used&nbsp;<code>Struct</code>&nbsp;before, here&#8217;s&nbsp;<a href="http://www.ruby-doc.org/core-1.9.3/Struct.html" rel="">the documentation of Struct from the Ruby standard library</a>.</p>
<p>Structs are used to create super simple classes with some instance variables and a simple constructor. Check it:</p>
<pre>Struct.new("Point", &#58;x, :y) #=&gt; Struct::Point
origin = Struct::Point.new(0,0) #=&gt; #</pre>
<p>Nobody uses it this way, though. Here&#8217;s the way I first saw it used:</p>
<pre>class Point &lt; Struct.new(:x, :y)
end
origin = Point.new(0,0)</pre>
<p>Wait, what? Inherit&#8230;from an instance of something? Yep!</p>
<pre>1.9.3p194 :001 &gt; Struct.new(:x,:y) =&gt; #&lt;Class:0x007f8fc38da2e8&gt;</pre>
<p><code>Struct.new</code>&nbsp;gives us a&nbsp;<code>Class</code>. We can inherit from this just like any other&nbsp;<code>Class</code>. Neat!</p>
<p>However, if you&#8217;re gonna make an empty class like this, I prefer this way:</p>
<pre>Point = Struct.new(:x, :y)
origin = Point.new(0,0)</pre>
<p>Yep. Classes are just constants, so we assign a constant to that particular&nbsp;<code>Class</code>.</p>
<p>If you&#8217;d like, you can pass a block to the <code>Struct</code>:</p>
<pre>Point = Struct.new(:x, :y) do
  def translate(x,y)
    self.x += x
    self.y += y
  end
end</pre>
<p>Now we can do this:</p>
<pre>origin = Point.new(0,0)
origin.translate(1,2)
puts origin #=&gt; &lt;struct Point x=1, y=2&gt;</pre>
<h3 id="ostruct">OStruct</h3>
<p><a href="http://ruby-doc.org/stdlib-1.9.3/libdoc/ostruct/rdoc/OpenStruct.html" rel=""><code>OStruct</code></a>s are like&nbsp;<code>Struct</code>&nbsp;on steroids. Check it:</p>
<pre>require 'ostruct'
origin = OpenStruct.new
origin.x = 0
origin.y = 0
origin = OpenStruct.new(:x =&gt; 0, :y =&gt; 0)</pre>
<p><code>OStruct</code>s are particularly good for configuration objects. Since any method works to set data in an&nbsp;<code>OStruct</code>, you don&#8217;t have to worry about enumerating every single option that you need:</p>
<pre>require 'ostruct'

def set_options 
  opts = OpenStruct.new
  yield opts
  opts
end

options = set_options do |o|
  o.set_foo = true
  o.load_path = "whatever:something"
end

options #=&gt; #&lt;OpenStruct set_foo=true, load_path="whatever:something"&gt;</pre>
<p>Neat, eh?</p>
<h3 id="structs_for_domain_concepts">Structs for domain concepts</h3>
<p>You can use&nbsp;<code>Struct</code>s to help reify domain concepts into simple little classes. For example, say we have this code, which uses a date:</p>
<pre>class Person
  attr_accessor :name, :day, :month, :year

  def initialize(opts = {})
    @name = opts[:name]
    @day = opts[:day]
    @month = opts[:month]
    @year = opts[:year]
  end

  def birthday
    "#@day/#@month/#@year"
  end
end</pre>
<p>and we have this spec</p>
<pre>$:.unshift("lib")
require 'person'

describe Person do
  it "compares birthdays" do
    joe = Person.new(:name =&gt; "Joe", :day =&gt; 5, :month =&gt; 6, :year =&gt; 1986)
    jon = Person.new(:name =&gt; "Jon", :day =&gt; 7, :month =&gt; 6, :year =&gt; 1986)

    joe.birthday.should == jon.birthday
  end
end</pre>
<p>It fails, of course. Like this:</p>
<pre>$ rspec
F

Failures:

1) Person compares birthdays
Failure/Error: joe.birthday.should == jon.birthday
expected: "7/6/1986"
got: "5/6/1986" (using ==)
# ./spec/person_spec.rb:9:in `block (2 levels) in'

Finished in 0.00053 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/person_spec.rb:5 # Person compares birthdays</pre>
<p>Now. We have these two birthdays. In this case, we know about why the test was failing, but imagine this failure in a real codebase. Are these month/day/year or day/month/year? You can&#8217;t tell, it could be either. If we switched our code to this:</p>
<pre>class Person
  attr_accessor :name, :birthday

  Birthday = Struct.new(:day, :month, :year)

  def initialize(opts = {})
    @name = opts[:name]
    @birthday = Birthday.new(opts[:day], opts[:month], opts[:year])
  end
end</pre>
<p>We get this failure instead:</p>
<pre>$ rspec
F

Failures:

1) Person compares birthdays
Failure/Error: joe.birthday.should == jon.birthday
expected: #&lt;struct Person::Birthday day=7, month=6, year=1986&gt;
got: #&lt;struct Person::Birthday day=5, month=6, year=1986&gt; (using ==)

Diff:
@@ -1,2 +1,2 @@
-#&lt;struct Person::Birthday day=7, month=6, year=1986&gt;
+#&lt;struct Person::Birthday day=5, month=6, year=1986&gt;
# ./temp.rb:18:in `block (2 levels) in &lt;top (required)&gt;'

Finished in 0.00514 seconds

1 example, 1 failure Failed examples: rspec ./spec/person_spec.rb:5 # Person compares birthdays</pre>
<p>We have a way, way more clear failure. We can clearly see that its our days that are off.</p>
<p>Of course, there are other good reasons to package related instance variables into&nbsp;<code>Struct</code>s, too: it makes more conceptual sense. This code represents our intent better: a Person has a Birthday, they don&#8217;t have three unrelated numbers stored inside them somehow. If we need to add something to our concept of birthdays, we now have a place to put it.</p>
<p class="update"><em>I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post.</em> Also, do check out Steve&#8217;s other articles: &#8220;<a href="http://rubylearning.com/blog/2011/07/28/how-do-i-test-my-code-with-minitest/">How do I test my code with Minitest?</a> and &#8220;<a href="http://rubylearning.com/blog/2010/12/20/how-do-i-keep-multiple-ruby-projects-separate/">How do I keep multiple Ruby projects separate?</a>&#8221; on RubyLearning. Thanks!</p>
</div>
<p>Technorati Tags: <a href="http://technorati.com/tag/struct" rel="tag">struct</a>, <a href="http://technorati.com/tag/Programming" rel="tag"> Programming</a>, <a href="http://technorati.com/tag/Ruby+programming" rel="tag">Ruby programming</a></p>
Posted by <b>Steve Klabnik</b><p><a href="http://www.launchbit.com/az/113-209/"><img width="468" height="60" src="http://www.launchbit.com/az-images/113-209/" /></a><br />
<small>(Powered by <a href="http://www.launchbit.com/lb/113-209/">LaunchBit</a>)</small></p>

]]></content:encoded>
			<wfw:commentRss>http://rubylearning.com/blog/2012/09/06/all-about-struct/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>How do I test my code with Minitest?</title>
		<link>http://rubylearning.com/blog/2011/07/28/how-do-i-test-my-code-with-minitest/</link>
		<comments>http://rubylearning.com/blog/2011/07/28/how-do-i-test-my-code-with-minitest/#comments</comments>
		<pubDate>Thu, 28 Jul 2011 04:13:48 +0000</pubDate>
		<dc:creator>Steve Klabnik</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Masters]]></category>
		<category><![CDATA[minitest]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby programming]]></category>

		<guid isPermaLink="false">http://rubylearning.com/blog/?p=5848</guid>
		<description><![CDATA[Send to Kindle How do I test my code with Minitest? This guest post is by Steve Klabnik, who is a software craftsman, writer, and former startup CTO. Steve tries to keep his Ruby consulting hours down so that he can focus on maintaining Hackety Hack and being a core member of Team Shoes, as [...]<p><a href="http://www.launchbit.com/az/113-209/"><img width="468" height="60" src="http://www.launchbit.com/az-images/113-209/" /></a><br />
<small>(Powered by <a href="http://www.launchbit.com/lb/113-209/">LaunchBit</a>)</small></p>
]]></description>
				<content:encoded><![CDATA[<div class='kindleWidget kindleLight' ><img src="http://rubylearning.com/blog/wp-content/plugins/send-to-kindle/media/black-25.png" /><span>Send to Kindle</span></div><p></p>
<div class="topsy_widget_data topsy_theme_brick-red" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frubylearning.com%252Fblog%252F2011%252F07%252F28%252Fhow-do-i-test-my-code-with-minitest%252F%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22How%20do%20I%20test%20my%20code%20with%20Minitest%3F%22%20%7D);"></div>
<div>
<h3>How do I test my code with Minitest?</h3>
<p class="update">This guest post is by <strong><a href="https://github.com/steveklabnik">Steve Klabnik</a></strong>, who is a software craftsman, writer, and former startup CTO. Steve tries to keep his Ruby consulting hours down so that he can focus on maintaining <a href="http://hackety-hack.com/">Hackety Hack</a> and being a core member of Team Shoes, as well as writing regularly for multiple blogs.</p>
<p class="block"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright" src="http://rubylearning.com/images/steve_cropped.jpg" alt="Steve Klabnik" /> <span class="drop_cap">P</span>rogramming is an interesting activity. Everyone has their favorite&nbsp;metaphor that really explains what programming means to them. Well, I&nbsp;have a few, but here&#8217;s one: Programming is all about automation. You&#8217;re&nbsp;really just getting the computer to automatically do work that you know&nbsp;how to do, but don&#8217;t want to do over and over again.</p>
<p>When I realized this, it made me look for other things that I do that&nbsp;could be automated. I don&#8217;t like repeating myself over and over and over&nbsp;again. That&#8217;s boring! Well, there&#8217;s one particular task that&#8217;s related&nbsp;to programming that&#8217;s easily made automatic, and that&#8217;s testing that&nbsp;your software works!</p>
<p>Does this story sound familiar? You run your program, try a few&nbsp;different inputs, check the outputs, and see that they&#8217;re right. Then,&nbsp;you make some changes in your code, and you&#8217;d like to see if they work&nbsp;or not, so you fire up Ruby and try those inputs again. That repetition&nbsp;should stick out. There has to be a better way.</p>
<p>Luckily, there is! Ruby has fantastic tools that let you set up tests&nbsp;for your code that you can run automatically. You can save yourself tons&nbsp;of time and effort by letting the computer run thousands of tests every&nbsp;time you make a change to your code. And it&#8217;ll never get tired and&nbsp;accidentally type in a 2 when you mean to type 3&#8230; Many people take&nbsp;this one step farther. They find testing so important and so helpful&nbsp;that they actually write the tests before they write the code! I won&#8217;t&nbsp;expound on the virtues of &#8220;test driven development&#8221; in this post, but&nbsp;it&#8217;s actually easier to write the tests first, once you get some&nbsp;practice at it. So, let&#8217;s pick a tiny bit of code to work on, and I&#8217;ll&nbsp;show you how to test it using Ruby&#8217;s built-in testing library, minitest.</p>
<p>For this exercise, let&#8217;s do something simple, so we can focus on the&nbsp;tests. We&#8217;ll make a Ruby class called CashRegister. It&#8217;ll have a bunch&nbsp;of features, but here&#8217;s the first two methods we&#8217;ll need:</p>
<ul>
<li>The register will have a scan method that takes in a price, and&nbsp;records it.</li>
<li>The register will have a total method that shows the current total of&nbsp;all the prices that have been scanned so far.</li>
<li>If no prices have been scanned, the total should be zero.</li>
<li>The register will have a clear method that clears the register of all&nbsp;scanned items. The total should go back to zero again.</li>
</ul>
<p>Seems simple, right? You might even know how to code this already.&nbsp;Sometimes, intermediate programmers practice coding problems that are&nbsp;easy, just to focus on how to write good tests, or to work on getting&nbsp;the perfect design. We call these kinds of problems &#8216;kata.&#8217; It&#8217;s a&nbsp;martial arts thing.</p>
<p>Anyway, enough about all of this! Let&#8217;s dig in to minitest. It already&nbsp;comes with Ruby 1.9, but if you&#8217;re still using 1.8, you can install it&nbsp;with &#8216;<code>gem install minitest</code>.&#8217; After doing so, open up a new file,&nbsp;register.rb, and put this in it:</p>
<pre>require 'minitest/autorun'

class TestCashRegister &lt; MiniTest::Unit::TestCase
  def setup
    @register = CashRegister.new
  end
  def test_default_is_zero
    assert_equal 0, @register.total
  end
end</pre>
<p>Okay! There&#8217;s a lot going on here. Let&#8217;s take it line by line. On the first line, we have a &#8216;require.&#8217; The autorun part of minispec includes everything you need to run your tests, automatically. All we need to do to run our tests is to type ruby register.rb, and they&#8217;ll run and check our code. But let&#8217;s look at the rest of the file before we do that. The next thing we do is set up a class that inherits from one of minitest&#8217;s base classes. That&#8217;s how minitest works, by running a series of TestCases. It also lets you group similar tests together, and split different ones up into multiple files.</p>
<p>Anyway, enough organizational stuff. In this class, we have two methods: the first is the setup method. This runs before each test, and allows us to prepare for the test we want to run. In this case, we want a new CashRegister each time, and we&#8217;ll store it in a variable. Now we don&#8217;t have to repeat our setup over and over again&#8230; it&#8217;s just automatic!</p>
<p>Finally, we get down to business, with the <code>test_default_is_zero</code> method. Minitest will run any method that starts with test_ as a test. In that method, we use the <code>assert_equal</code> method with two arguments. <code>assert_equal</code> is where it all happens, by comparing 0 to our register&#8217;s total, and it will complain if they&#8217;re not equal.</p>
<p>Okay, so we have our first test. Rock! You might be tempted to start implementing our CashRegister class, but wait! Let&#8217;s try running the tests first. We know they&#8217;ll fail, because we don&#8217;t even have a CashRegister yet! But if we run the tests before writing code, the error messages will tell us what we need to do next. The tests will guide us through the implementation of our class. So, as I mentioned earlier, we can run the tests by doing this:</p>
<pre>$ ruby register.rb</pre>
<p>We get this as output:</p>
<pre>Loaded suite register
Started
E
Finished in 0.000853 seconds.

1) Error:
test_default_is_zero(TestRegister):
NameError: uninitialized constant TestRegister::CashRegister
register.rb:5:in `setup'

1 tests, 0 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 36463</pre>
<p>Whoah! Okay, so you can see that we had one test, one error. Since we know classes are constants in Ruby, we know that the uninitialized constant error means we haven&#8217;t defined our class yet! So let&#8217;s do that. Go ahead and stick in an empty class at the bottom:</p>
<pre>class CashRegister
end</pre>
<p>And run the tests again. You should see this:</p>
<pre>1) Error:
test_default_is_zero(TestRegister):
NoMethodError: undefined method `total' for #&lt;CashRegister:0x00000101032a80&gt;
register.rb:9:in `test_default_is_zero'</pre>
<p>Progress! Now it says we don&#8217;t have a total method. So let&#8217;s define an empty one. Modify the class like this:</p>
<pre>class CashRegister
  def total
  end
end</pre>
<p>And run the tests again. Another failure:</p>
<pre>1) Failure:
test_default_is_zero(TestRegister) [register.rb:9]:
Expected 0, not nil.</pre>
<p>Okay! No more syntax errors, just the wrong result. Let&#8217;s keep it as simple as possible, and fill out a nice and easy total method:</p>
<pre>def total
  0
end</pre>
<p>Now, you may be saying, &#8220;Steve, that doesn&#8217;t calculate a total!&#8221; Well, you&#8217;re right. It doesn&#8217;t. But our tests aren&#8217;t yet asking to calculate a total, they&#8217;re just asking for a default. If we want a total, we should write a test that actually demonstrates adding it up. But we have fulfilled objective #3, so we&#8217;re doing good! Now, let&#8217;s work on objective #2, since we sorta feel like the total method is lying about what it&#8217;s supposed to do. In order to add up the items that were scanned, we need to scan them in the first place! Objective #1 says that this method should be called scan, so let&#8217;s write a test. Put it in your test class with the test_default_is_zero method:</p>
<pre>def test_total_calculation
  @register.scan 1
  @register.scan 2
  assert_equal 3, @register.total
end</pre>
<p>Make sense? We want to scan two things in, and then check that the total is correct. Let&#8217;s run our tests!</p>
<pre>Loaded suite register
Started
.E
Finished in 0.000921 seconds.

1) Error:
test_total_calculation(TestRegister):
NoMethodError: undefined method `scan' for #&lt;CashRegister:0x00000101031838&gt;
register.rb:13:in `test_total_calculation'

2 tests, 1 assertions, 0 failures, 1 errors, 0 skips

Test run options: --seed 54501</pre>
<p>Okay! See that &#8216;.E&#8217; up there? That graphically shows that we had one test passing, and one test with an error. Our first test still works, but our second is failing because we don&#8217;t have a scan method. Add an empty one to our CashRegister class, and run again:</p>
<pre>1) Error:
test_total_calculation(TestRegister):
ArgumentError: wrong number of arguments (1 for 0)
register.rb:24:in `scan'
register.rb:13:in `test_total_calculation'</pre>
<p>Whoops! It takes an argument. Let&#8217;s add that: def scan(price). Run the tests!</p>
<pre>1) Failure:
test_total_calculation(TestRegister) [register.rb:15]:
Expected 3, not 0.</pre>
<p>Okay! This sounds more like what we expected. Our total method just returns zero all the time! Let&#8217;s think about this for a minute. We need to have scan add the price to a list of scanned prices. So we&#8217;d better have it do that:</p>
<pre>def scan(item)
  @items &lt;&lt; item
end</pre>
<p>But if you run the tests, you&#8217;ll see this:</p>
<pre>1) Error:
test_total_calculation(TestRegister):
NoMethodError: undefined method `&lt;&lt;' for nil:NilClass
register.rb:25:in `scan'
register.rb:13:in `test_total_calculation'</pre>
<p>Oops! @items is undefined. Let&#8217;s make it be an empty array, when we create our register:</p>
<pre>def initialize
  @items = []
end</pre>
<p>And run the tests:</p>
<pre>1) Failure:
test_total_calculation(TestRegister) [register.rb:15]:
Expected 3, not 0.</pre>
<p>Okay! We&#8217;re back to our original failure. But we&#8217;ve made some progress: now that we have an actual list of items, we&#8217;re in a position to make our total method work. Also, at each step, even though one test was failing, the other was still passing, so we know that we didn&#8217;t break our default functionality while we were working on getting a real total going.</p>
<p>Now, we&#8217;re in a better place to calculate the total:</p>
<pre>def total
  @items.inject(0) {|sum, item| sum += item }
end</pre>
<p>Or, if you want to make it even shorter:</p>
<pre>def total
  @items.inject(0, &amp;:+)
end</pre>
<p>If you&#8217;re not familiar with <code>Enumerable#inject</code>, it takes a list of somethings and turns it into a single something by means of a function, in a block. So in this case, we can keep a running sum of all items, and then add the price of each one to the sum. Done! Run your tests:</p>
<pre>Started
..
Finished in 0.000762 seconds.

2 tests, 2 assertions, 0 failures, 0 errors, 0 skips</pre>
<p>Woo hoo! We&#8217;re done! Our total can now be calculated. Great job!</p>
<p>Now, here&#8217;s a challenge, to see if you&#8217;ve really learned this stuff: write a test for a new method, clear, that clears the total. That&#8217;s objective #4 we talked about above.</p>
<h4>Other parts of minitest</h4>
<p>This has been a mini intro to minitest and using it to test your code. There are other methods in the <code>assert</code> family, too, like <code>assert_match</code>, which takes a regular expression and tries to match it against something. There&#8217;s the <code>refute</code> family of tests, which are the opposite of <code>assert</code>:</p>
<pre>assert true #=&gt; pass
refute true #=&gt; fail</pre>
<p>There are also other tools that make minitest useful, like mocks, benchmark tests, and the RSpec-style &#8216;spec&#8217; syntax. Those will have to wait until later! If you&#8217;d like to learn about them now, check out <a href="https://github.com/seattlerb/minitest">the source code on GitHub.</a></p>
<p>Happy testing!</p>
<p class="update"><em>I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post.</em> Also, do check out Steve&#8217;s other article: &#8220;<a href="http://rubylearning.com/blog/2010/12/20/how-do-i-keep-multiple-ruby-projects-separate/">How do I keep multiple Ruby projects separate?</a>&#8221; on RubyLearning. Thanks!</p>
</div>
<p>Technorati Tags: <a href="http://technorati.com/tag/minitest" rel="tag">minitest</a>, <a href="http://technorati.com/tag/Programming" rel="tag"> Programming</a>, <a href="http://technorati.com/tag/Ruby+programming" rel="tag">Ruby programming</a></p>
Posted by <b>Steve Klabnik</b><p><a href="http://www.launchbit.com/az/113-209/"><img width="468" height="60" src="http://www.launchbit.com/az-images/113-209/" /></a><br />
<small>(Powered by <a href="http://www.launchbit.com/lb/113-209/">LaunchBit</a>)</small></p>

]]></content:encoded>
			<wfw:commentRss>http://rubylearning.com/blog/2011/07/28/how-do-i-test-my-code-with-minitest/feed/</wfw:commentRss>
		<slash:comments>40</slash:comments>
		</item>
		<item>
		<title>How do I keep multiple Ruby projects separate?</title>
		<link>http://rubylearning.com/blog/2010/12/20/how-do-i-keep-multiple-ruby-projects-separate/</link>
		<comments>http://rubylearning.com/blog/2010/12/20/how-do-i-keep-multiple-ruby-projects-separate/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 07:20:32 +0000</pubDate>
		<dc:creator>Steve Klabnik</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Popular]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Masters]]></category>
		<category><![CDATA[Bundler]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby programming]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://rubylearning.com/blog/?p=5431</guid>
		<description><![CDATA[Send to Kindle How do I keep multiple Ruby projects separate? This guest post is by Steve Klabnik, who is a software craftsman, writer, and former startup CTO. Steve tries to keep his Ruby consulting hours down so that he can focus on maintaining Hackety Hack and being a core member of Team Shoes, as [...]<p><a href="http://www.launchbit.com/az/113-209/"><img width="468" height="60" src="http://www.launchbit.com/az-images/113-209/" /></a><br />
<small>(Powered by <a href="http://www.launchbit.com/lb/113-209/">LaunchBit</a>)</small></p>
]]></description>
				<content:encoded><![CDATA[<div class='kindleWidget kindleLight' ><img src="http://rubylearning.com/blog/wp-content/plugins/send-to-kindle/media/black-25.png" /><span>Send to Kindle</span></div><p></p>
<div class="topsy_widget_data topsy_theme_brick-red" style="float: right;margin-left: 0.75em; background: url(data:,%7B%20%22url%22%3A%20%22http%253A%252F%252Frubylearning.com%252Fblog%252F2010%252F12%252F20%252Fhow-do-i-keep-multiple-ruby-projects-separate%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FeU1Mf1%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22How%20do%20I%20keep%20multiple%20Ruby%20projects%20separate%3F%22%20%7D);"></div>
<div>
<h3>How do I keep multiple Ruby projects separate?</h3>
<p class="update">This guest post is by <strong><a href="https://github.com/steveklabnik">Steve Klabnik</a></strong>, who is a software craftsman, writer, and former startup CTO. Steve tries to keep his Ruby consulting hours down so that he can focus on maintaining <a href="http://hackety-hack.com/">Hackety Hack</a> and being a core member of Team Shoes, as well as writing regularly for multiple blogs.</p>
<p class="block"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright" src="http://rubylearning.com/images/steve_cropped.jpg" alt="Steve Klabnik" /> <span class="drop_cap">I</span>f you&#8217;re anything like me, you&#8217;re already starting a new project immediately after wrapping up the last one. There just aren&#8217;t enough hours in the day to code up all the crazy ideas I have floating around in my head. Often, these ideas are the result of checking out some fun new gem, GitHub project, or even a different Ruby. Real quickly, a problem develops: what happens when these projects interfere with one another? What if I want to use Ruby 1.8.7 for an older project, Ruby 1.8.5 for a legacy application, Ruby 1.9.2 for the latest and greatest, and JRuby to use an interesting Ruby library? Luckily, there are a few things that you can do to isolate your different projects from one another, and some settings for that will make them quite painless to use. There are three main things that can go wrong when you try to use different sets of tools on a per-project basis: conflicts between Ruby versions, conflicts between gems, and forgetting which tools you use on which project.</p>
<h3>Ruby Version Conflicts</h3>
<p>This is the biggest and most painful kind of problem. If you want to use Ruby 1.8 for one project and Ruby 1.9 for another, you have a problem. If you&#8217;re using Linux, for example, your package manager may see that both ruby18 and ruby19 fulfill a &#8216;ruby&#8217; dependency, and so it won&#8217;t let you have them both installed side by side. The solution isn&#8217;t pretty: install different Rubies from source. This gets ugly really quickly, because it&#8217;s easy to forget where you&#8217;ve compiled different Rubies, and having software outside of your package manager isn&#8217;t a great answer. If you&#8217;re on OS X or Windows, you skip right past the package manager problem and straight to the source &#8216;solution.&#8217; This is no good!</p>
<p>Luckily, there&#8217;s an awesome project by Wayne E. Seguin named <a href="http://rvm.beginrescueend.com/">rvm</a>. rvm is sort of like a package manager for Ruby. If you&#8217;d like to install both Ruby 1.8.7 and 1.9.2, just type this in:</p>
<pre>$ rvm install 1.8.7
$ rvm install 1.9.2</pre>
<p>It&#8217;ll go fetch the Ruby source code, compile it, and get you all set up. To use a specific Ruby, you can type &#8216;use&#8217;:</p>
<pre>$ rvm use 1.8.7
$ ruby -v
ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10.4.0]
$ rvm use 1.9.2
$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]</pre>
<p>Neat! You can even get other Ruby versions:</p>
<pre>$ rvm install jruby
$ rvm install rbx
$ rvm install macruby</pre>
<p>You can see a full list of these with &#8216;rvm list known&#8217;. For a full list of everything that rvm can do, as well as installation instructions, visit <a href="http://rvm.beginrescueend.com/">the rvm website.</a></p>
<h3>Gem Conflicts</h3>
<p>Once you&#8217;ve gotten your Rubies straight, you can still have conflicts between different gems that your project needs. One project uses Rails 2.3.8, another uses Rails 3&#8230; It gets worse when you have certain gems installed only as a dependency, and you don&#8217;t know exactly which one is correct:</p>
<pre>$ gem list | grep net-ssh
net-ssh (2.0.23, 2.0.4, 1.1.4)</pre>
<p>rvm has a neat feature called &#8216;gemsets.&#8217; They let you create separate sets of gems per Ruby you have installed. This allows you to isolate each application, giving it its own set of gems. Check it out:</p>
<pre>$ gem list

*** LOCAL GEMS ***

aasm (2.1.5)
abstract (1.0.0)
acl9 (0.12.0)
*snip*

$ rvm gemset create new-gemset
$ rvm use 1.9.2@new-gemset
$ gem list

*** LOCAL GEMS ***

$</pre>
<p>Cool stuff! As you can see, use an &#8216;@&#8217; symbol to tell rvm which gemset you&#8217;d like to use. Now we&#8217;ve isolated each project&#8217;s gems from each other. There is, however, a much more complicated kind of conflicts that can occur between gems. This happens when two gems have interlocking dependencies.</p>
<p>Here&#8217;s an example of this from the past: ActionPack 2.3.5 requires Rack =1.0.0, which is the newest version. Unicorn requires Rack &gt;1.0.0. Rack releases a new version, 1.1.0. Now, when starting up a Rails application, the unicorn gem is loaded first, so it loads the newest version of the gem that works, which is rack-1.1.0. Then rails loads, and it loads actionpack, which tries to load rack. It needs =1.0.1, but sees that 1.1.0 has already been loaded, and throws this ugly, ugly error:</p>
<pre>Gem::LoadError: can't activate rack (~&gt; 1.0.0, runtime)
for ["actionpack-2.3.5"], already activated rack-1.1.0
for ["unicorn"]</pre>
<p>There&#8217;s a set of versions here that works, but the way that the gems are loaded means that it doesn&#8217;t. The problem is that at the time that unicorn loads, it can&#8217;t possibly know that you&#8217;re planning on loading a different version of rack somewhere down the line. What we really need is a tool that knows about all of our dependencies, and can calculate the graph of all of our requirements, and figure out which versions of everything we need, and then only place those versions on the $LOAD_PATH. Luckily, such a project exists: <a href="http://gembundler.com/">bundler</a>.</p>
<p>To use bundler, you first need to make a file named &#8216;Gemfile&#8217; in the root of your project directory. This file looks something like this:</p>
<pre>source "http://rubygems.org"

gem "rails", "~&gt;3.0.0"

group :development do
  gem 'sqlite3-ruby', :require =&gt; 'sqlite3'
end

group :production do
  gem "pg"
end</pre>
<p>The first line tells Bundler where to look for gems. The second line says that we want to use the &#8216;rails&#8217; gem, and we want any version that&#8217;s at least 3.0.0 but less than 3.1.0. Finally, the other lines show &#8216;groups&#8217; of gems: in development, we want to use sqlite3-ruby, and we need to require it via the name &#8216;sqlite3&#8242;, but we want to use Postgres in production. To install these gems, just:</p>
<pre>$ bundle install</pre>
<p>Bundler gets all the information that it needs on all the gems, figures out what versions of everything work together, and then installs the right versions. It then creates a Gemfile.lock file that holds all of this information. It&#8217;s just a simple YAML file, you can open it up and see the specifics. You&#8217;ll want to add the Gemfile and Gemfile.lock into your version control, so that anyone else that&#8217;s developing with you can also get the same gem versions.</p>
<p>To use the gems in your bundle, just use these two lines:</p>
<pre>require "rubygems"
require "bundler/setup"</pre>
<p>From there, whenever you require a gem, it&#8217;ll be the version from the bundle. If you want Bundler to automatically require all of your gems for you, just &#8216;<code>Bundler.require</code>&#8216; and it&#8217;ll require the default group of gems.</p>
<p>Rails 3 automatically comes with a Gemfile and bundler support right out of the box. If you want to use Bundler with Rails 2.3, check out <a href="http://gembundler.com/rails23.html">the Bundler site</a> for setup instructions.</p>
<p>The combination of gemsets and Bundler will make sure that you don&#8217;t have any nasty gem conflicts. Gemsets keep your projects isolated from each other, and Bundler keeps your gems&#8217; versions from interfering with each other. The two work really well together.</p>
<h3>I can&#8217;t remember which tool I used!</h3>
<p>All of these rubies and gemsets can get confusing. Luckily, rvm has an awesome feature to take care of this, too: .rvmrc files. If you put a file named &#8216;.rvmrc&#8217; in your project&#8217;s root directory, when you enter the project, it&#8217;ll switch your Ruby version (and gemset) automatically. It&#8217;s really easy to use, too. Just put the command you&#8217;d use to switch in the file. For example, in the Hackety Hack website project, I have the following <a href="https://github.com/hacketyhack/hackety-hack.com/blob/master/.rvmrc">.rvmrc</a>:</p>
<pre>rvm 1.8.7@hackety-hack.com</pre>
<p>Astute readers will notice that I left off the &#8216;use,&#8217; rvm defaults to &#8216;use&#8217; if you don&#8217;t give it a different command. Check it out:</p>
<pre>$ ruby -v
ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-darwin10.4.0]
$ cd hackety-hack.com
$ ruby -v
ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10.4.0]</pre>
<p>Super cool. Now you&#8217;ll never forget which Ruby you were using, and you don&#8217;t even need to switch manually. This is one of the first things that I do when I start a new project in Ruby: Pick a Ruby version, make a gemset with the same name as the project, and set up an .rvmrc. It&#8217;s saved me hours of time and headaches.</p>
<h3>Multiple projects: super simple</h3>
<p>rvm is a fantastic tool to help solve your multiple-ruby woes. It really does make using multiple kinds of Ruby really, really easy. And Bundler makes sure that your gems play nice togther. It&#8217;s a great time to be a Rubyist.</p>
<p><em>I hope you found this article valuable. Feel free to ask questions and give feedback in the comments section of this post. Thanks!</em></p>
</div>
<p>Technorati Tags: <a href="http://technorati.com/tag/Bundler" rel="tag">Bundler</a>, <a href="http://technorati.com/tag/rvm" rel="tag">rvm</a>, <a href="http://technorati.com/tag/Programming" rel="tag"> Programming</a>, <a href="http://technorati.com/tag/Ruby+programming" rel="tag">Ruby programming</a></p>
Posted by <b>Steve Klabnik</b><p><a href="http://www.launchbit.com/az/113-209/"><img width="468" height="60" src="http://www.launchbit.com/az-images/113-209/" /></a><br />
<small>(Powered by <a href="http://www.launchbit.com/lb/113-209/">LaunchBit</a>)</small></p>

]]></content:encoded>
			<wfw:commentRss>http://rubylearning.com/blog/2010/12/20/how-do-i-keep-multiple-ruby-projects-separate/feed/</wfw:commentRss>
		<slash:comments>77</slash:comments>
		</item>
	</channel>
</rss>
