<?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; Gonçalo Silva</title>
	<atom:link href="http://rubylearning.com/blog/author/goncalosilva/feed/" rel="self" type="application/rss+xml" />
	<link>http://rubylearning.com/blog</link>
	<description>Helping Ruby Programmers become Awesome</description>
	<lastBuildDate>Tue, 21 May 2013 02:40:50 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Performance Testing Rails Applications &#8212; How To?</title>
		<link>http://rubylearning.com/blog/2011/08/14/performance-testing-rails-applications-how-to/</link>
		<comments>http://rubylearning.com/blog/2011/08/14/performance-testing-rails-applications-how-to/#comments</comments>
		<pubDate>Sun, 14 Aug 2011 02:07:42 +0000</pubDate>
		<dc:creator>Gonçalo Silva</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Masters]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby programming]]></category>

		<guid isPermaLink="false">http://rubylearning.com/blog/?p=5925</guid>
		<description><![CDATA[Send to Kindle Performance Testing Rails Applications &#8212; How To? This guest post is by Gonçalo Silva, who is a full-time Ruby on Rails developer at escolinhas.pt and has participated in the Ruby Summer of Code 2010. He loves and contributes to many open-source projects, being a fan of Linux, Ruby and Android. He likes [...]<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%252F08%252F14%252Fperformance-testing-rails-applications-how-to%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FpZKKcu%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Performance%20Testing%20Rails%20Applications%20--%20How%20To%3F%22%20%7D);"></div>
<div>
<h2>Performance Testing Rails Applications &#8212; How To?</h2>
<p class="update">This guest post is by <strong>Gonçalo Silva</strong>, who is a full-time Ruby on Rails developer at <a href="http://escolinhas.pt/">escolinhas.pt</a> and has participated in the Ruby Summer of Code 2010. He loves and contributes to many open-source projects, being a fan of Linux, Ruby and Android. He likes to call himself a hacker, but that&#8217;s just an excuse for being in front of the computer all the time. Oh, and he tweets at <a href="http://twitter.com/goncalossilva">@goncalossilva</a>.</p>
<p class="block"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright" src="http://rubylearning.com/images/Goncalo_Silva_125x125.jpg" alt="Gonçalo Silva" /> <span class="drop_cap">R</span>ails 3.1 is just around the corner, and it brings enhanced performance testing tools. Let&#8217;s have a look at this often overlooked feature of our web application framework of choice.</p>
<h3>This isn&#8217;t new</h3>
<p>Rails has had built-in performance testing tools since version 2.2. Originally developed by <a href="https://github.com/rails/rails/commit/eab71208db1afead6803501c8d51d77625e5ad6e">Jeremy Kemper</a>, these allowed developers to test the performance of their applications by writing integration tests which could be benchmarked and profiled under <em>MRI</em>. He later introduced two scripts &#8211; <code>benchmarker</code> and <code>profiler</code> &#8211; which were great to quickly benchmark or profile small snippets of code.</p>
<h3>Actually, this is kind of new</h3>
<p>I came across these tools during last year&#8217;s <em>Ruby Summer of Code</em>. I remember feeling astonished and bit ashamed about not having played with them before. I couldn&#8217;t use them at their full potential because of the lack of full support for <em>YARV</em> (or <em>MRI 1.9</em>), so I set off fixing that. While working on it, I&#8217;ve made a list of other things these tools lacked, that I wanted to implement after <em>RSoC</em>, namely: &#8211; <em>Rubinius</em> support &#8211; <em>JRuby</em> support &#8211; Test configurability &#8211; Decoupling <code>benchmarker</code> and <code>profiler</code> from <em>RubyProf</em></p>
<p>Everything listed above is now implemented. Rails 3.1 will ship with these improvements and we&#8217;ll no longer have excuses for not using these great tools Rails provides for all of us.</p>
<h3>Why you should care</h3>
<p>The web should be fast. Response times are a key factor in user experience and there is very limited patience for slow websites. Ruby interpreters aren&#8217;t famous for being performant and our beloved framework <a href="http://www.youtube.com/watch?v=kWOAHIpmLAI&amp;feature=player_detailpage#t=2058s">isn&#8217;t known for getting faster with new releases</a>. Nevertheless, we want our websites to be fast and responsive, and buying tons of hardware isn&#8217;t always an available choice &#8211; we need our code to be fast. We <strong>should</strong> care.</p>
<h3>How does this work?</h3>
<p>Rails&#8217; performance testing tools allow you to quickly detect performance bottlenecks. As a rule of thumb, use benchmarking to detect the problem and then use profiling to understand it. Profiling provides in-depth information about your code and what it&#8217;s doing, but it lacks the speed and simplicity of benchmarking.</p>
<h4>Patching your Ruby interpreter</h4>
<p>You can skip this section if you&#8217;re a <em>Rubinius</em>/<em>JRuby</em>/<em>REE</em> user.</p>
<p>If you&#8217;re an MRI/YARV user, you&#8217;ll need a patched interpreter to access all available metrics. Before you run off, let me tell you that it&#8217;s <strong>very</strong> simple to install a patched Ruby interpreter nowadays. Thanks to Wayne, the author of <em><a href="https://rvm.beginrescueend.com/">RVM</a></em>, all you need to do is to specify an additional flag when installing your interpreter, like this: <code>rvm install 1.9.2 --patch gcdata</code> Or, if you&#8217;re still using 1.8 (really?): <code>rvm install 1.8.7 --patch ruby187gc</code></p>
<p>That&#8217;s all, folks. You now have a patched Ruby interpreter. If you want, you can have your patched interpreter side by side with your regular one, by simply assigning a name to it:</p>
<pre>rvm install 1.9.2 --patch gcdata --name perf
rvm 1.9.2-perf  # my patched interpreter
rvm 1.9.2       # my regular interpreter</pre>
<p>And that&#8217;s it.</p>
<h4>Editing your Gemfile</h4>
<p>You can skip this section if you&#8217;re using <em>Rubinius</em>/<em>JRuby</em>.</p>
<p>If you&#8217;re not, you&#8217;ll need to add <a href="http://github.com/wycats/ruby-prof/commits/master">RubyProf</a> to your <em>Gemfile</em>:</p>
<pre>gem 'ruby-prof', :git =&gt; 'git://github.com/wycats/ruby-prof.git'</pre>
<p>Don&#8217;t forget to remove this from your <em>Gemfile</em> and re-run <code>bundle install</code> if you intend to switch to <em>Rubinius</em> or <em>JRuby</em>.</p>
<h4>Performance tests</h4>
<p>In order to use these tools, you&#8217;ll need to write performance tests. These tests are just like integration tests, except that the point is not to assert anything. They&#8217;ll just run the code that you want to see benchmarked/profiled.</p>
<h5>Generating</h5>
<p>As expected, Rails does this stuff for you. Just run:</p>
<pre>script/rails generate performance_test example</pre>
<p>And a new file will be placed in <code>test/performance/example_test.rb</code> containing the default test:</p>
<pre>require 'test_helper'
require 'rails/performance_test_help'
class ExampleTest &lt; ActionDispatch::PerformanceTest
  # Refer to the documentation for all available options
  # self.profile_options = { :runs =&gt; 5, :metrics =&gt; [:wall_time, :memory]
  #                          &#58;output =&gt; 'tmp/performance', :formats =&gt; [:flat] }

  def test_homepage
    get '/'
  end
end</pre>
<h5>Editing</h5>
<p>Since <code>ActionDispatch::PerformanceTest</code> inherits from <code>ActionDispatch::IntegrationTest</code>, you can use <a href="http://guides.rubyonrails.org/testing.html#helpers-available-for-integration-tests">all available helpers for integration tests</a> in your performance tests. For instance, if you wanted a test for your login action you could use:</p>
<pre>class LoginTest &lt; ActionDispatch::PerformanceTest
  fixtures :users
  self.profile_options = { :metrics =&gt; [:wall_time, :memory] }

  def test_login
    post_via_redirect "/login", :username =&gt; users(:youruser).username, :password =&gt; users(:youruser).password
  end
end</pre>
<h5>Tweaking</h5>
<p>Starting with Rails 3.1, performance tests can be configured. As you&#8217;ve probably figured out from the aforeshown <code>LoginTest</code>, all you need to do is to specify an optional hash of options to use when benchmarking/profiling. You can use <strong>one set of options for each class</strong>. Not all options are available to all interpreters, especially the ones related with profiling. Metric/output availability for each interpreter will be shown below. You can skip this section and come back later, after grasping the whole concept. You&#8217;ll also be able to check it out on <a href="http://guides.rubyonrails.org/performance_testing.html">Rails&#8217; performance testing guide</a> once 3.1 comes out.</p>
<h6>Metric availability</h6>
</div>
<div style="width: image 669 px;font-size: 80%;text-align: left">Benchmarking<br />
<img style="padding-bottom: 0.5em" src="http://rubylearning.com/images/Screen Shot 2011-08-14 at 2.58.31 AM.png" alt="Benchmarking" width="669" /></div>
<div style="width: image 667 px;font-size: 80%;text-align: left">Profiling<br />
<img style="padding-bottom: 0.5em" src="http://rubylearning.com/images/Screen Shot 2011-08-14 at 2.58.53 AM.png" alt="Profiling" width="667" /></div>
<div style="width: image 281 px;font-size: 80%;text-align: left">Output availability<br />
<img style="padding-bottom: 0.5em" src="http://rubylearning.com/images/Screen Shot 2011-08-14 at 2.59.20 AM.png" alt="Output availability" width="281" /></div>
<div>
<h5>Running</h5>
<p>Finally, it&#8217;s time to run your tests. Let&#8217;s start with benchmarking:</p>
<pre>rake test:benchmark</pre>
<p>And the output should be similar to this:</p>
<pre>ExampleTest:
ExampleTest#test_homepage (16 ms warmup)
           wall_time: 0 ms
              memory: 17 KB
             objects: 195
             gc_runs: 0
             gc_time: 0 ms
 homepage (0.75s)

LoginTest:
LoginTest#test_login (92 ms warmup)
           wall_time: 10 ms
              memory: 180 KB
 login (0.44s)

Finished in 1.193759 seconds.</pre>
<p>If any result disappoints you, profile it:</p>
<pre>rake test:profile TEST=test/performance/login_test.rb</pre>
<p>And you should get a similar output:</p>
<pre>LoginTest:
LoginTest#test_login (105 ms warmup)
           wall_time: 69 ms
              memory: 2.4 KB
 login (5.02s)</pre>
<p>Profiling will give you much more information than what&#8217;s printed on your terminal.</p>
<h5>Reviewing results</h5>
<p>By default, performance tests store their results in <code>tmp/performance</code> (although it can be changed by specifying a value for <code>&#58;output</code> in the <code>profile_options</code> hash). For benchmarks, this is pretty straightforward: it stores one <em>CSV</em> per metric (<code>LoginTest#test_login_memory.csv</code>, for instance) with the results as time goes by.</p>
<pre>measurement,created_at,app,rails,ruby,platform
183222,2011-08-10T18:15:09Z,,3.1.0.rc5,ruby-1.9.2.290,i686-linux
216344,2011-08-11T14:37:59Z,,3.1.0.rc5,ruby-1.9.2.290,i686-linux
(...)</pre>
<p>When profiling, however, the result files are extremely important. They contain the juicy details of your test runs. Similarly to benchmarking results, there will be one file per metric. There are, however, multiple formats available, specially if you&#8217;re using RubyProf (and consequently <em>MRI</em>/<em>REE</em>/<em>YARV</em>). These formats can range from messy flat text files to awesome HTML stack traces, and they will provide valuable input when spotting bottlenecks.</p>
<p>The scope of this article is not to explore RubyProf&#8217;s available output formats, but you should <a href="http://ruby-prof.rubyforge.org/">have a look at the available printers</a>. However, keep in mind that RubyProf supports more metrics and output formats than <em>Rubinius</em>/<em>JRuby</em>&#8216;s profilers. These can only measure wall time when profiling, and will only print their results in Flat/Graph text formats.</p>
</div>
<div style="width: image 686 px;font-size: 80%;text-align: center"><img style="padding-bottom: 0.5em" src="http://rubylearning.com/images/ruby-prof_html_stack_printer.png" alt="RubyProf's HTML stack printer" width="686" /><br />
RubyProf&#8217;s HTML stack printer</div>
<div>
<h4>Quick tests</h4>
<p>Performance tests are great, but they can be inconvenient when all you want is to quickly test a small snippet of code. For this, Rails provides two command line tools: <code>benchmarker</code> and <code>profiler</code>.</p>
<p>Open your terminal and run:</p>
<pre>rails benchmarker 'User.all'</pre>
<p>And it will work as if you had created a performance test and put that code in it. Very simple, right? Another example:</p>
<pre>rails profiler 'User.all' 'User.find_by_login("goncalossilva")' --runs 3 --metrics cpu_time,memory # profiling memory won't work under Rubinius/JRuby (benchmarking memory will!)</pre>
<p>Two things pop up from this code snippet: you can run multiple tests in a single command and you can specify options as you would with normal performance tests.</p>
<p>To get a glimpse at all available options, run:</p>
<pre>rails benchmarker --help rails profiler --help</pre>
<h3>What can be done with this?</h3>
<p>A lot of things can be accomplished with these tools. First and foremost, you can assess the performance of your application by benchmarking certain parts, either through tests or simple snippets of code. After finding potential bottlenecks, you can use profiling to gain a greater insight into what&#8217;s happening and how it can be improved.</p>
<p>There are other useful tasks that can be done with these tools. You could, for instance, compare the performance of different interpreters on your application:</p>
<pre>    rvm 1.9.2
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory
    rvm ree
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory
    rvm rubinius
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory
    rvm jruby
    rails benchmarker 'MyModel.slow_method' 'get "/"' --metrics wall_time,memory</pre>
<p>Now you&#8217;ll know which interpreter takes less/more time/memory when it&#8217;s opening your homepage/running <code>MyModel.slow_method</code>.</p>
<h3>Giving it a try</h3>
<p>If you&#8217;ve come this far, now you know how to use these powerful tools. Try playing with them: I&#8217;m sure you&#8217;ll find valuable information about your applications&#8217; performance, and potentially spot some easily fixable bottlenecks. With little effort, your application will be faster, you will be prouder and your users will be happier!</p>
<p class="alert"><em>Feel free to ask questions and give feedback in the comments section of this post.</em> Gonçalo has also written a guest blog post for RubyLearning before, titled &#8211; &#8220;<a href="http://rubylearning.com/blog/2010/12/14/ruby-gems-%E2%80%94-what-why-and-how/">Ruby gems &#8212; what, why and how</a>&#8220;. Fellow Rubyists, if you would like to write a guest blog post for RubyLearning write to <b>satish [at] rubylearning.org</b></p>
</div>
<p>Technorati Tags: <a href="http://technorati.com/tag/Programming" rel="tag">Programming</a>, <a href="http://technorati.com/tag/Ruby+programming" rel="tag">Ruby programming</a>, <a href="http://technorati.com/tag/Ruby+on+Rails" rel="tag"> Ruby on Rails</a></p>
Posted by <b>Gonçalo Silva</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/08/14/performance-testing-rails-applications-how-to/feed/</wfw:commentRss>
		<slash:comments>52</slash:comments>
		</item>
		<item>
		<title>Ruby gems — what, why and how</title>
		<link>http://rubylearning.com/blog/2010/12/14/ruby-gems-%e2%80%94-what-why-and-how/</link>
		<comments>http://rubylearning.com/blog/2010/12/14/ruby-gems-%e2%80%94-what-why-and-how/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 04:20:03 +0000</pubDate>
		<dc:creator>Gonçalo Silva</dc:creator>
				<category><![CDATA[Beginners]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Masters]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Ruby Gems]]></category>
		<category><![CDATA[ruby programming]]></category>

		<guid isPermaLink="false">http://rubylearning.com/blog/?p=5380</guid>
		<description><![CDATA[Send to Kindle Ruby gems — what, why and how This guest post is by Gonçalo Silva, who is a full-time Ruby on Rails developer at escolinhas.pt and has participated in the Ruby Summer of Code 2010. He loves and contributes to many open-source projects, being a fan of Linux, Ruby and Android. He likes [...]<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%252F14%252Fruby-gems-%2525e2%252580%252594-what-why-and-how%252F%22%2C%20%22shorturl%22%3A%20%22http%3A%2F%2Fbit.ly%2FfwjMLp%22%2C%20%22style%22%3A%20%22big%22%2C%20%22title%22%3A%20%22Ruby%20gems%20%E2%80%94%20what%2C%20why%20and%20how%22%20%7D);"></div>
<div>
<h3>Ruby gems — what, why and how</h3>
<p class="update">This guest post is by <strong>Gonçalo Silva</strong>, who is a full-time Ruby on Rails developer at <a href="http://escolinhas.pt/">escolinhas.pt</a> and has participated in the  Ruby Summer of Code 2010. He loves and contributes to many open-source projects, being a fan of Linux, Ruby and Android. He likes to call himself a hacker, but that&#8217;s just an excuse for being in front of the computer all the time. Oh, and he tweets at <a href="http://twitter.com/goncalossilva">@goncalossilva</a>.</p>
<h3>What is a gem</h3>
<p class="block"><img style=' float: right; padding: 4px; margin: 0 0 2px 7px;'  class="alignright" src="http://rubylearning.com/images/Goncalo_Silva_125x125.jpg" alt="Gonçalo Silva" /> <span class="drop_cap">A</span>t its most basic form, a Ruby gem is a package. It has the necessary files and information for being installed on the system. Quoting <a href="http://docs.rubygems.org/read/chapter/1%20Introducing%20RubyGems">RubyGems</a>: «A gem is a packaged Ruby application or library. It has a name (e.g. rake) and a version (e.g. 0.4.16)».</p>
<p>Being very powerful, gems are of great importance in the Rubyland. They can easily be used to extend or change functionality within Ruby applications.</p>
<h4>Structure</h4>
<p>Every gem is different, but most follow a basic structure:</p>
<pre>gem/
|-- lib/
|   |-- gem.rb
|-- test/
|-- README
|-- Rakefile
|-- gem.gemspec</pre>
<p>Your gem&#8217;s code is located under <em>lib/</em> which typically holds a Ruby file with the name of the gem. You can choose to have all the magic happening in this file, but you can also use it to load some other Ruby files also located under <em>lib/</em>, typically inside a folder with the gem&#8217;s name. Confused? Have a look:</p>
<pre>your_gem/
|-- lib/
|   |-- your_gem.rb
|   |-- your_gem/
|   |   |-- source1.rb
|   |   |-- source2.rb
|-- ...</pre>
<p>The test folder&#8217;s name is not necessarily named <em>test/</em>. When you&#8217;re working with <a href="http://rspec.info/%20RSpec">RSpec</a>, for instance, its name is usually <em>spec/</em>. As you&#8217;ve probably guessed, this folder holds tests for your gem.</p>
<p>After the <em>README</em> file, which hopefully doesn&#8217;t need any introduction, comes the <em>Rakefile</em>. In a gem&#8217;s context, the <em>Rakefile</em> is extremely useful. It can hold various tasks to help building, testing and debugging your gem, among all other things that you might find useful.</p>
<p>The <em>gemspec</em>—as the name implies—contains your gem&#8217;s specification by defining several attributes. An example <em>gemspec</em> file could be:</p>
<pre>Gem::Specification.new do |s|
  s.name              = "gem"
  s.version           = "0.0.1"
  s.platform          = Gem::Platform::RUBY
  s.authors           = ["Gonçalo Silva"]
  s.email             = ["goncalossilva@gmail.com"]
  s.homepage          = "http://github.com/goncalossilva/gem_template"
  s.summary           = "Sample gem"
  s.description       = "A gem template"
  s.rubyforge_project = s.name

  s.required_rubygems_version = "&gt;= 1.3.6"

  # If you have runtime dependencies, add them here
  # s.add_runtime_dependency "other", "~&gt; 1.2"

  # If you have development dependencies, add them here
  # s.add_development_dependency "another", "= 0.9"

  # The list of files to be contained in the gem
  s.files         = `git ls-files`.split("\n")
  # s.executables   = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
  # s.extensions    = `git ls-files ext/extconf.rb`.split("\n")

  s.require_path = 'lib'

  # For C extensions
  # s.extensions = "ext/extconf.rb"
end</pre>
<p>Some attributes like the name, version, platform and summary are required others are optional. If you use git with your project, you can use the nifty trick shown above to list the project&#8217;s files, executables and extensions. If you don&#8217;t, you can simply fall back to using pure Ruby code like:</p>
<pre>s.files = Dir["{lib}/**/*.rb", "{lib}/**/*.rake", "{lib}/**/*.yml", "LICENSE", "*.md"]</pre>
<p>The <a href="http://github.com/goncalossilva/dummy">dummy</a> gem is very simple. Because of this, it perfectly illustrates some of the ideas explained above. Some interesting bits are shown below:</p>
<pre>dummy/
|-- lib/
|   |-- dummy/
|   |   |-- core_ext/
|   |   |   |-- array.rb
|   |   |   |-- string.rb
|   |   |-- address.rb
|   |   |-- company.rb
|   |   |-- ...
|   |-- dummy.rb</pre>
<p>This gem is organized into several source files inside <em>lib/</em>. The <em>dummy.rb</em> implements the <strong>top-level module</strong> and <strong>loads all functionality</strong> from the Ruby files inside <em>lib/dummy/</em>. It also includes some core extensions, namely to the <em>Array</em> and <em>String</em> classes (which are part of Ruby&#8217;s core).</p>
<h4>RubyGems</h4>
<p>Finally, RubyGems. It is a package manager which became part of the standard library in Ruby 1.9. It allows developers to search, install and build gems, among other features. All of this is done by using the <code>gem</code> command-line utility. You can find its website at <a href="http://rubygems.org%20rubygems.org%20%7C%20your%20community%20gem%20host/">rubygems.org</a>.</p>
<h3>Why is this useful</h3>
<p>Gems are very useful for not reinventing the wheel and avoiding duplication. That&#8217;s basically it. Many Ruby developers create and publish awesome gems which address specific requirements, solve specific problems or add specific functionality. Anyone who comes across similar requirements or problems can use them and eventually improve them. That&#8217;s the joint awesomeness of Ruby&#8217;s strong open-source foundation and extreme flexibility. Anyway, you&#8217;re reading this article&#8230; so you&#8217;ve probably understood the concept and grasped its usefulness long before reading this paragraph.</p>
<h3>How to make your own</h3>
<p>Making your own gem is nothing more than packaging your library or application according to the structure stated above. Put all your code under <em>lib/</em>, all your tests under <em>test/</em> or <em>spec/</em>, your gem specification under <em>your_gem.gemspec</em> and you&#8217;re good to go. Of course, a few other files might come in handy, namely a <em>Rakefile</em>, a <em>README</em> and a <em>LICENSE</em>. A <em>CHANGELOG</em>, sometimes, might be useful as well.</p>
<h4>Ruby Idioms</h4>
<p>When developing a gem, you are probably creating, extending or overriding functionality. You might want people to include your module in their classes, or perhaps you just want to extend a given class with your module—it&#8217;s your choice. What you shouldn&#8217;t really do, however, is reinventing Ruby&#8217;s module system. There is an <a href="http://yehudakatz.com/2009/11/12/better-ruby-idioms/">excellent blog post</a> on this which can help if you—like many gem authors I&#8217;ve seen—start overriding <code>include</code> to behave like <code>extend</code>. It&#8217;s very important to understand the difference between the two and, fortunately, there are <a href="http://railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/">great resources</a> about this out there.</p>
<h4>Developing with Bundler</h4>
<p>Using <a href="http://gembundler.com/%20Bundler">Bundler</a> to manage your gem&#8217;s dependencies is also pretty easy. Just create a <em>Gemfile</em> and add:</p>
<pre>gemspec</pre>
<p>After this, fire Bundler:</p>
<pre>bundle install</pre>
<p>And yes, you got it right. After adding <code>gemspec</code> to your <em>Gemfile</em>, Bundler can scan your <em>gemspec</em>, find your runtime and development dependencies and install them for you.</p>
<p>While not being mandatory, I <strong>strongly</strong> recommend you to consider using Bundler to manage your gem&#8217;s dependencies. If used correctly, it can probably be a time saver.</p>
<h4>Testing</h4>
<p>When it comes to testing, you&#8217;ve got plenty of good options. Some people rely on test-unit (or minitest in 1.9), others prefer RSpec. It&#8217;s really up to you. The only bad choice you can possibly make is opting to <strong>not</strong> testing your gems at all.</p>
<p>Once again, I&#8217;m going to use dummy&#8217;s simplicity to explain this a bit further. All tests were built on test-unit and are organized as follows:</p>
<pre>dummy/
|-- test/
|   |-- address_test.rb
|   |-- company_test.rb
|   |-- ...
|   |-- test_helper.rb</pre>
<p>As you&#8217;ve seen, tests are structured similarly to dummy itself. The test_helper is in charge of loading the necessary libraries and setting up any variables or methods used across most (if not all) tests. All tests are organized into files which target specific functionality in dummy. The tests contained in <em>address_test.rb</em> run against <em>address.rb</em> and so on.</p>
<h4>Publishing</h4>
<p>After everything is coded and tested, all you got left to do is packaging and publishing. The previously mentioned <em>gem</em> utility makes it all very simple. Just run <code>gem build your_gem.gemspec</code> and you should see something along these lines:</p>
<pre>Successfully built RubyGem
Name: your_gem
Version: 0.0.1
File: your_gem-0.0.1.gem</pre>
<p>Pushing your gem to RubyGems is as easy as it is to build it. Just <code>gem push your_gem-0.0.1.gem</code> and soon it&#8217;ll be published. Be aware that the first time you issue this command you&#8217;ll be prompted to login with a RubyGems.org account.</p>
<p>Concerning this, I like keeping these simple tasks in my <em>Rakefile</em>:</p>
<pre>desc "Validate the gemspec"
task :gemspec do
  gemspec.validate
end

desc "Build gem locally"
task :build =&gt; :gemspec do
  system "gem build #{gemspec.name}.gemspec"
  FileUtils.mkdir_p "pkg"
  FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg"
end

desc "Install gem locally"
task :install =&gt; :build do
  system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
end</pre>
<p>These help me build and install my gems. They also aid at keeping all packages in the <em>pkg/</em> folder, which is useful for keeping the root directory clean and tidy.</p>
<h4>Gems for building gems</h4>
<p>There are a few gems which were specifically created to help developers build their own gems. Among them are the renowned <a href="https://github.com/technicalpickles/jeweler%20jeweler">jeweler</a>, <a href="https://github.com/seattlerb/hoe%20hoe">hoe</a> and <a href="https://github.com/fauna/echoe%20echoe">echoe</a>. I can&#8217;t go into detail in any of these since I&#8217;ve never really used them &#8211; I started building my gem skeleton from scratch right at the beginning. However, some of these tools are very helpful so you should <strong>really</strong> take a look and see if any fits your needs.</p>
<h4>Gem template</h4>
<p>As I mentioned, I&#8217;ve been using a gem skeleton for some time now, which <a href="https://github.com/goncalossilva/gem_template%20gem_template">you can find at GitHub</a>. Every gem I&#8217;ve built started with that template, which I kept trying to improve over time.</p>
<p>You can start your gems from scratch, but that&#8217;s just nonsense. You should create your own skeleton, use one made by someone else or use a third-party gem to help creating your gem.</p>
<h4>Legen—<em>wait for it</em>—dary</h4>
<p>Ruby gems are filled with awesomeness. Hop in and start making your own!</p>
<p><em>Feel free to ask questions and give feedback in the comments section of this post. Thanks and Good Luck!</em></p>
</div>
<p>Technorati Tags: <a href="http://technorati.com/tag/Programming" rel="tag">Programming</a>, <a href="http://technorati.com/tag/Ruby+programming" rel="tag">Ruby programming</a>, <a href="http://technorati.com/tag/Ruby+Gems" rel="tag"> Ruby Gems</a></p>
Posted by <b>Gonçalo Silva</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/14/ruby-gems-%e2%80%94-what-why-and-how/feed/</wfw:commentRss>
		<slash:comments>111</slash:comments>
		</item>
	</channel>
</rss>
