<?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>The Brian Olore Story &#187; ruby</title>
	<atom:link href="http://brian.olore.net/wp/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://brian.olore.net</link>
	<description>Less of a story, more of a brain dump</description>
	<lastBuildDate>Sun, 18 Dec 2011 17:19:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Doing battle with metric_fu</title>
		<link>http://brian.olore.net/wp/2010/08/doing-battle-with-metric_fu/</link>
		<comments>http://brian.olore.net/wp/2010/08/doing-battle-with-metric_fu/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 02:17:01 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[work]]></category>
		<category><![CDATA[metric_fu]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://brian.olore.net/?p=198</guid>
		<description><![CDATA[&#8220;Metric_fu is a set of rake tasks that make it easy to generate metrics reports. It uses Saikuro, Flog, Flay, Rcov, Reek, Roodi, Churn, RailsBestPractices, Subversion, Git, and Rails built-in stats task to create a series of reports. It&#8217;s designed to integrate easily with CruiseControl.rb by placing files in the Custom Build Artifacts folder.&#8221; It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;<a href="http://metric-fu.rubyforge.org/">Metric_fu</a> is a set of rake tasks that make it easy to generate metrics reports. It uses Saikuro, Flog, Flay, Rcov, Reek, Roodi, Churn, RailsBestPractices, Subversion, Git, and Rails built-in stats task to create a series of reports. It&#8217;s designed to integrate easily with CruiseControl.rb by placing files in the Custom Build Artifacts folder.&#8221;</p>
<p>It&#8217;s really a pretty sweet tool. It generates all these reports and you can either ignore them or act on them. Not saying which of those we do&#8230; but that&#8217;s not important right now.</p>
<p>If you&#8217;ve used metric_fu you probably ran into the <strong>NaN</strong> error. Good ol&#8217; &#8220;Not A Number&#8221;.<br />
Generally the output looks something like this:</p>
<div class="dean_ch" style="overflow: scroll;white-space: nowrap;">NaN<br />
/usr/lib64/ruby/gems/<span class="nu0">1.8</span>/gems/activesupport<span class="nu0">-2.3</span><span class="nu0">.4</span>/lib/active_support/core_ext/<span class="kw3">float</span>/rounding.<span class="me1">rb</span>:<span class="nu0">19</span>:<span class="kw1">in</span> <span class="st0">`round_without_precision&#8217;<br />
/usr/lib64/ruby/gems/1.8/gems/activesupport-2.3.4/lib/active_support/core_ext/float/rounding.rb:19:in `</span>round<span class="st0">&#8216;<br />
/usr/lib64/ruby/gems/1.8/gems/metric_fu-1.3.0/lib/base/generator.rb:135:in `round_to_tenths&#8217;</span><br />
/usr/lib64/ruby/gems/<span class="nu0">1.8</span>/gems/metric_fu<span class="nu0">-1.3</span><span class="nu0">.0</span>/lib/generators/rcov.<span class="me1">rb</span>:<span class="nu0">85</span>:<span class="kw1">in</span> <span class="st0">`to_h&#8217;<br />
/usr/lib64/ruby/gems/1.8/gems/metric_fu-1.3.0/lib/base/generator.rb:131:in `</span>generate_report<span class="st0">&#8216;<br />
/usr/lib64/ruby/gems/1.8/gems/metric_fu-1.3.0/lib/base/generator.rb:53:in `generate_report&#8217;</span><br />
/usr/lib64/ruby/gems/<span class="nu0">1.8</span>/gems/metric_fu<span class="nu0">-1.3</span><span class="nu0">.0</span>/lib/base/report.<span class="me1">rb</span>:<span class="nu0">54</span>:<span class="kw1">in</span> <span class="st0">`add&#8217;<br />
/usr/lib64/ruby/gems/1.8/gems/metric_fu-1.3.0/lib/../tasks/metric_fu.rake:6<br />
/usr/lib64/ruby/gems/1.8/gems/metric_fu-1.3.0/lib/../tasks/metric_fu.rake:6:in `</span>each<span class="st0">&#8216;<br />
/usr/lib64/ruby/gems/1.8/gems/metric_fu-1.3.0/lib/../tasks/metric_fu.rake:6<br />
</span></div>
<p>This particular error has cropped up several times for us, each time we do the same google searches, look at the same metric_fu sources, and slowly dissect which tests are causing this problem. Hopefully this post will help expedite debugging this error for you and your friends.</p>
<p><span id="more-198"></span></p>
<p>The NaN error is the result of an Infinity/Infinity calculation in metric_fu. How Infinity gets in there in the first place is left as a reader exercise. Ultimately the problem resides in the fact that the <strong>scratch/rcov/rcov.txt</strong> output file does not contain the expected output. In fact, in our case, it contained a failing test.</p>
<p>At this point, running rcov by itself (outside of metric_fu) would result in expected output &#8211; everything worked and there were no failing tests!</p>
<p>So we ran metric_fu again with all tests disabled except for rcov (by editing our rake task).<br />
Metric_fu failed in the exact same place. Great &#8211; at least now it is narrowed down (even if it does take a few minutes to run).</p>
<p>Taking a look at the failing test nothing stood out, until we dug a little deeper.<br />
This test class was overriding a cattr_reader with a cattr_accessor so it could change the value for testing.<br />
No big deal, it worked fine when run by itself &#8230;.</p>
<p>Turns out that this wasn&#8217;t the only test class that was modifying the class variable.<br />
Metric_fu loads up all of the tests (functionals &amp; units) and runs them together.<br />
We had one unit test class that was modifying a class variable (and not setting it back!) and<br />
a functional test class that was making assertion based on the expected default value of that class variable.<br />
<strong>We had indirectly made our tests order dependent.</strong></p>
<p>The reason we never saw it in our normal tests was that our functional and unit tests run separately (via rake).</p>
<p><strong>Summary:</strong></p>
<ol>
<li>Look in scratch/rcov/rcov.txt to find a failing test</li>
<li>Look for usage of class variables or constants &#8211; namely the changing of them (and not setting them back).</li>
</ol>
<p><strong>Our Solution:</strong></p>
<p style="padding-left: 30px;">Our solution was to only temporarily change the class variable, and only do it when we need to:</p>
<div class="dean_ch" style="overflow: scroll;white-space: nowrap;"><span class="kw1">def</span> temporarily_set_observer_limit_to<span class="br0">&#40;</span>count, &amp;amp;block<span class="br0">&#41;</span><br />
&nbsp; old_limit = MyClass.<span class="me1">observer_limit</span><br />
&nbsp; MyClass.<span class="me1">observer_limit</span>=count<br />
&nbsp; <span class="kw1">yield</span><br />
&nbsp; MyClass.<span class="me1">observer_limit</span>=old_limit<br />
<span class="kw1">end</span><br />
&nbsp;</div>
<p>A better solution would be to get rid of the class variables&#8230;<br />
Another solution would be to change metric_fu to handle a failing test more gracefully</p>
<p>In the end, we are left with this rule:</p>
<h3>Don&#8217;t change class variables in tests!</h3>
<p>&#8230; or better yet &#8230;</p>
<h3>Don&#8217;t use class variables!</h3>
<p style="text-align: right;">Friends don&#8217;t let friends use class variables.<br />
Partnership for cattr-free coding.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.olore.net/wp/2010/08/doing-battle-with-metric_fu/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Compleat Rubyist &#8211; Day 1</title>
		<link>http://brian.olore.net/wp/2010/06/compleat-rubyist-day-1/</link>
		<comments>http://brian.olore.net/wp/2010/06/compleat-rubyist-day-1/#comments</comments>
		<pubDate>Sat, 19 Jun 2010 12:25:21 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[work]]></category>
		<category><![CDATA[compleatrubyist]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://brian.olore.net/?p=193</guid>
		<description><![CDATA[Day 1 of 2 of my notes for the Compleat Rubyist training course Ruby Versions and Implementations  &#8211; David http://ruby-versions.net/ &#8211; David&#8217;s home for ruby versions &#38; implementations for learning &#38; historical reference Ruby version manager &#8211; http://rvm.beginrescueend.com &#8211; lets you install several ruby versions/implementations and easily switch between (including your own custom compiled version). [...]]]></description>
			<content:encoded><![CDATA[<p>Day 1 of 2 of my notes for the <a href="http://www.compleatrubyist.com">Compleat Rubyist</a> training course</p>
<h3><span style="text-decoration: underline;">Ruby Versions and Implementations  &#8211; David</span></h3>
<p><a href="http://ruby-versions.net/">http://ruby-versions.net/</a> &#8211; David&#8217;s home for ruby versions &amp; implementations for learning &amp; historical reference</p>
<p>Ruby version manager &#8211; <a href="http://rvm.beginrescueend.com">http://rvm.beginrescueend.com</a> &#8211; lets you install several ruby versions/implementations and easily switch between (including your own custom compiled version). Suggestion &#8211; don&#8217;t install as root, even though it is allowed.</p>
<p>Notes on a few of the existing options:</p>
<ul>
<li>MacRuby &#8211; interacts with Cocoa</li>
<li> Rubinius &#8211; Ruby in Ruby</li>
<li> JRuby &#8211; Ruby on JVM</li>
<li> REE &#8211; optimized &#8211; created by Phusion Passenger team</li>
<li> MagLev &#8211; built in object persistence, repository instead of files, smalltalk-ish</li>
<li> IronRuby &#8211; Ruby on .NET</li>
<li> URABE &#8211; ?</li>
</ul>
<p>rvm allows you to compare performance between versions/implementation:</p>
<pre>rvm ruby-1.8.6,ruby1.9.2 benchmark filename.rb</pre>
<p>Why does everyone use 1.8 instead of 1.9?</p>
<ul>
<li>Same amount of people are using it as last year (like almost no one)</li>
<li>Rails considerations</li>
<li>1.9 is not 100% backwards compatible</li>
<li>1.8.7 backported many of the features of 1.9, so people feel safer</li>
</ul>
<p>Ruby Enterprise Edition has major memory and speed improvements</p>
<p><strong>Highlights of changes between 1.8 &amp; 1.9</strong></p>
<ul>
<li> Enumerators</li>
<li> Method parameters</li>
<li> Block variable binding &amp; scope</li>
<li> Syntax changes</li>
</ul>
<p><strong><span id="more-193"></span>Discussion</strong></p>
<ul>
<li>&#8220;Ruby 1.9 was plenty different enough to be 2.0&#8243; &#8211; David</li>
<li>1.9.1 is currently the stable supported version and has been for about a year.</li>
<li>1.8.6 to 1.8.7 was a big jump &#8211; major backporting of 1.9 features into 1.8</li>
<li>1.8.7 was a safe harbor for those that wanted 1.9 features but were scared of 1.9</li>
<li>rails3 + ruby 1.9.1 = segfaults <img src='http://brian.olore.net/wp/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' />    … works with certain revisions of 1.9.2 HEAD</li>
</ul>
<p><strong>Enumerator object &#8211; 1.9</strong></p>
<ul>
<li>mixes in Enumerable</li>
<li>you write the &#8216;each&#8217; method
<ul>
<li> borrow from another object (can be lazy)</li>
<li> or</li>
<li> pass in code block on instantiation (via a yielder)</li>
</ul>
</li>
<li>once it knows how to &#8216;each&#8217;, it can do select, map, each_cons ….</li>
<li>1.8.6 &#8211; require &#8216;enumerator&#8217; &#8211; Enumerable::Enumerator</li>
<li>1.9.x &#8211; no require needed &#8211; promoted to top level &#8216;Enumerator&#8217;</li>
</ul>
<p>side bar: each_cons vs each_slice</p>
<p>Note to self: I need to memorize each/select/map/collect</p>
<p>What methods do I get with Enumerator that I don&#8217;t get with Enumerable (Array)?</p>
<pre>Enumerator.instance_methods - Array.instance_methods
:with_index, :with_object, :next, :rewind</pre>
<p><strong>Method argument semantics<br />
</strong>required args can now come after optional args<br />
def m(a, b=1, c)<br />
def m(a, *b, c)<br />
def m((a,b),c)<br />
required arguments get filled first</p>
<p><strong>Block variable scope</strong></p>
<ul>
<li>probably the most important/annoying/significant change</li>
<li>breaks stuff in surprising ways</li>
<li>but if it does break stuff, you were likely doing something buggy before</li>
</ul>
<p>Example 1:</p>
<pre>a = [1,2,3]
a.each {|x| p x}</pre>
<p>x gets value of 3 when you are done</p>
<p>|x| literally assigns x ( |x=…| ), so it becomes available outside the block</p>
<p>Example 2:</p>
<pre>a = 1
array.each { a = 2 }</pre>
<p>does not change the value of a</p>
<ul>
<li>Matz said he wished he had done this from the beginning</li>
<li>Unifies the parameter syntax between methods &amp; lambas</li>
</ul>
<p><strong>1.9 Miscellany</strong></p>
<ul>
<li>no more String#each
<ul>
<li>&#8220;Hello&#8221;[0] = &#8220;H&#8221;  #in 1.8 it returns 72</li>
</ul>
</li>
<li>new instance_exec is like instance_eval but takes a param to inject</li>
</ul>
<p>JRuby &#8211; ask David about using ArrayList instead of [] in playpoker.rb</p>
<h3><span style="text-decoration: underline;">The Testing Landscape</span></h3>
<p>Test::Unit is gone in 1.9<br />
Test::Unit::TestCase -&gt; Mini::Test::TestCase<br />
Mini::Test has a new option: refute_match<br />
require &#8216;shoulda&#8217; &#8211; makes it more like RSpec without going full RSpec<br />
RSpec is the defacto standard for Behavior-driven testing</p>
<p>Jeremy &#8211; wrote &#8216;context&#8217; and &#8216;match&#8217;<br />
Given/When/Then &#8211; cucumber is most popular<br />
&#8220;Think in units of features rather than units of code&#8221; &#8211; Gregory<br />
require &#8216;could&#8217; &#8211; another tool &#8211; include feature test right in the same file as tests</p>
<p><strong>Test data </strong></p>
<ul>
<li>YAML/CSV &#8211; hard to maintain, csv is kinda nice because you can open in spreadsheet program (or rather your testers can)</li>
<li>model_stubbing  <a href="http://github.com/technoweenie/model_stubbing">http://github.com/technoweenie/model_stubbing</a></li>
<li>Factories is the new hotness
<ul>
<li> FactoryGirl</li>
<li> Machinist &#8211; <a href="http://github.com/notahat/machinist">http://github.com/notahat/machinist</a>
<ul>
<li> create shams &amp; blueprints</li>
<li> &#8220;way slower&#8221; than fixtures</li>
</ul>
</li>
</ul>
</li>
<li>mocking/stubbing
<ul>
<li> can extend a class to do it</li>
<li> can use OpenStruct to do it require &#8216;ostrich&#8217;</li>
<li> Jeremy likes using &#8216;rr&#8217;</li>
<li> RSpec has it&#8217;s own stubbing</li>
<li> flexmock</li>
</ul>
</li>
<li>Proxies
<ul>
<li>Proxies are like mocks &amp; stubs &amp; real code combined</li>
<li>Proxies are the Ken Jennings of mocks &amp; stubs</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brian.olore.net/wp/2010/06/compleat-rubyist-day-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Make it faster</title>
		<link>http://brian.olore.net/wp/2010/03/make-it-faster/</link>
		<comments>http://brian.olore.net/wp/2010/03/make-it-faster/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 03:02:03 +0000</pubDate>
		<dc:creator>Brian</dc:creator>
				<category><![CDATA[work]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[timeout]]></category>

		<guid isPermaLink="false">http://brian.olore.net/?p=119</guid>
		<description><![CDATA[This past week or so I&#8217;ve been concentrating on improving the performance of our system. Thankfully this isn&#8217;t a solo task and my teammate really knows what he&#8217;s doing. Luckily I was able to contribute based on my past experiences with things like cache settings in Apache, ulimit settings and other tweaks here and there. [...]]]></description>
			<content:encoded><![CDATA[<p>This past week or so I&#8217;ve been concentrating on improving the performance of our system. Thankfully this isn&#8217;t a solo task and my teammate really knows what he&#8217;s doing. Luckily I was able to contribute based on my past experiences with things like cache settings in Apache, ulimit settings and other tweaks here and there.<img class="alignright size-medium wp-image-123" title="Pole Position" src="http://brian.olore.net/wp/wp-content/uploads/2010/03/pole-position-300x225.jpg" alt="Make it fast like Pole Postion fast!" width="300" height="225" /></p>
<p>We&#8217;ve uncovered a slew of things to work on. The first obvious place was to have the static content served by Apache rather than the mongrels. This has been on the todo-list for a long time, but has always fallen to the wayside. We knocked that off and looked towards the other items that were slowing us down. That&#8217;s when I uncovered some TCPSocket weirdness within memcache-client 1.7.4 that comes with activesupport 2.3.5.</p>
<p>During some tests we noticed a severe lag which we narrowed down to the fact that we were pointing to a list of memcached servers that contained one that didn&#8217;t exist. Turns out that when the memcached hostname resolves, but is not pingable, memcache-client 1.7.4 waits <strong>3 seconds</strong> before responding with an error message (in addition it doesn&#8217;t mark the server as &#8220;down&#8221;, which I think is also a bug). This 3 second delay happens on RHEL 4, and in some brief tests on Ubuntu 10.9, it was even worse, taking over 30 seconds to respond. My guess is that there is some OS level setting that affects this, but I have yet to locate it. The fun part however, is that this problem does not exist in our old environment where we run acivesupport 2.1.2 which uses memcache-client 1.5.0.</p>
<p>Turns out, in 1.5.0, <a href="http://github.com/fiveruns/memcache-client/blob/master/lib/memcache.rb#L767" target="_blank">the memcache-client uses a 250ms timeout when calling TCPSocket.new</a>. Something that was lost on the way to 1.7.4. Some initial tests of simply adding this CONNECT_TIMEOUT back in have been promising. It&#8217;s currently not throwing the right exception or marking the server as &#8220;down&#8221;, but once I do that, I will see about posting the source somewhere.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.olore.net/wp/2010/03/make-it-faster/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

