<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:rhnh.net,2008:/posts</id>
  <link rel="alternate" type="text/html" href="http://rhnh.net/"/>
  <link rel="self" type="application/atom+xml" href="http://rhnh.net/posts.atom"/>
  <title>Xavier Shay's Blog</title>
  <updated>2014-10-12T22:30:37Z</updated>
  <generator uri="http://enkiblog.com">Enki</generator>
  <author>
    <name>Xavier Shay</name>
    <email>notreal@rhnh.net</email>
  </author>
  <entry>
    <id>tag:rhnh.net,2008:Post/882</id>
    <published>2014-10-12T22:30:00Z</published>
    <updated>2014-10-12T22:30:37Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2014/10/12/new-non-tech-blog"/>
    <title>New non-tech blog</title>
    <content type="html">&lt;p&gt;Have been writing a bit recently, just not here. More politics and book reviews. I&amp;#8217;ve separated it out over on &lt;a href="https://xaviershay.github.io/blog/"&gt;Github pages&lt;/a&gt;.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/881</id>
    <published>2014-08-17T22:30:19Z</published>
    <updated>2014-08-17T22:30:19Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2014/08/17/dropwizard-logger-for-ruby-and-webrick"/>
    <title>Dropwizard logger for Ruby and WEBrick</title>
    <content type="html">&lt;p&gt;Wouldn&amp;#8217;t it be great if instead of webrick logs looking like:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; ruby server.rb&lt;tt&gt;
&lt;/tt&gt;[2014-08-17 15:29:10] INFO  WEBrick 1.3.1&lt;tt&gt;
&lt;/tt&gt;[2014-08-17 15:29:10] INFO  ruby 2.1.1 (2014-02-24) [x86_64-darwin13.0]&lt;tt&gt;
&lt;/tt&gt;[2014-08-17 15:29:10] INFO  WEBrick::HTTPServer#start: pid=17304 port=8000&lt;tt&gt;
&lt;/tt&gt;D, [2014-08-17T15:29:11.452223 #17304] DEBUG -- : hello from in the request&lt;tt&gt;
&lt;/tt&gt;localhost - - [17/Aug/2014:15:29:11 PDT] &amp;quot;GET / HTTP/1.1&amp;quot; 200 13&lt;tt&gt;
&lt;/tt&gt;- -&amp;gt; /&lt;tt&gt;
&lt;/tt&gt;E, [2014-08-17T15:29:12.787505 #17304] ERROR -- : fail (RuntimeError)&lt;tt&gt;
&lt;/tt&gt;server.rb:57:in `block in &amp;lt;main&amp;gt;'&lt;tt&gt;
&lt;/tt&gt;/Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpservlet/prochandler.rb:38:in `call'&lt;tt&gt;
&lt;/tt&gt;/Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpservlet/prochandler.rb:38:in `do_GET'&lt;tt&gt;
&lt;/tt&gt;/Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpservlet/abstract.rb:106:in `service'&lt;tt&gt;
&lt;/tt&gt;/Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'&lt;tt&gt;
&lt;/tt&gt;/Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'&lt;tt&gt;
&lt;/tt&gt;/Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'&lt;tt&gt;
&lt;/tt&gt;localhost - - [17/Aug/2014:15:29:12 PDT] &amp;quot;GET /fail HTTP/1.1&amp;quot; 500 6&lt;tt&gt;
&lt;/tt&gt;- -&amp;gt; /fail&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;They looked like:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; ruby server.rb&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;   ,~~.,''&amp;quot;'`'.~~.&lt;tt&gt;
&lt;/tt&gt;  : {` .- _ -. '} ;&lt;tt&gt;
&lt;/tt&gt;   `:   O(_)O   ;'&lt;tt&gt;
&lt;/tt&gt;    ';  ._|_,  ;`   i am starting the server&lt;tt&gt;
&lt;/tt&gt;     '`-.\_/,.'`&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;INFO  [2014-08-17 22:28:13,186] webrick: WEBrick 1.3.1&lt;tt&gt;
&lt;/tt&gt;INFO  [2014-08-17 22:28:13,186] webrick: ruby 2.1.1 (2014-02-24) [x86_64-darwin13.0]&lt;tt&gt;
&lt;/tt&gt;INFO  [2014-08-17 22:28:13,187] webrick: WEBrick::HTTPServer#start: pid=17253 port=8000&lt;tt&gt;
&lt;/tt&gt;DEBUG [2014-08-17 22:28:14,738] app: hello from in the request&lt;tt&gt;
&lt;/tt&gt;INFO  [2014-08-17 15:28:14,736] webrick: GET / 200&lt;tt&gt;
&lt;/tt&gt;ERROR [2014-08-17 22:28:15,603] app: RuntimeError: fail&lt;tt&gt;
&lt;/tt&gt;! server.rb:57:in `block in &amp;lt;main&amp;gt;'&lt;tt&gt;
&lt;/tt&gt;! /Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpservlet/prochandler.rb:38:in `call'&lt;tt&gt;
&lt;/tt&gt;! /Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpservlet/prochandler.rb:38:in `do_GET'&lt;tt&gt;
&lt;/tt&gt;! /Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpservlet/abstract.rb:106:in `service'&lt;tt&gt;
&lt;/tt&gt;! /Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpserver.rb:138:in `service'&lt;tt&gt;
&lt;/tt&gt;! /Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/httpserver.rb:94:in `run'&lt;tt&gt;
&lt;/tt&gt;! /Users/xavier/.rubies/cruby-2.1.1/lib/ruby/2.1.0/webrick/server.rb:295:in `block in start_thread'&lt;tt&gt;
&lt;/tt&gt;INFO  [2014-08-17 15:28:15,602] webrick: GET /fail 500&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;I thought so, hence:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;55&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;65&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;webrick&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-BANNER&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;   ,~~.,''&amp;quot;'`'.~~.&lt;tt&gt;
&lt;/tt&gt;  : {` .- _ -. '} ;&lt;tt&gt;
&lt;/tt&gt;   `:   O(_)O   ;'&lt;tt&gt;
&lt;/tt&gt;    ';  ._|_,  ;`   i am starting the server&lt;tt&gt;
&lt;/tt&gt;     '`-.&lt;/span&gt;&lt;span class="ch"&gt;\\&lt;/span&gt;&lt;span class="k"&gt;_/,.'`&lt;tt&gt;
&lt;/tt&gt;&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;BANNER&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;DropwizardLogger&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Logger&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(label, *args)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;super&lt;/span&gt;(*args)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@label&lt;/span&gt; = label&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;format_message&lt;/span&gt;(severity, timestamp, progname, msg)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%-5s [%s] %s: %s&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % [&lt;tt&gt;
&lt;/tt&gt;      severity,&lt;tt&gt;
&lt;/tt&gt;      timestamp.utc.strftime(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%Y-%m-%d %H:%M:%S,%3N&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;),&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="iv"&gt;@label&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;      msg2str(msg),&lt;tt&gt;
&lt;/tt&gt;    ]&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;msg2str&lt;/span&gt;(msg)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;case&lt;/span&gt; msg&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="co"&gt;String&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      msg&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="co"&gt;Exception&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      (&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%s: %s&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % [msg.class, msg.message]) +&lt;tt&gt;
&lt;/tt&gt;        (msg.backtrace ? msg.backtrace.map {|x| &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="k"&gt;! &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;x&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; }.join : &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      msg.inspect&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.&lt;span class="fu"&gt;webrick_format&lt;/span&gt;(label)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;INFO  [%{%Y-%m-%d %H:%M:%S,%3N}t] &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;label&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;: %m %U %s&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;server = &lt;span class="co"&gt;WEBrick&lt;/span&gt;::&lt;span class="co"&gt;HTTPServer&lt;/span&gt;.new \&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:Port&lt;/span&gt;      =&amp;gt; &lt;span class="i"&gt;8000&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:Logger&lt;/span&gt;    =&amp;gt; &lt;span class="co"&gt;DropwizardLogger&lt;/span&gt;.new(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;webrick&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="gv"&gt;$stdout&lt;/span&gt;).tap {|x|&lt;tt&gt;
&lt;/tt&gt;                  x.level = &lt;span class="co"&gt;Logger&lt;/span&gt;::&lt;span class="co"&gt;INFO&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;                },&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:AccessLog&lt;/span&gt; =&amp;gt; [[&lt;span class="gv"&gt;$stdout&lt;/span&gt;, &lt;span class="co"&gt;DropwizardLogger&lt;/span&gt;.webrick_format(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;webrick&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)]]&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="gv"&gt;$logger&lt;/span&gt; = &lt;span class="co"&gt;DropwizardLogger&lt;/span&gt;.new(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;app&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="gv"&gt;$stdout&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;server.mount_proc &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |req, res|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;begin&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    raise &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;rescue&lt;/span&gt; =&amp;gt; e&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="gv"&gt;$logger&lt;/span&gt;.error(e)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  res.body = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;failed&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  res.status = &lt;span class="i"&gt;500&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;server.mount_proc &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |req, res|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="gv"&gt;$logger&lt;/span&gt;.debug(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello from in the request&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  res.body = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Hello, world!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;trap &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;INT&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  server.shutdown&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;server.start&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/880</id>
    <published>2014-08-16T23:32:00Z</published>
    <updated>2014-08-16T23:32:21Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2014/08/16/querying-consul-with-range"/>
    <title>Querying consul with range</title>
    <content type="html">&lt;p&gt;&lt;em&gt;Disclaimer: this has not been tried in a production environment. It is a weekend hack.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.consul.io/"&gt;Consul&lt;/a&gt; is a highly available, datacenter aware, service discovery mechanism. &lt;a href="http://godoc.org/github.com/xaviershay/grange"&gt;Range&lt;/a&gt; is a query language for selecting information out of arbitrary, self-referential metadata. I combined the two!&lt;/p&gt;
&lt;p&gt;Start by firing up a two node consul cluster, per the &lt;a href="http://www.consul.io/intro/getting-started/join.html"&gt;getting started guide&lt;/a&gt;. On the master node, grab the &lt;a href="https://github.com/xaviershay/grange-server/pull/4"&gt;&lt;code&gt;consul&lt;/code&gt; branch of grange-server&lt;/a&gt; and run it with the following config:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;[rangeserver]&lt;tt&gt;
&lt;/tt&gt;loglevel=DEBUG&lt;tt&gt;
&lt;/tt&gt;consul=true&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;(It could run against any consul agent, but it&amp;#8217;s easier to demo on the master node.)&lt;/p&gt;
&lt;p&gt;Querying range, we already see a consul cluster, &lt;code&gt;cluster&lt;/code&gt;. This is a default service containing the consul servers.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; export RANGE_HOST=172.20.20.10&lt;tt&gt;
&lt;/tt&gt;&amp;gt; erg &amp;quot;allclusters()&amp;quot;&lt;tt&gt;
&lt;/tt&gt;consul&lt;tt&gt;
&lt;/tt&gt;&amp;gt; erg &amp;quot;%consul&amp;quot;&lt;tt&gt;
&lt;/tt&gt;agent-one&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Add a new service to the agents, and it shows up in range!&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;n2&amp;gt; curl -v -X PUT --data '{&amp;quot;name&amp;quot;: &amp;quot;web&amp;quot;, &amp;quot;port&amp;quot;: 80}' http://localhost:8500/v1/agent/service/register&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt; erg &amp;quot;allclusters()&amp;quot;&lt;tt&gt;
&lt;/tt&gt;consul,web&lt;tt&gt;
&lt;/tt&gt;&amp;gt; erg &amp;quot;%web&amp;quot;&lt;tt&gt;
&lt;/tt&gt;agent-two&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;n1&amp;gt; curl -v -X PUT --data '{&amp;quot;name&amp;quot;: &amp;quot;web&amp;quot;, &amp;quot;port&amp;quot;: 80}' http://localhost:8500/v1/agent/service/register&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt; erg &amp;quot;%web&amp;quot;&lt;tt&gt;
&lt;/tt&gt;agent-one,agent-two&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Though eventually consistent, range is a big improvement over the consul &lt;span class="caps"&gt;HTTP&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; for quick ad-hoc queries against your production layout, particularly when combined with other metadata. How many nodes are running redis? What services are running on a particular rack?&lt;/p&gt;
&lt;p&gt;This is just a proof of concept for now, but I&amp;#8217;m excited about the potential. To be useable it needs to be tested against production sized clusters, better handling of error conditions, and some code review (in particular around handling cluster state changes).&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/879</id>
    <published>2014-04-26T18:20:00Z</published>
    <updated>2014-04-26T18:20:46Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2014/04/26/bash-script-to-keep-a-git-clone-synced-with-a-remote"/>
    <title>Bash script to keep a git clone synced with a remote</title>
    <content type="html">&lt;p&gt;Use the following under a process manager (such as runit) to keep a local git clone in sync with a remote, when a push based solution isn&amp;#8217;t an option. Most other versions either neglect to verify remote is correct, or use &lt;code&gt;git pull&lt;/code&gt; which can fail if someone has been monkeying with the local version.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;function update_git_repo() {&lt;tt&gt;
&lt;/tt&gt;  GIT_DIR=$1&lt;tt&gt;
&lt;/tt&gt;  GIT_REMOTE=$2&lt;tt&gt;
&lt;/tt&gt;  GIT_BRANCH=${3:-master}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  if [ ! -d $GIT_DIR ]; then&lt;tt&gt;
&lt;/tt&gt;    CURRENT_SHA=&amp;quot;&amp;quot;&lt;tt&gt;
&lt;/tt&gt;    git clone --depth 1 $GIT_REMOTE $GIT_DIR -b $GIT_BRANCH&lt;tt&gt;
&lt;/tt&gt;  else&lt;tt&gt;
&lt;/tt&gt;    CURRENT_REMOTE=$(cd $GIT_DIR &amp;amp;&amp;amp; git config --get remote.origin.url || true)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    if [ &amp;quot;$GIT_REMOTE&amp;quot; == &amp;quot;$CURRENT_REMOTE&amp;quot; ]; then&lt;tt&gt;
&lt;/tt&gt;      CURRENT_SHA=$(cat $GIT_DIR/.git/refs/heads/$GIT_BRANCH)&lt;tt&gt;
&lt;/tt&gt;    else&lt;tt&gt;
&lt;/tt&gt;      rm -Rf $GIT_DIR&lt;tt&gt;
&lt;/tt&gt;      exit 0 # Process manager should restart this script&lt;tt&gt;
&lt;/tt&gt;    fi&lt;tt&gt;
&lt;/tt&gt;  fi&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  cd $GIT_DIR &amp;amp;&amp;amp; \&lt;tt&gt;
&lt;/tt&gt;    git fetch &amp;amp;&amp;amp; \&lt;tt&gt;
&lt;/tt&gt;    git reset --hard origin/$GIT_BRANCH&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  NEW_SHA=$(cat $GIT_DIR/.git/refs/heads/$GIT_BRANCH)&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;update_git_repo &amp;quot;/tmp/myrepo&amp;quot; &amp;quot;git://example.com/my/repo.git&amp;quot;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;sleep 60 # No need for a tight loop&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/878</id>
    <published>2014-03-29T22:17:00Z</published>
    <updated>2014-03-29T22:17:16Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2014/03/29/ruby-progress-bar-no-gems"/>
    <title>Ruby progress bar, no gems</title>
    <content type="html">&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;import&lt;/span&gt;(filename, out = &lt;span class="gv"&gt;$stdout&lt;/span&gt;, &amp;amp;block)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# Yes, there are gems that do progress bars.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# No, I'm not about to add another dependency for something this simple.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  width     = &lt;span class="i"&gt;50&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  processed = &lt;span class="i"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  printed   = &lt;span class="i"&gt;0&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  total     = &lt;span class="co"&gt;File&lt;/span&gt;.read(filename).lines.length.to_f&lt;tt&gt;
&lt;/tt&gt;  label     = &lt;span class="co"&gt;File&lt;/span&gt;.basename(filename, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;.csv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  out.print &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%11s: |&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % label&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;CSV&lt;/span&gt;.foreach(filename, &lt;span class="ke"&gt;headers&lt;/span&gt;: &lt;span class="pc"&gt;true&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt; |row|&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;yield&lt;/span&gt; row&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    processed += &lt;span class="i"&gt;1&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    wanted = (processed / total * width).to_i&lt;tt&gt;
&lt;/tt&gt;    out.print &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;-&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; * (wanted - printed)&lt;tt&gt;
&lt;/tt&gt;    printed = wanted&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  out.puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;|&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;     file_1: |--------------------------------------------------|&lt;tt&gt;
&lt;/tt&gt;     file_2: |--------------------------------------------------|&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/877</id>
    <published>2013-12-10T04:37:26Z</published>
    <updated>2013-12-10T04:37:26Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2013/12/10/new-in-rspec-3-verifying-doubles"/>
    <title>New in RSpec 3: Verifying Doubles</title>
    <content type="html">&lt;p&gt;One of the features I am most excited about in RSpec 3 is the verifying double support&lt;sup class="footnote" id="fnr1"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;. Using traditional doubles has always made me uncomfortable, since it is really easy to accidentally mock or stub a method that does not exist. This leads to the awkward situation where a refactoring can leave your code broken but with green specs. For example, consider the following:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;# double_demo.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;User&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Struct&lt;/span&gt;.new(&lt;span class="sy"&gt;:notifier&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;suspend!&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    notifier.notify(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;suspended as&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;describe &lt;span class="co"&gt;User&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;#suspend!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;notifies the console&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    notifier = double(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;ConsoleNotifier&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    expect(notifier).to receive(&lt;span class="sy"&gt;:notify&lt;/span&gt;).with(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;suspended as&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    user = &lt;span class="co"&gt;User&lt;/span&gt;.new(notifier)&lt;tt&gt;
&lt;/tt&gt;    user.suspend!&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;code&gt;ConsoleNotifier&lt;/code&gt; is defined as:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;# console_notifier.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ConsoleNotifier&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;notify!&lt;/span&gt;(msg)&lt;tt&gt;
&lt;/tt&gt;    puts msg&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Note that the method &lt;code&gt;notify!&lt;/code&gt; does not match the &lt;code&gt;notify&lt;/code&gt; method we are expecting! This is broken code, but the spec still passes:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; rspec -r./console_notifier double_demo.rb&lt;tt&gt;
&lt;/tt&gt;.&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Finished in 0.0006 seconds&lt;tt&gt;
&lt;/tt&gt;1 example, 0 failures&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Verifying doubles solve this issue.&lt;/p&gt;
&lt;h3&gt;Verifying doubles to the rescue&lt;/h3&gt;
&lt;p&gt;A verifying double provides guarantees about methods that are being expected, including whether they exist, whether the number of arguments is valid for that method, and whether they have the correct visibility. If we change &lt;code&gt;double('ConsoleNotifier')&lt;/code&gt; to &lt;code&gt;instance_double('ConsoleNotifier')&lt;/code&gt; in the previous spec, it will now ensure that any method we expect is a valid instance method of &lt;code&gt;ConsoleNotifier&lt;/code&gt;. So the spec will now fail:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; rspec -r./console_notifier.rb double_demo.rb&lt;tt&gt;
&lt;/tt&gt;F&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Failures:&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  1) User#suspend! notifies the console&lt;tt&gt;
&lt;/tt&gt;     Failure/Error: expect(notifier).to receive(:notify).with(&amp;quot;suspended as&amp;quot;)&lt;tt&gt;
&lt;/tt&gt;       ConsoleNotifier does not implement:&lt;tt&gt;
&lt;/tt&gt;         notify&lt;tt&gt;
&lt;/tt&gt;    # ... backtrace&lt;tt&gt;
&lt;/tt&gt;         &lt;tt&gt;
&lt;/tt&gt;Finished in 0.00046 seconds&lt;tt&gt;
&lt;/tt&gt;1 example, 1 failure         &lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Other types of verifying doubles include &lt;code&gt;class_double&lt;/code&gt; and &lt;code&gt;object_double&lt;/code&gt;. You can read more about them in &lt;a href="https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/verifying-doubles"&gt;the documentation&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Isolation&lt;/h3&gt;
&lt;p&gt;Even though we have a failing spec, we now have to load our dependencies for the privilege. This is undesirable when those dependencies take a long time to load, such as the Rails framework. Verifying doubles provide a solution to this problem: if the dependent class does not exist, it simply operates as a normal double! This is often confusing to people, but understanding it is key to understanding the power of verifying doubles.&lt;/p&gt;
&lt;p&gt;Running the spec that failed above &lt;em&gt;without&lt;/em&gt; loading &lt;code&gt;console_notifier.rb&lt;/code&gt;, it actually passes:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; rspec double_demo.rb&lt;tt&gt;
&lt;/tt&gt;.&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;Finished in 0.0006 seconds&lt;tt&gt;
&lt;/tt&gt;1 example, 0 failures&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This is the killer feature of verifying doubles. You get both confidence that your specs are correct, &lt;em&gt;and&lt;/em&gt; the speed of running them isolation. Typically I will develop a spec and class in isolation, then load up the entire environment for a full test run and in CI.&lt;/p&gt;
&lt;p&gt;There are a number of other neat tricks you can do with verifying doubles, such as enabling them for partial doubles and replacing constants, all covered in &lt;a href="https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/verifying-doubles"&gt;the documentation&lt;/a&gt;.&lt;br /&gt;
There really isn&amp;#8217;t a good reason to use normal doubles anymore. &lt;a href="http://myronmars.to/n/dev-blog/2013/11/rspec-2-99-and-3-0-betas-have-been-released"&gt;Install the RSpec 3 beta&lt;/a&gt; (via 2.99) to take them for a test drive!&lt;/p&gt;
&lt;p class="footnote" id="fn1"&gt;&lt;a href="#fnr1"&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; This functionality has been available for a while now in &lt;a href="http://github.com/xaviershay/rspec-fire"&gt;rspec-fire&lt;/a&gt;. RSpec 3 fully replaces that library, and even adds some more features.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/876</id>
    <published>2013-07-04T18:08:02Z</published>
    <updated>2013-07-04T18:08:02Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2013/07/04/ruby-style-guide"/>
    <title>Ruby Style Guide</title>
    <content type="html">&lt;p&gt;My coding style has evolved over time, and has always been something I kept in my head. This morning I tried to document it explicitly, so I can point offending pull requests at it. My personal &lt;a href="http://xaviershay.com/ruby-style-guide"&gt;Ruby Style Guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What is it missing?&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/875</id>
    <published>2013-06-29T18:02:00Z</published>
    <updated>2013-06-29T18:02:36Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2013/06/29/writing-about-code"/>
    <title>Writing About Code</title>
    <content type="html">&lt;p&gt;I wrote some words about &lt;a href="http://xaviershay.github.io/writing/docs/1_sos.html"&gt;The Mathematical Syntax of Small-step Operational Semantics&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s the latest in a sequence of experiments on techniques for presenting ideas and code, &lt;a href="https://github.com/xaviershay/xspec"&gt;xspec&lt;/a&gt; being another that you may be interested in.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/874</id>
    <published>2012-12-20T02:44:00Z</published>
    <updated>2012-12-20T02:44:21Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/12/20/how-i-test-rails-applications"/>
    <title>How I Test Rails Applications</title>
    <content type="html">&lt;p&gt;The &lt;a href="http://guides.rubyonrails.org/testing.html"&gt;Rails conventions&lt;/a&gt; for testing provide three categories for your tests:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;Unit.&lt;/b&gt; What you write to test your models.&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Integration.&lt;/b&gt; Used to test the interaction among any number of controllers.&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Functional.&lt;/b&gt; Testing the various actions of a single controller.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tells you &lt;strong&gt;where&lt;/strong&gt; to put your tests, but the type of testing you perform on each part of the system is the same: load fixtures into the database to get the app into the required state, run some part of the system either directly (models) or using provided harnesses (controllers), then verify the expected output.&lt;/p&gt;
&lt;p&gt;This techinque is simple, but is only one of a number of ways of testing. As your application grows, you will need to add other approaches to your toolbelt to enable your test suite to continue providing valuable feedback not just on the correctness of your code, but its design as well.&lt;/p&gt;
&lt;p&gt;I use a different set of categories for my tests (taken from the &lt;a href="http://www.growing-object-oriented-software.com/"&gt;&lt;span class="caps"&gt;GOOS&lt;/span&gt; book&lt;/a&gt;):&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;b&gt;Unit.&lt;/b&gt; Do our objects do the right thing, and are they convenient to work with?&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Integration.&lt;/b&gt; Does our code work against code we can&#8217;t change?&lt;/li&gt;
	&lt;li&gt;&lt;b&gt;Acceptance.&lt;/b&gt; Does the whole system work?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Note that these definitions of unit and integration are &lt;em&gt;radically different&lt;/em&gt; to how Rails defines them. That is unfortunate, but these definitions are more commonly accepted across other languages and frameworks and I prefer to use them since it facilitates an exchange of information across them. All of the typical Rails tests fall under the &amp;#8220;integration&amp;#8221; label, leaving two new levels of testing to talk about: unit and acceptance.&lt;/p&gt;
&lt;h2&gt;Unit Tests&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&#8220;A test is not a unit test if it talks to the database, communicates across a network, or touches the file system.&#8221; &amp;#8211; Working with Legacy Code, p. 14&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This type of test is typically referred to in the Rails community as a &amp;#8220;fast unit test&amp;#8221;, which is unfortunate since speed is far from the primary benefit. &lt;b&gt;The primary benefit of unit testing is the feedback it provides on the dependencies in your design.&lt;/b&gt; &amp;#8220;Design unit tests&amp;#8221; would be a better label.&lt;/p&gt;
&lt;p&gt;This feedback is absolutely critical in any non-trivial application. Unchecked dependency is crippling, and Rails encourages you not to think about it (most obviously by implicitly autoloading everything).&lt;/p&gt;
&lt;p&gt;By unit testing a class you are forced to think about how it interacts with other classes, which leads to simpler dependency trees and simpler programs.&lt;/p&gt;
&lt;p&gt;Unit tests tend to (though don&amp;#8217;t always have to) make use of mocking to verify interactions between classes. Using &lt;a href="https://github.com/xaviershay/rspec-fire"&gt;rspec-fire&lt;/a&gt; is absolutely critical when doing this. It verifies your mocks represent actual objects with no extra effort required in your tests, bridging the gap to statically-typed mocks in languages like Java.&lt;/p&gt;
&lt;p&gt;As a guideline, a single unit test shouldn&amp;#8217;t take more than 1ms to run.&lt;/p&gt;
&lt;h2&gt;Acceptance Tests&lt;/h2&gt;
&lt;p&gt;A Rails integration test doesn&amp;#8217;t exercise the entire system, since it uses a harness and doesn&amp;#8217;t use the system from the perspective of a user. As one example, you need to post form parameters directly rather than actually filling out the form, making the test both brittle in that if you change your &lt;span class="caps"&gt;HTML&lt;/span&gt; form the test will still pass, and incomplete in that it doesn&amp;#8217;t actually load the page up in a browser and verify that Javascript and &lt;span class="caps"&gt;CSS&lt;/span&gt; are not intefering with the submission of the form.&lt;/p&gt;
&lt;p&gt;Full system testing was popularized by the &lt;a href="http://cukes.info/"&gt;cucumber&lt;/a&gt; library, but cucumber adds a level of indirection that isn&amp;#8217;t useful for most applications. Unless you are actually collaborating with non-technical stakeholders, the extra complexity just gets in your way. RSpec can easily be written in a &lt;span class="caps"&gt;BDD&lt;/span&gt; style without extra libraries.&lt;/p&gt;
&lt;p&gt;Theoretically you should only be interacting with the system as a black box, which means no creating fixture data or otherwise messing with the internals of the system in order to set it up correctly. In practice, this tends to be unweildy but I still maintain a strict abstraction so that tests read like black box tests, hiding any internal modification behind an interface that &lt;em&gt;could&lt;/em&gt; be implemented by black box interactions, but is &amp;#8220;optimized&amp;#8221; to use internal knowledge. I&amp;#8217;ve had success with the builder pattern, also presented in the &lt;span class="caps"&gt;GOOS&lt;/span&gt; book, but that&amp;#8217;s another blog post (i.e. &lt;code&gt;build_registration.with_hosting_request.create&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;A common anti-pattern is to try and use transactional fixtures in acceptance tests. Don&amp;#8217;t do this. It isn&amp;#8217;t executing the full system (so can&amp;#8217;t test transaction level functionality) and is prone to flakiness.&lt;/p&gt;
&lt;p&gt;An acceptance test will typically take seconds to run, and should only be used for happy-path verification of behaviour. It makes sure that all the pieces hang together correctly. Edge case testing should be done at the unit or integration level. Ideally each new feature should have only one or two acceptance tests.&lt;/p&gt;
&lt;h2&gt;File Organisation.&lt;/h2&gt;
&lt;p&gt;I use &lt;code&gt;spec/{unit,integration,acceptance}&lt;/code&gt; folders as the parent of all specs. Each type of spec has it&amp;#8217;s own helper require, so unit specs require &lt;code&gt;unit_helper&lt;/code&gt; rather than &lt;code&gt;spec_helper&lt;/code&gt;. Each of those helpers will then require other helpers as appropriate, for instance my &lt;code&gt;rails_helper&lt;/code&gt; looks like this (note the hack required to support this layout):&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;RAILS_ENV&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] ||= &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="co"&gt;File&lt;/span&gt;.expand_path(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;../../config/environment&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;span class="pc"&gt;__FILE__&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# By default, rspec/rails tags all specs in spec/integration as request specs,&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# which is not what we want. There does not appear to be a way to disable this&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# behaviour, so below is a copy of rspec/rails.rb with this default behaviour&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# commented out.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;RSpec&lt;/span&gt;::configure &lt;span class="r"&gt;do&lt;/span&gt; |c|&lt;tt&gt;
&lt;/tt&gt;  c.backtrace_clean_patterns &amp;lt;&amp;lt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;vendor&lt;/span&gt;&lt;span class="ch"&gt;\/&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  c.backtrace_clean_patterns &amp;lt;&amp;lt; &lt;span class="rx"&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;span class="k"&gt;lib&lt;/span&gt;&lt;span class="ch"&gt;\/&lt;/span&gt;&lt;span class="k"&gt;rspec&lt;/span&gt;&lt;span class="ch"&gt;\/&lt;/span&gt;&lt;span class="k"&gt;rails&lt;/span&gt;&lt;span class="dl"&gt;/&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/extensions&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/view_rendering&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/adapters&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/matchers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/fixture_support&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/mocks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/module_inclusion&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# require 'rspec/rails/example' # Commented this out&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/vendor/capybara&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/vendor/webrat&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# Added the below, we still want access to some of the example groups&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/example/rails_example_group&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/example/controller_example_group&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;rspec/rails/example/helper_example_group&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Controllers specs go in &lt;code&gt;spec/integration/controllers&lt;/code&gt;, though I&amp;#8217;m trending towards using &lt;a href="https://github.com/xaviershay/poniard"&gt;poniard&lt;/a&gt; that allows me to test controllers in isolation (&lt;code&gt;spec/unit/controllers&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;Helpers are either unit or integration tested depending on the type of work they are doing. If it is domain level logic it can be unit tested (though I tend to use presenters for this, which are also unit tested), but for helpers that layer on top of Rails provided helpers (like &lt;code&gt;link_to&lt;/code&gt; or &lt;code&gt;content_tag&lt;/code&gt;) they should be integration tested to verify they are using the library in the correct way.&lt;/p&gt;
&lt;p&gt;I have used this approach on a number of Rails applications over the last 1-2 years and found it leads to better and more enjoyable code.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/873</id>
    <published>2012-12-09T21:45:12Z</published>
    <updated>2012-12-09T21:45:12Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/12/09/blocking-synchronous-calls-in-goliath"/>
    <title>Blocking (synchronous) calls in Goliath</title>
    <content type="html">&lt;p&gt;Posting for my future self. A generic function to run blocking code in a deferred thread and resume the fiber on completion, so as not to block the reactor loop.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;blocking&lt;/span&gt;(&amp;amp;f)&lt;tt&gt;
&lt;/tt&gt;  fiber = &lt;span class="co"&gt;Fiber&lt;/span&gt;.current&lt;tt&gt;
&lt;/tt&gt;  result = &lt;span class="pc"&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;EM&lt;/span&gt;.defer(f, -&amp;gt;(x){&lt;tt&gt;
&lt;/tt&gt;    result = x&lt;tt&gt;
&lt;/tt&gt;    fiber.resume&lt;tt&gt;
&lt;/tt&gt;  })&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;Fiber&lt;/span&gt;.yield&lt;tt&gt;
&lt;/tt&gt;  result&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Usage&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;MyServer&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Goliath&lt;/span&gt;::&lt;span class="co"&gt;API&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;response&lt;/span&gt;(env)&lt;tt&gt;
&lt;/tt&gt;    blocking { sleep &lt;span class="i"&gt;1&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;    [&lt;span class="i"&gt;200&lt;/span&gt;, {}, &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Woken up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/872</id>
    <published>2012-12-03T00:53:59Z</published>
    <updated>2012-12-03T00:53:59Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/12/03/form-objects-in-rails"/>
    <title>Form Objects in Rails</title>
    <content type="html">&lt;p&gt;For a while now I have been using form objects instead of nested attributes for complex forms, and the experience has been pleasant. A form object is an object designed explicitly to back a given form. It handles validation, defaults, casting, and translation of attributes to the persistence layer. A basic example:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Form::NewRegistration&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class="co"&gt;ActiveModel&lt;/span&gt;::&lt;span class="co"&gt;Validations&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.&lt;span class="fu"&gt;scalar_attributes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    [&lt;span class="sy"&gt;:name&lt;/span&gt;, &lt;span class="sy"&gt;:age&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  attr_accessor *scalar_attributes&lt;tt&gt;
&lt;/tt&gt;  attr_reader &lt;span class="sy"&gt;:event&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  validates_presence_of &lt;span class="sy"&gt;:name&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(event, params = {})&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="pc"&gt;self&lt;/span&gt;.class.scalar_attributes.each &lt;span class="r"&gt;do&lt;/span&gt; |attr|&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="pc"&gt;self&lt;/span&gt;.send(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%s=&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % attr, params[attr]) &lt;span class="r"&gt;if&lt;/span&gt; params.has_key?(attr)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;create&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;return&lt;/span&gt; &lt;span class="r"&gt;unless&lt;/span&gt; valid?&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    registration = &lt;span class="co"&gt;Registration&lt;/span&gt;.create!(&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ke"&gt;event&lt;/span&gt;: event,&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ke"&gt;data_json&lt;/span&gt;: {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ke"&gt;name&lt;/span&gt;: name,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ke"&gt;age&lt;/span&gt;:  age.to_i,&lt;tt&gt;
&lt;/tt&gt;      }.to_json&lt;tt&gt;
&lt;/tt&gt;    )&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    registration&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# ActiveModel support&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.&lt;span class="fu"&gt;name&lt;/span&gt;; &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Registration&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;; &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;persisted?&lt;/span&gt;; &lt;span class="pc"&gt;false&lt;/span&gt;; &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;to_key&lt;/span&gt;; &lt;span class="pc"&gt;nil&lt;/span&gt;; &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Note how this allows an easy mapping from form fields to a serialized &lt;span class="caps"&gt;JSON&lt;/span&gt; blob.&lt;/p&gt;
&lt;p&gt;I have found this more explicit and flexible than tying forms directly to nested attributes. It allows more fine tuned control of the form behaviour, is easier to reason about and test, and enables you to refactor your data model with minimal other changes. (In fact, if you are planning on refactoring your data model, adding in a form object as a &amp;#8220;shim&amp;#8221; to protect other parts of the system from change before you refactor is usually desirable.) It even works well with nested attributes, using the form object to build up the required nested hash in the &lt;code&gt;#create&lt;/code&gt; method.&lt;/p&gt;
&lt;h3&gt;Relationships&lt;/h3&gt;
&lt;p&gt;A benefit of this approach, albeit still a little clunky, is having accessors map one to one with form fields even for one to many associations. My approach takes advantages of Ruby&amp;#8217;s flexible object model to define accessors on the fly. For example, say a registration has multiple custom answer fields, as defined on the event, I would call the following method on initialisation:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;add_answer_accessors!&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  event.questions.each &lt;span class="r"&gt;do&lt;/span&gt; |q|&lt;tt&gt;
&lt;/tt&gt;    attr = &lt;span class="sy"&gt;&lt;span class="sy"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;answer_&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;q.id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    instance_eval &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-RUBY&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;      def &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;attr&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;;     answers[&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;q.id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;]; end&lt;tt&gt;
&lt;/tt&gt;      def &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;attr&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;=(x); answers[&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;q.id&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;] = x; end&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;    RUBY&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;With the exception of the above code (which isn&amp;#8217;t too bad), this greatly simplifies typical code for handling one to many relationships: it avoids &lt;code&gt;fields_for&lt;/code&gt;, &lt;code&gt;index&lt;/code&gt;, and is easier to set up sane defaults for.&lt;/p&gt;
&lt;h3&gt;Casting&lt;/h3&gt;
&lt;p&gt;I use a small supporting module to handle casting of attributes to certain types.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;TypedWriter&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;typed_writer&lt;/span&gt;(type, attribute)&lt;tt&gt;
&lt;/tt&gt;    class_eval &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;lt;&amp;lt;-EOS&lt;/span&gt;&lt;/span&gt;&lt;span class="s"&gt;&lt;span class="k"&gt;&lt;tt&gt;
&lt;/tt&gt;      def &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;attribute&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;=(x)&lt;tt&gt;
&lt;/tt&gt;        @&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;attribute&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt; = type_cast(x, :&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;type&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="k"&gt;)&lt;tt&gt;
&lt;/tt&gt;      end&lt;/span&gt;&lt;span class="dl"&gt;&lt;tt&gt;
&lt;/tt&gt;    EOS&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;type_cast&lt;/span&gt;(x, type)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;case&lt;/span&gt; type&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="sy"&gt;:integer&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      x.to_s.length &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt; ? x.to_i : &lt;span class="pc"&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="sy"&gt;:boolean&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      x.to_s.length &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt; ? x == &lt;span class="pc"&gt;true&lt;/span&gt; || x == &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : &lt;span class="pc"&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="sy"&gt;:boolean_with_nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt; x.to_s == &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; || x.nil?&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pc"&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        x.to_s.length &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt; ? x == &lt;span class="pc"&gt;true&lt;/span&gt; || x == &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; : &lt;span class="pc"&gt;nil&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;when&lt;/span&gt; &lt;span class="sy"&gt;:int_array&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      [*x].map(&amp;amp;&lt;span class="sy"&gt;:to_i&lt;/span&gt;).select {|x| x &amp;gt; &lt;span class="i"&gt;0&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      raise &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Unknown type &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;type&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="pc"&gt;self&lt;/span&gt;.&lt;span class="fu"&gt;included&lt;/span&gt;(klass)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# Make methods available both as class and instance methods.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    klass.extend(&lt;span class="pc"&gt;self&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;It is used like so:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Form::NewRegistration&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="c"&gt;# ...&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class="co"&gt;TypedWriter&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  typed_writer &lt;span class="sy"&gt;:age&lt;/span&gt;, &lt;span class="sy"&gt;:integer&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;I don&amp;#8217;t load Rails for my form tests, so an explicit require of active model is necessary. I do this in my form code since I like explicitly requiring third-party dependencies everywhere they are used.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;55&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;61&lt;tt&gt;
&lt;/tt&gt;62&lt;tt&gt;
&lt;/tt&gt;63&lt;tt&gt;
&lt;/tt&gt;64&lt;tt&gt;
&lt;/tt&gt;65&lt;tt&gt;
&lt;/tt&gt;66&lt;tt&gt;
&lt;/tt&gt;67&lt;tt&gt;
&lt;/tt&gt;68&lt;tt&gt;
&lt;/tt&gt;69&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;70&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;71&lt;tt&gt;
&lt;/tt&gt;72&lt;tt&gt;
&lt;/tt&gt;73&lt;tt&gt;
&lt;/tt&gt;74&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;unit_helper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;form/new_registration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;describe &lt;span class="co"&gt;Form&lt;/span&gt;::&lt;span class="co"&gt;NewRegistration&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  include &lt;span class="co"&gt;RSpec&lt;/span&gt;::&lt;span class="co"&gt;Fire&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  let(&lt;span class="sy"&gt;:event&lt;/span&gt;) { fire_double(&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Event&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;) }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  subject { described_class.new(event) }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;valid_attributes&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    {&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ke"&gt;name&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;don&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ke"&gt;age&lt;/span&gt;:  &lt;span class="i"&gt;25&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;form&lt;/span&gt;(extra = {})&lt;tt&gt;
&lt;/tt&gt;    described_class.new(event, valid_attributes.merge(extra))&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;validations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;is valid for default attributes&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      form.should be_valid&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    it { form(&lt;span class="ke"&gt;name&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;).should have_error_on(&lt;span class="sy"&gt;:name&lt;/span&gt;) }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;type-casting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    let(&lt;span class="sy"&gt;:f&lt;/span&gt;) { form } &lt;span class="c"&gt;# Memoize the form&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# This pattern is overkill in this example, but useful when you have many&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;# typed attributes.&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    let(&lt;span class="sy"&gt;:typecasts&lt;/span&gt;) {{&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ke"&gt;int&lt;/span&gt;: {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pc"&gt;nil&lt;/span&gt;  =&amp;gt; &lt;span class="pc"&gt;nil&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;   =&amp;gt; &lt;span class="pc"&gt;nil&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="i"&gt;23&lt;/span&gt;   =&amp;gt; &lt;span class="i"&gt;23&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;23&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; =&amp;gt; &lt;span class="i"&gt;23&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;      }&lt;tt&gt;
&lt;/tt&gt;    }}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;casts age to an int&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      typecasts[&lt;span class="sy"&gt;:int&lt;/span&gt;].each &lt;span class="r"&gt;do&lt;/span&gt; |value, expected|&lt;tt&gt;
&lt;/tt&gt;        f.age = value&lt;tt&gt;
&lt;/tt&gt;        f.age.should == expected&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;#create&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;returns false when not valid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      subject.create.should_not be&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;creates a new registration&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      f = form&lt;tt&gt;
&lt;/tt&gt;      dao = fire_replaced_class_double(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Registration&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;      dao.should_receive(&lt;span class="sy"&gt;:create&lt;/span&gt;).with {|x|&lt;tt&gt;
&lt;/tt&gt;        x[&lt;span class="sy"&gt;:event&lt;/span&gt;].should == event&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        data = &lt;span class="co"&gt;JSON&lt;/span&gt;.parse(x[&lt;span class="sy"&gt;:data_json&lt;/span&gt;])&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;        data[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;].should == valid_attributes[&lt;span class="sy"&gt;:name&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;        data[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;].should == valid_attributes[&lt;span class="sy"&gt;:age&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;      }&lt;tt&gt;
&lt;/tt&gt;      f.create.should new_rego&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  it { should_not be_persisted }&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;h3&gt;Code Sharing&lt;/h3&gt;
&lt;p&gt;I tend to have a parent object &lt;code&gt;Form::Registration&lt;/code&gt;, with subclasses for &lt;code&gt;Form::{New,Update,View}Registration&lt;/code&gt;. A common mixin would also work. For testing, I use a shared spec that is run by the specs for each of the three subclasses.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;There are other solutions to this problem (such as &lt;a href="http://devcaffeine.com/2012/06/20/isolating-validations-in-activemodel/"&gt;separating validations completely&lt;/a&gt;) which I haven&amp;#8217;t tried yet, and I haven&amp;#8217;t used this approach on a team yet. It has worked well for my solo projects though, and I&amp;#8217;m just about confident enough to recommend it for production use.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/871</id>
    <published>2012-11-25T20:27:38Z</published>
    <updated>2012-11-25T20:27:38Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/11/25/poniard-a-dependency-injector-for-rails"/>
    <title>Poniard: a Dependency Injector for Rails</title>
    <content type="html">&lt;p&gt;I just open sourced &lt;a href="https://github.com/xaviershay/poniard"&gt;poniard&lt;/a&gt;, a dependency injector for Rails. It&amp;#8217;s a newer version of &lt;a href="http://rhnh.net/2012/10/09/dependency-injection-for-rails-controllers"&gt;code I posted a few weeks back&lt;/a&gt; that allows you to write controllers using plain ruby objects:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="r"&gt;module&lt;/span&gt; &lt;span class="cl"&gt;Controller&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Registration&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;update&lt;/span&gt;(response, now_flash, update_form)&lt;tt&gt;
&lt;/tt&gt;      form = update_form&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;if&lt;/span&gt; form.save&lt;tt&gt;
&lt;/tt&gt;        response.respond_with &lt;span class="co"&gt;SuccessfulUpdateResponse&lt;/span&gt;, form&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;else&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        now_flash[&lt;span class="sy"&gt;:message&lt;/span&gt;] = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Could not save registration.&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        response.render &lt;span class="ke"&gt;action&lt;/span&gt;: &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;edit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;, &lt;span class="ke"&gt;ivars&lt;/span&gt;: {&lt;span class="ke"&gt;registration&lt;/span&gt;: form}&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="co"&gt;SuccessfulUpdateResponse&lt;/span&gt; = &lt;span class="co"&gt;Struct&lt;/span&gt;.new(&lt;span class="sy"&gt;:form&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;html&lt;/span&gt;(response, flash, current_event)&lt;tt&gt;
&lt;/tt&gt;        flash[&lt;span class="sy"&gt;:message&lt;/span&gt;] = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Updated details for %s&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % form.name&lt;tt&gt;
&lt;/tt&gt;        response.redirect_to &lt;span class="sy"&gt;:registrations&lt;/span&gt;, current_event&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;js&lt;/span&gt;(response)&lt;tt&gt;
&lt;/tt&gt;        response.render &lt;span class="ke"&gt;json&lt;/span&gt;: form&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This makes it possible to test them in isolation, leading to a better appreciation of your dependencies and nicer code.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/xaviershay/poniard"&gt;Check it out!&lt;/a&gt;&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/870</id>
    <published>2012-10-20T18:26:53Z</published>
    <updated>2012-10-20T18:26:53Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/10/20/guice-in-your-jruby"/>
    <title>Guice in your JRuby</title>
    <content type="html">&lt;p&gt;At &lt;a href="https://squareup.com"&gt;work&lt;/a&gt; we have a Java application container that uses &lt;a href="http://code.google.com/p/google-guice/"&gt;Google Guice&lt;/a&gt; for dependency injection. I thought it would be fun to try and embed some Ruby code into it.&lt;/p&gt;
&lt;p&gt;Guice uses types and annotations to wire components together, neither of which Ruby has. It also uses Java meta-class information heavily (&lt;code&gt;SomeClass.class&lt;/code&gt;). High hurdles, but we can clear them.&lt;/p&gt;
&lt;h2&gt;Warming Up&lt;/h2&gt;
&lt;p&gt;Normally JRuby is used to interpret Ruby code inside a Java environment, but it also provides functionality to compile a Ruby class to a Java one. In essence, it creates a Java wrapper class that delegates all calls to Ruby. Let&amp;#8217;s look at a simple example.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;# SayHello.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SayHello&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;hello&lt;/span&gt;(name)&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Compile using the &lt;code&gt;jrubyc&lt;/code&gt; script. By default it compiles directly to a &lt;code&gt;.class&lt;/code&gt; file, but it doesn&amp;#8217;t work correctly at the moment. Besides, going to Java first allows us to see what is going on.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;jrubyc --java SayHello.rb&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;The compiled Java is refreshingly easy to understand. It even has comments!&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Imports are redacted from all Java examples for brevity.&lt;/em&gt;&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;24&lt;tt&gt;
&lt;/tt&gt;25&lt;tt&gt;
&lt;/tt&gt;26&lt;tt&gt;
&lt;/tt&gt;27&lt;tt&gt;
&lt;/tt&gt;28&lt;tt&gt;
&lt;/tt&gt;29&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;30&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;31&lt;tt&gt;
&lt;/tt&gt;32&lt;tt&gt;
&lt;/tt&gt;33&lt;tt&gt;
&lt;/tt&gt;34&lt;tt&gt;
&lt;/tt&gt;35&lt;tt&gt;
&lt;/tt&gt;36&lt;tt&gt;
&lt;/tt&gt;37&lt;tt&gt;
&lt;/tt&gt;38&lt;tt&gt;
&lt;/tt&gt;39&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;40&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;41&lt;tt&gt;
&lt;/tt&gt;42&lt;tt&gt;
&lt;/tt&gt;43&lt;tt&gt;
&lt;/tt&gt;44&lt;tt&gt;
&lt;/tt&gt;45&lt;tt&gt;
&lt;/tt&gt;46&lt;tt&gt;
&lt;/tt&gt;47&lt;tt&gt;
&lt;/tt&gt;48&lt;tt&gt;
&lt;/tt&gt;49&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;51&lt;tt&gt;
&lt;/tt&gt;52&lt;tt&gt;
&lt;/tt&gt;53&lt;tt&gt;
&lt;/tt&gt;54&lt;tt&gt;
&lt;/tt&gt;55&lt;tt&gt;
&lt;/tt&gt;56&lt;tt&gt;
&lt;/tt&gt;57&lt;tt&gt;
&lt;/tt&gt;58&lt;tt&gt;
&lt;/tt&gt;59&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;60&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;// SayHello.java&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SayHello&lt;/span&gt; &lt;span class="di"&gt;extends&lt;/span&gt; RubyObject  {&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; Ruby __ruby__ = Ruby.getGlobalRuntime();&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="di"&gt;final&lt;/span&gt; RubyClass __metaclass__;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;static&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="pt"&gt;String&lt;/span&gt; source = &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="pt"&gt;StringBuilder&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;class SayHello&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;  def hello(name)&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;    puts &lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello #{name}&lt;/span&gt;&lt;span class="ch"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;  end&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="ch"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; +&lt;tt&gt;
&lt;/tt&gt;            &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;).toString();&lt;tt&gt;
&lt;/tt&gt;        __ruby__.executeScript(source, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;SayHello.rb&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        RubyClass metaclass = __ruby__.getClass(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;SayHello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        metaclass.setRubyStaticAllocator(SayHello.class);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;if&lt;/span&gt; (metaclass == &lt;span class="pc"&gt;null&lt;/span&gt;) &lt;span class="kw"&gt;throw&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; &lt;span class="ex"&gt;NoClassDefFoundError&lt;/span&gt;(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Could not load Ruby class: SayHello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;        __metaclass__ = metaclass;&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;/**&lt;tt&gt;
&lt;/tt&gt;     * Standard Ruby object constructor, for construction-from-Ruby purposes.&lt;tt&gt;
&lt;/tt&gt;     * Generally not for user consumption.&lt;tt&gt;
&lt;/tt&gt;     *&lt;tt&gt;
&lt;/tt&gt;     * @param ruby The JRuby instance this object will belong to&lt;tt&gt;
&lt;/tt&gt;     * @param metaclass The RubyClass representing the Ruby class of this object&lt;tt&gt;
&lt;/tt&gt;     */&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;private&lt;/span&gt; SayHello(Ruby ruby, RubyClass metaclass) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;super&lt;/span&gt;(ruby, metaclass);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;/**&lt;tt&gt;
&lt;/tt&gt;     * A static method used by JRuby for allocating instances of this object&lt;tt&gt;
&lt;/tt&gt;     * from Ruby. Generally not for user comsumption.&lt;tt&gt;
&lt;/tt&gt;     *&lt;tt&gt;
&lt;/tt&gt;     * @param ruby The JRuby instance this object will belong to&lt;tt&gt;
&lt;/tt&gt;     * @param metaclass The RubyClass representing the Ruby class of this object&lt;tt&gt;
&lt;/tt&gt;     */&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; IRubyObject __allocate__(Ruby ruby, RubyClass metaClass) {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; &lt;span class="kw"&gt;new&lt;/span&gt; SayHello(ruby, metaClass);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="c"&gt;/**&lt;tt&gt;
&lt;/tt&gt;     * Default constructor. Invokes this(Ruby, RubyClass) with the classloader-static&lt;tt&gt;
&lt;/tt&gt;     * Ruby and RubyClass instances assocated with this class, and then invokes the&lt;tt&gt;
&lt;/tt&gt;     * no-argument 'initialize' method in Ruby.&lt;tt&gt;
&lt;/tt&gt;     *&lt;tt&gt;
&lt;/tt&gt;     * @param ruby The JRuby instance this object will belong to&lt;tt&gt;
&lt;/tt&gt;     * @param metaclass The RubyClass representing the Ruby class of this object&lt;tt&gt;
&lt;/tt&gt;     */&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; SayHello() {&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="lv"&gt;this&lt;/span&gt;(__ruby__, __metaclass__);&lt;tt&gt;
&lt;/tt&gt;        RuntimeHelpers.invoke(__ruby__.getCurrentContext(), &lt;span class="lv"&gt;this&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;initialize&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="pt"&gt;Object&lt;/span&gt; hello(&lt;span class="pt"&gt;Object&lt;/span&gt; name) {&lt;tt&gt;
&lt;/tt&gt;        IRubyObject ruby_name = JavaUtil.convertJavaToRuby(__ruby__, name);&lt;tt&gt;
&lt;/tt&gt;        IRubyObject ruby_result = RuntimeHelpers.invoke(__ruby__.getCurrentContext(), &lt;span class="lv"&gt;this&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, ruby_name);&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="kw"&gt;return&lt;/span&gt; (&lt;span class="pt"&gt;Object&lt;/span&gt;)ruby_result.toJava(&lt;span class="pt"&gt;Object&lt;/span&gt;.class);&lt;tt&gt;
&lt;/tt&gt;    }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Simple: A Java class with concrete type and method definitions, delegating each method to Ruby. For the next step, JRuby supports metadata provided in Ruby to control the exact types and annotations that are used in the generated code.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;# SayHello.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SayHello&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  java_signature &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;void hello(String)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;hello&lt;/span&gt;(name)&lt;tt&gt;
&lt;/tt&gt;    puts &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello &lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;name&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; hello(&lt;span class="pt"&gt;String&lt;/span&gt; name) {&lt;tt&gt;
&lt;/tt&gt;    IRubyObject ruby_name = JavaUtil.convertJavaToRuby(__ruby__, name);&lt;tt&gt;
&lt;/tt&gt;    IRubyObject ruby_result = RuntimeHelpers.invoke(__ruby__.getCurrentContext(), &lt;span class="lv"&gt;this&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, ruby_name);&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="kw"&gt;return&lt;/span&gt;;&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Perfect! Now we have all the pieces we need to start wiring our Ruby into Guice.&lt;/p&gt;
&lt;h2&gt;Guice&lt;/h2&gt;
&lt;p&gt;Let&amp;#8217;s start by injecting an object that our Ruby class can use to do something interesting.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;JrubyGuiceExample&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; main(&lt;span class="pt"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; args) {&lt;tt&gt;
&lt;/tt&gt;    Injector injector = Guice.createInjector();&lt;tt&gt;
&lt;/tt&gt;    SimplestApp app = injector.getInstance(SimplestApp.class);&lt;tt&gt;
&lt;/tt&gt;    app.run();&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;java&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;java_package &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;net.rhnh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;java_import &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;com.google.inject.Inject&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;SimplestApp&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  java_annotation &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;Inject&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  java_signature &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;void MyApp(BareLogger logger)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;initialize&lt;/span&gt;(logger)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@logger&lt;/span&gt; = logger&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;run&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="iv"&gt;@logger&lt;/span&gt;.info(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;Hello from Ruby&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Guice will see the &lt;code&gt;BareLogger&lt;/code&gt; type, and automatically create an instance of that class to be passed to the initializer.&lt;/p&gt;
&lt;p&gt;Guice also allows more complex dependency graphs, such as knowing which concrete class to provide for an interface. These are declared using a module, which &amp;#8212; though probably not a good idea &amp;#8212; we can also write in ruby. The following example tells Guice to provide an instance of &lt;code&gt;PrefixLogger&lt;/code&gt; whenever an interface of &lt;code&gt;SimpleLogger&lt;/code&gt; is asked for.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;JrubyGuiceExample&lt;/span&gt; {&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="di"&gt;public&lt;/span&gt; &lt;span class="di"&gt;static&lt;/span&gt; &lt;span class="ty"&gt;void&lt;/span&gt; main(&lt;span class="pt"&gt;String&lt;/span&gt;&lt;span class="ty"&gt;[]&lt;/span&gt; args) {&lt;tt&gt;
&lt;/tt&gt;    Injector injector = Guice.createInjector(&lt;span class="kw"&gt;new&lt;/span&gt; ComplexModule());&lt;tt&gt;
&lt;/tt&gt;    ComplexApp app = injector.getInstance(ComplexApp.class);&lt;tt&gt;
&lt;/tt&gt;    app.run();&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;20&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;21&lt;tt&gt;
&lt;/tt&gt;22&lt;tt&gt;
&lt;/tt&gt;23&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;java&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;java_package &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;net.rhnh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;java_import &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;com.google.inject.Provides&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;java_import &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;com.google.inject.Binder&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ty"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ComplexModule&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  java_implements &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;com.google.inject.Module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  java_signature &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;void configure(Binder binder)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  def configure(binder)&lt;tt&gt;
&lt;/tt&gt;    binder.&lt;tt&gt;
&lt;/tt&gt;      bind(java::SimpleLogger.java_class).&lt;tt&gt;
&lt;/tt&gt;      to(java::PrefixLogger.java_class)&lt;tt&gt;
&lt;/tt&gt;  end&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="di"&gt;protected&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  def java&lt;tt&gt;
&lt;/tt&gt;    Java::net.rhnh&lt;tt&gt;
&lt;/tt&gt;  end&lt;tt&gt;
&lt;/tt&gt;end&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;You can also provide more complex setup logic in dedicated methods with the &lt;code&gt;Provides&lt;/code&gt; annotation. See the example project linked at the bottom of the post.&lt;/p&gt;
&lt;h2&gt;Maven integration&lt;/h2&gt;
&lt;p&gt;Running &lt;code&gt;jrubyc&lt;/code&gt; all the time is a drag. Thankfully, someone has already made a maven plugin that puts everything in the right place.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="ta"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;de.saumya.mojo&lt;span class="ta"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;jruby-maven-plugin&lt;span class="ta"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.29.1&lt;span class="ta"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;configuration&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;generateJava&amp;gt;&lt;/span&gt;true&lt;span class="ta"&gt;&amp;lt;/generateJava&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;generatedJavaDirectory&amp;gt;&lt;/span&gt;target/generated-sources/jruby&lt;span class="ta"&gt;&amp;lt;/generatedJavaDirectory&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;/configuration&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;executions&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;execution&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ta"&gt;&amp;lt;phase&amp;gt;&lt;/span&gt;process-resources&lt;span class="ta"&gt;&amp;lt;/phase&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ta"&gt;&amp;lt;goals&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;        &lt;span class="ta"&gt;&amp;lt;goal&amp;gt;&lt;/span&gt;compile&lt;span class="ta"&gt;&amp;lt;/goal&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="ta"&gt;&amp;lt;/goals&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="ta"&gt;&amp;lt;/execution&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="ta"&gt;&amp;lt;/executions&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="ta"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Now running &lt;code&gt;mvn package&lt;/code&gt; will compile Ruby code from &lt;code&gt;src/main/ruby&lt;/code&gt; to java code in &lt;code&gt;target&lt;/code&gt;, which is then available for the main Java build to compile.&lt;/p&gt;
&lt;p&gt;For more examples and runnable code, see the &lt;a href="https://raw.github.com/xaviershay/jruby-guice"&gt;jruby-guice&lt;/a&gt; project on GitHub.&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/869</id>
    <published>2012-10-15T00:13:23Z</published>
    <updated>2012-10-15T00:13:23Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/10/15/benchmarking-rspec-double-versus-openstruct"/>
    <title>Benchmarking RSpec double versus OpenStruct</title>
    <content type="html">&lt;p&gt;I noticed a number of my unit tests were taking upwards of 10ms, an order of magnitude slower than they should be. Turns out I was abusing rspec doubles, in particular I was using one instead of a value object. Doubles are &lt;em&gt;far&lt;/em&gt; slower than plain Ruby objects, in particular as the number of attributes goes up. It looks linear, but the constant factor is bad. The following benchmark demonstrates using a double versus an &lt;code&gt;OpenStruct&lt;/code&gt;, which can often be used as a drop in replacement. (Normally I just use the value object itself, but it this case it was an &lt;code&gt;ActiveRecord&lt;/code&gt; subclass.)&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;ostruct&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;benchmark&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  let(&lt;span class="sy"&gt;:attributes&lt;/span&gt;) {&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="co"&gt;ENV&lt;/span&gt;[&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;N&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;].to_i.times.each_with_object({}) {|x, h| h[&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;attr_&lt;/span&gt;&lt;span class="il"&gt;&lt;span class="idl"&gt;#{&lt;/span&gt;x&lt;span class="idl"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;] = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; }&lt;tt&gt;
&lt;/tt&gt;  }&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="i"&gt;5&lt;/span&gt;.times &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;measures doubles&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      double(attributes)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;    it &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;measures structs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="co"&gt;OpenStruct&lt;/span&gt;.new(attributes)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;&lt;img src="https://img.skitch.com/20121015-c22uj2mm3ds18ncdisfhf8rqxu.jpg" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Only 6-8 attributes before the 1ms barrier is broken, and this is only for construction!&lt;/p&gt;
&lt;p&gt;To graph it, I threw out the first result for each measurement, since it tended to be all over the shop during warm up. The following script is a hack that relies on &lt;em&gt;a priori&lt;/em&gt; knowledge that double is slower, since it doesn&amp;#8217;t try to match rspec profile out measurements to label. The measurements are so different in this case that it works.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&amp;gt; for N in {1..20}; do env N=$N rspec benchmark_spec.rb -p | \&lt;tt&gt;
&lt;/tt&gt;  grep seconds | \&lt;tt&gt;
&lt;/tt&gt;  grep benchmark_spec | \&lt;tt&gt;
&lt;/tt&gt;  awk '{print $1}' | \&lt;tt&gt;
&lt;/tt&gt;  xargs echo $N; done &amp;gt; results.dat&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&amp;gt; gnuplot &amp;lt;&amp;lt; eor&lt;tt&gt;
&lt;/tt&gt;set terminal jpeg size 600,200 font &amp;quot;arial,9&amp;quot;&lt;tt&gt;
&lt;/tt&gt;set key left&lt;tt&gt;
&lt;/tt&gt;set output 'graph.jpg'&lt;tt&gt;
&lt;/tt&gt;set datafile separator &amp;quot; &amp;quot;&lt;tt&gt;
&lt;/tt&gt;set xlabel '# of attributes'&lt;tt&gt;
&lt;/tt&gt;set ylabel 'construction time (s)'&lt;tt&gt;
&lt;/tt&gt;plot 'results.dat' u 1:( (\$3+\$4+\$5+\$6)/4) with lines title 'Double', \&lt;tt&gt;
&lt;/tt&gt;       '' u 1:( (\$8+\$9+\$10+\$11) / 4) with lines title 'Struct'&lt;tt&gt;
&lt;/tt&gt;eor&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;My next project: what is the best way to get the elevated guarantees provided by &lt;a href="https://github.com/xaviershay/rspec-fire"&gt;rspec-fire&lt;/a&gt; without taking the speed hit?&lt;/p&gt;</content>
  </entry>
  <entry>
    <id>tag:rhnh.net,2008:Post/868</id>
    <published>2012-10-13T19:11:00Z</published>
    <updated>2012-10-13T19:11:18Z</updated>
    <link rel="alternate" type="text/html" href="http://rhnh.net/2012/10/13/testing-stripe-oauth-connect-with-capybara-and-selenium"/>
    <title>Testing Stripe OAuth Connect with Capybara and Selenium</title>
    <content type="html">&lt;p&gt;&lt;a href="https://stripe.com"&gt;Stripe&lt;/a&gt; only allows you to set a fixed redirect &lt;span class="caps"&gt;URL&lt;/span&gt; in your test OAuth settings. This is problematic because you need to redirect to a different host and port depending on whether you are in development or test mode. In other words, there is a global callback that needs to be routed correctly to local callbacks.&lt;/p&gt;
&lt;p&gt;My workaround is to use a simple rack application that redirects any incoming requests to the selected host and port. The Capybara host and port is written out to a file on spec start, and if that isn&amp;#8217;t present it assumes development. It is clearly a hack, but works fairly well until Stripe provides a better way to do it.&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;14&lt;tt&gt;
&lt;/tt&gt;15&lt;tt&gt;
&lt;/tt&gt;16&lt;tt&gt;
&lt;/tt&gt;17&lt;tt&gt;
&lt;/tt&gt;18&lt;tt&gt;
&lt;/tt&gt;19&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;# stripe.ru&lt;tt&gt;
&lt;/tt&gt;run lambda {|env|&lt;tt&gt;
&lt;/tt&gt;  req = Rack::Request.new(env)&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  server_file = &amp;quot;/tmp/capybara_server&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  host_and_port = if File.exists?(server_file)&lt;tt&gt;
&lt;/tt&gt;    File.read(server_file)&lt;tt&gt;
&lt;/tt&gt;  else&lt;tt&gt;
&lt;/tt&gt;    &amp;quot;localhost:3000&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  end&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  response = Rack::Response.new(env)&lt;tt&gt;
&lt;/tt&gt;  url = &amp;quot;http://#{host_and_port}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  url &amp;lt;&amp;lt; &amp;quot;#{req.path}&amp;quot;&lt;tt&gt;
&lt;/tt&gt;  url &amp;lt;&amp;lt; &amp;quot;?#{req.query_string}&amp;quot; unless req.query_string.empty?&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  response.redirect(url)&lt;tt&gt;
&lt;/tt&gt;  response.finish&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;5&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;13&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;&lt;span class="c"&gt;# spec/acceptance_helper.rb&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;SERVER_FILE&lt;/span&gt; = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;/tmp/capybara_server&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;Capybara&lt;/span&gt;.server {|app, port|&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;File&lt;/span&gt;.open(&lt;span class="co"&gt;SERVER_FILE&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;w&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;) {|f| f.write(&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;%s:%i&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; % [&lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, port]) }&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;Capybara&lt;/span&gt;.run_default_server(app, port)&lt;tt&gt;
&lt;/tt&gt;}&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;RSpec&lt;/span&gt;.configure &lt;span class="r"&gt;do&lt;/span&gt; |config|&lt;tt&gt;
&lt;/tt&gt;  config.after &lt;span class="sy"&gt;:suite&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="co"&gt;FileUtils&lt;/span&gt;.rm(&lt;span class="co"&gt;SERVER_FILE&lt;/span&gt;) &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="co"&gt;File&lt;/span&gt;.exists?(&lt;span class="co"&gt;SERVER_FILE&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;This requires the rack application to be running already (much like the database is expected to be running), which can be done thusly:&lt;/p&gt;&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"&gt;bundle exec rackup --port 3001 stripe.ru&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
&lt;p&gt;Set your Stripe callback to &lt;code&gt;http://localhost:3001/your/callback&lt;/code&gt;.&lt;/p&gt;</content>
  </entry>
</feed>
