Jekyll2022-03-21T11:50:11+00:00https://alisnic.github.io/feed.xmlAndrei Lisnic blogMy static blogAndrei Lisnicandrei.lisnic@gmail.comOn logic in a Rails app, revisited 6 years later2019-05-18T00:00:00+00:002019-05-18T00:00:00+00:00https://alisnic.github.io/posts/rails-logic-revisited<p>6 years ago, I wrote one of my most popular blog posts - <a href="/posts/rails-logic/">On logic in a Rails app</a>, in which I debate one of <a href="https://mobile.twitter.com/dhh">@dhh</a>’s
critiques of <a href="https://grantammons.me/2012/12/22/where-the-logic-hides/">extracting code from controller</a>:</p>
<blockquote>
<p>So all you’ve done here is extract the work of the controller action into a separate object. This adds needless indirection, makes the code base harder to follow, and is completely unnecessary.</p>
</blockquote>
<p><em>NOTE: the original article changed its permalink, which wiped out
the original disqus comments including <a href="https://mobile.twitter.com/dhh">@dhh</a>’s comment
in that post</em></p>
<p>To summarize my article, my argument was that Rails is just an UI layer, and business
logic should be put in domain objects instead of keeping somewhere in Model, View or Controller.</p>
<p>To give you some context, it was a time when I was starting to grow as a Rails/Ruby
developer. I was reading a lot of blog posts on the topics and (as any young
developer with a lot of self esteem) I started to have
very strong feelings as to how Rails code should be written.</p>
<p>Fast forward 6 years, and a lot of things happened in my career as software developer:</p>
<ul>
<li>My experience got more rich. I launched projects, working with a lot of different
constraints and people</li>
<li>My day to day work changed. I climbed the company ladder, eventually ending up in the
CTO position. The types of decisions that I have to make changed.</li>
<li>I got more emotionally mature, which thankfully prevented me from writing more
controversial blog posts</li>
</ul>
<p>So what do I think about that post, and the comment from <a href="https://mobile.twitter.com/dhh">@dhh</a> now?
Where should logic of your application be put? model? controller? service objects?</p>
<p>It’s about trade-offs and personal preferences. If you found a way to keep all the logic in controllers, while:</p>
<ul>
<li>your team iterates fast and does not make silly mistakes</li>
<li>code is easily digestible</li>
<li>new features can be added without pain</li>
</ul>
<p>Then good for you! It doesn’t matter what me or <a href="https://mobile.twitter.com/dhh">@dhh</a> or any other person says. If not,
well maybe putting logic in domain objects will work for your team, maybe not. Just explore and
find what suits you best.</p>
<p>Each team operates in an unique set of technical and non-technical circumstances, which are almost impossible to communicate
via internet during technical arguments. That’s due language limitations, lack of proper
writing skills for all parties, silly code samples (most code is under NDA, so people use animals that inherit each other
to teach OO)</p>
<p>All the factors mentioned above mean only one thing - it’s very hard to maintain a productive
discussion on the internet about the “right” approach of building software, because that may
be very similar to discussing religion. There’s so much hidden context, that you might as
well just respect the other’s decisions and focus on their personal insight instead.</p>
<p>See discussion of this post on <a href="https://news.ycombinator.com/item?id=19949554">Hacker News</a>.</p>Andrei Lisnicandrei.lisnic@gmail.com6 years ago, I wrote one of my most popular blog posts - On logic in a Rails app, in which I debate one of @dhh’s critiques of extracting code from controller:Fitting the “339 bytes of responsive CSS” in a tweet, with a twist2019-05-17T00:00:00+00:002019-05-17T00:00:00+00:00https://alisnic.github.io/posts/fitting-339-bytes-of-responsive-css-in-a-tweet<p>Being amazed by how good and functional a web page can be by just
<a href="https://blog.koley.in/2019/339-bytes-of-responsive-css">using 339 bytes of css</a>,
I decided to play a bit with it and adapt it to my needs.</p>
<p>The styling of the post you are reading right now, (minified, except syntax highlighting css) <a href="https://mobile.twitter.com/andrei_lisnic/status/1129495286471168006">fits in a tweet</a>.
It has the following features:</p>
<ul>
<li>responsive - looks good on any screen</li>
<li>is friendly to source code</li>
<li>does not use external fonts to save bytes and the planet</li>
<li><strong>it supports Safari’s dark mode</strong></li>
</ul>
<p>Here’s how the dark mode switching looks in action:</p>
<p><img src="/assets/fitting-339-bytes-of-responsive-css-it-a-tweet/dark-mode.gif" alt="" /></p>
<p>And here’s the unminidied, annotated source:</p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">body</span> <span class="p">{</span>
<span class="nl">font-family</span><span class="p">:</span> <span class="n">Georgia</span><span class="p">,</span> <span class="nb">serif</span><span class="p">;</span>
<span class="nl">line-height</span><span class="p">:</span> <span class="m">1.6</span><span class="p">;</span>
<span class="c">/* when you use relative units, stuff looks good on any screen */</span>
<span class="nl">max-width</span><span class="p">:</span> <span class="m">40rem</span><span class="p">;</span>
<span class="nl">padding</span><span class="p">:</span> <span class="m">2rem</span><span class="p">;</span>
<span class="nl">margin</span><span class="p">:</span> <span class="nb">auto</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">img</span> <span class="p">{</span>
<span class="c">/* make sure that all images fit in the viewport */</span>
<span class="nl">max-width</span><span class="p">:</span> <span class="m">100%</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">pre</span> <span class="p">{</span>
<span class="c">/* add a line to separate code blocks visually from usual text */</span>
<span class="nl">border</span><span class="p">:</span> <span class="m">1px</span> <span class="nb">solid</span> <span class="m">#eee</span><span class="p">;</span>
<span class="nl">border-width</span><span class="p">:</span> <span class="m">1px</span> <span class="m">0</span><span class="p">;</span>
<span class="c">/* Pre blocks don't wrap (and shouldn't). Scroll their content in case
they overflow so that the viewport size stays the same */</span>
<span class="nl">overflow-y</span><span class="p">:</span> <span class="nb">scroll</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">@media</span> <span class="p">(</span><span class="n">prefers-color-scheme</span><span class="p">:</span><span class="n">dark</span><span class="p">)</span> <span class="p">{</span>
<span class="nt">body</span> <span class="p">{</span>
<span class="c">/* the dark mode just inverts everything, using a black background */</span>
<span class="nl">filter</span><span class="p">:</span> <span class="nb">invert</span><span class="p">(</span><span class="m">1</span><span class="p">);</span>
<span class="nl">background-color</span><span class="p">:</span> <span class="no">black</span><span class="p">;</span>
<span class="p">}</span>
<span class="nt">img</span> <span class="p">{</span>
<span class="c">/* the invert filter above inverts images as well, so we'll need
to revert that effect */</span>
<span class="nl">filter</span><span class="p">:</span> <span class="nb">invert</span><span class="p">(</span><span class="m">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>Andrei Lisnicandrei.lisnic@gmail.comBeing amazed by how good and functional a web page can be by just using 339 bytes of css, I decided to play a bit with it and adapt it to my needs.Enforcing that a ruby method is called from a specific location2017-06-28T00:00:00+00:002017-06-28T00:00:00+00:00https://alisnic.github.io/posts/validating-calltrace<p>If you, like me, get interested in tricky programming questions found randomly
on twitter, here’s a nice one for you:</p>
<p>Suppose you have a Ruby class with a method and another class with other methods that
call it:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Work</span>
<span class="k">def</span> <span class="nf">execute</span>
<span class="c1"># calling Foo.new.bar here should work</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">other_method</span>
<span class="c1"># calling Foo.new.bar here should raise error</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>The requirement is simple - enforce that <code class="language-plaintext highlighter-rouge">Foo#bar</code> is ONLY called from inside
<code class="language-plaintext highlighter-rouge">Work#execute</code>, not from elsewhere.</p>
<p>First thought that comes to mind is to use magic
<a href="https://ruby-doc.org/core-2.4.1/Kernel.html#method-i-caller">caller</a>
array in Ruby to make sure that a given location is in the callstack:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># test.rb</span>
<span class="k">module</span> <span class="nn">Guardian</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">ensure_method_called!</span><span class="p">(</span><span class="n">location</span><span class="p">)</span>
<span class="k">unless</span> <span class="nb">caller</span><span class="p">.</span><span class="nf">any?</span> <span class="p">{</span><span class="o">|</span><span class="n">line</span><span class="o">|</span> <span class="n">line</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="n">location</span><span class="p">)}</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"nice try lol"</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="no">Guardian</span><span class="p">.</span><span class="nf">ensure_method_called!</span><span class="p">(</span><span class="s2">"test.rb:21"</span><span class="p">)</span>
<span class="s2">"bar"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Work</span>
<span class="k">def</span> <span class="nf">execute</span>
<span class="c1"># calling Foo.new.bar here should work</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">bar</span> <span class="o">+</span> <span class="s2">" from execute"</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">other_method</span>
<span class="c1"># calling Foo.new.bar here should raise error</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="no">Work</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">execute</span>
<span class="nb">puts</span> <span class="no">Work</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">other_method</span>
</code></pre></div></div>
<p>Executing it, we get the following output:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ruby test.rb
bar from execute
test.rb:6:in `ensure_method_called!': nice try lol (ArgumentError)
from test.rb:13:in `bar'
from test.rb:26:in `other_method'
from test.rb:31:in `<main>'
shell returned 1
</code></pre></div></div>
<p>When can see that the approach works, BUT there are several issues with the implementation:</p>
<ul>
<li>if you rename the file, the checks will not work (filename is hardcoded)</li>
<li>if you change the source, the change will also break (line number is hardcoded)</li>
</ul>
<p>To <em>really</em> solve the challenge, we need to have a flexible solution
that will not be coupled with any hardcoded values. Ideally, the API should look
like this:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="no">Guardian</span><span class="p">.</span><span class="nf">ensure_instance_method_called!</span><span class="p">(</span><span class="no">Work</span><span class="p">,</span> <span class="ss">:execute</span><span class="p">)</span>
<span class="s2">"bar"</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>We can use the same <code class="language-plaintext highlighter-rouge">caller</code> array check, but this time we need to somehow figure
out lines where a method is defined, and then check if one of the lines of the
method is included in the <code class="language-plaintext highlighter-rouge">caller</code> array. The code would look line this:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="nn">Guardian</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">ensure_instance_method_called!</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
<span class="n">file_name</span><span class="p">,</span> <span class="n">source_lines</span> <span class="o">=</span> <span class="n">instance_method_info</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
<span class="n">is_method_called</span> <span class="o">=</span> <span class="nb">caller</span><span class="p">.</span><span class="nf">any?</span> <span class="k">do</span> <span class="o">|</span><span class="n">frame</span><span class="o">|</span>
<span class="c1"># frame looks like this:</span>
<span class="c1"># /Users/andrei/Play/alisnic.github.com/test.rb:14:in `work'</span>
<span class="n">file</span><span class="p">,</span> <span class="n">line</span> <span class="o">=</span> <span class="n">frame</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">)[</span><span class="mi">0</span><span class="o">..</span><span class="mi">1</span><span class="p">]</span>
<span class="n">file</span> <span class="o">==</span> <span class="n">file_name</span> <span class="o">&&</span> <span class="n">source_lines</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="nf">to_i</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"nice try lol"</span><span class="p">)</span> <span class="k">unless</span> <span class="n">is_method_called</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>All that is left is to implement the <code class="language-plaintext highlighter-rouge">instance_method_info</code>, which should return
the file name and a range with line numbers where an instance method is defined.</p>
<p>Ruby has “instance_method” method, which can give us some information about an
instance method:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">003</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="no">Work</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:execute</span><span class="p">)</span>
<span class="o">=></span> <span class="c1">#<UnboundMethod: Work#execute></span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">004</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="no">Work</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:execute</span><span class="p">).</span><span class="nf">methods</span> <span class="o">-</span> <span class="no">Object</span><span class="p">.</span><span class="nf">methods</span>
<span class="o">=></span> <span class="p">[</span><span class="ss">:arity</span><span class="p">,</span> <span class="ss">:original_name</span><span class="p">,</span> <span class="ss">:owner</span><span class="p">,</span> <span class="ss">:bind</span><span class="p">,</span> <span class="ss">:source_location</span><span class="p">,</span> <span class="ss">:parameters</span><span class="p">,</span> <span class="ss">:super_method</span><span class="p">]</span>
</code></pre></div></div>
<p>We can notice that among the defined methods there is an interesting one -
<code class="language-plaintext highlighter-rouge">source_location</code>. Let’s see what it returns:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">005</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="no">Work</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:execute</span><span class="p">).</span><span class="nf">source_location</span>
<span class="o">=></span> <span class="p">[</span><span class="s2">"/Users/andrei/Play/alisnic.github.com/test.rb"</span><span class="p">,</span> <span class="mi">19</span><span class="p">]</span>
</code></pre></div></div>
<p>We are close! We have the file name and the line where the method <em>starts</em>. All
that is left is to figure out where the method ends.</p>
<p>As you saw above, in Ruby we can ask a class all of its methods. We can also ask
for all instance methods:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">007</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="no">Work</span><span class="p">.</span><span class="nf">instance_methods</span> <span class="o">-</span> <span class="no">Object</span><span class="p">.</span><span class="nf">methods</span>
<span class="o">=></span> <span class="p">[</span><span class="ss">:execute</span><span class="p">,</span> <span class="ss">:other_method</span><span class="p">]</span>
</code></pre></div></div>
<p><strong>NOTE</strong>: we are subtracting <code class="language-plaintext highlighter-rouge">Object.methods</code> from the result because Ruby defines
a bunch of methods for us. We are interested only in those that we wrote.</p>
<p>So how to figure out where a method ends? Well, it certainly ends before the next
one begins! We can get source_location of all methods, sort it, and make a guess
where each method ends:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">module</span> <span class="nn">Guardian</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">instance_method_info</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
<span class="nb">methods</span> <span class="o">=</span> <span class="n">klass</span><span class="p">.</span><span class="nf">instance_methods</span> <span class="o">-</span> <span class="no">Object</span><span class="p">.</span><span class="nf">methods</span>
<span class="c1"># We start by building an array with all the instance methods of the class.</span>
<span class="c1"># Each entry would look like this:</span>
<span class="c1">#</span>
<span class="c1"># {</span>
<span class="c1"># name: :other_method,</span>
<span class="c1"># file: "/Users/andrei/Play/alisnic.github.com/test.rb",</span>
<span class="c1"># start_line: 24</span>
<span class="c1"># }</span>
<span class="n">candidates</span> <span class="o">=</span> <span class="nb">methods</span><span class="p">.</span><span class="nf">map</span> <span class="k">do</span> <span class="o">|</span><span class="nb">name</span><span class="o">|</span>
<span class="n">location</span> <span class="o">=</span> <span class="n">klass</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="nb">name</span><span class="p">).</span><span class="nf">source_location</span>
<span class="p">{</span>
<span class="ss">name: </span><span class="nb">name</span><span class="p">,</span>
<span class="ss">file: </span><span class="n">location</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span>
<span class="ss">start_line: </span><span class="n">location</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="c1"># Next, we sort those entries by start line, in reverse order. We will start</span>
<span class="c1"># guessing method locations from bottom to up</span>
<span class="n">reversed</span> <span class="o">=</span> <span class="n">candidates</span><span class="p">.</span><span class="nf">sort_by</span> <span class="p">{</span><span class="o">|</span><span class="n">entry</span><span class="o">|</span> <span class="o">-</span><span class="n">entry</span><span class="p">[</span><span class="ss">:start_line</span><span class="p">]</span> <span class="p">}</span>
<span class="c1"># We don't know where is the end of the last method of the class, hence we</span>
<span class="c1"># assume it is 99999. Starting from there, each method's last line is the</span>
<span class="c1"># line before the previous method start line</span>
<span class="n">with_lines</span> <span class="o">=</span> <span class="n">reversed</span><span class="p">.</span><span class="nf">reduce</span><span class="p">([])</span> <span class="k">do</span> <span class="o">|</span><span class="n">result</span><span class="p">,</span> <span class="n">entry</span><span class="o">|</span>
<span class="n">previous_method</span> <span class="o">=</span> <span class="n">result</span><span class="p">.</span><span class="nf">last</span>
<span class="n">previous_line</span> <span class="o">=</span> <span class="n">previous_method</span> <span class="p">?</span> <span class="n">previous_method</span><span class="p">[</span><span class="ss">:start_line</span><span class="p">]</span> <span class="p">:</span> <span class="mi">99999</span>
<span class="n">result</span> <span class="o"><<</span> <span class="n">entry</span><span class="p">.</span><span class="nf">merge</span><span class="p">(</span><span class="ss">lines: </span><span class="n">entry</span><span class="p">[</span><span class="ss">:start_line</span><span class="p">]</span><span class="o">..</span><span class="n">previous_line</span><span class="p">)</span>
<span class="k">end</span>
<span class="c1"># Next, we find the method we are interested in</span>
<span class="nb">method</span> <span class="o">=</span> <span class="n">with_lines</span><span class="p">.</span><span class="nf">find</span> <span class="p">{</span><span class="o">|</span><span class="n">entry</span><span class="o">|</span> <span class="n">entry</span><span class="p">[</span><span class="ss">:name</span><span class="p">]</span> <span class="o">==</span> <span class="n">method_name</span> <span class="p">}</span>
<span class="c1"># And return only the information we need</span>
<span class="p">[</span><span class="nb">method</span><span class="p">[</span><span class="ss">:file</span><span class="p">],</span> <span class="nb">method</span><span class="p">[</span><span class="ss">:lines</span><span class="p">]]</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>When we try to execute the defined method, we get the following result:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mi">114</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="no">Guardian</span><span class="p">.</span><span class="nf">instance_method_info</span><span class="p">(</span><span class="no">Work</span><span class="p">,</span> <span class="ss">:execute</span><span class="p">)</span>
<span class="o">=></span> <span class="p">[</span><span class="s2">"/Users/andrei/Play/alisnic.github.com/test.rb"</span><span class="p">,</span> <span class="mi">19</span><span class="o">..</span><span class="mi">24</span><span class="p">]</span>
</code></pre></div></div>
<p>Awesome! We have the range of lines where the method is defined, let’s write the
final test script:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># test.rb</span>
<span class="k">module</span> <span class="nn">Guardian</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">ensure_method_called!</span><span class="p">(</span><span class="n">location</span><span class="p">)</span>
<span class="k">unless</span> <span class="nb">caller</span><span class="p">.</span><span class="nf">any?</span> <span class="p">{</span><span class="o">|</span><span class="n">line</span><span class="o">|</span> <span class="n">line</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="n">location</span><span class="p">)}</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"nice try lol"</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">ensure_instance_method_called!</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
<span class="n">file_name</span><span class="p">,</span> <span class="n">source_lines</span> <span class="o">=</span> <span class="n">instance_method_info</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
<span class="n">is_method_called</span> <span class="o">=</span> <span class="nb">caller</span><span class="p">.</span><span class="nf">any?</span> <span class="k">do</span> <span class="o">|</span><span class="n">frame</span><span class="o">|</span>
<span class="n">file</span><span class="p">,</span> <span class="n">line</span> <span class="o">=</span> <span class="n">frame</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">":"</span><span class="p">)[</span><span class="mi">0</span><span class="o">..</span><span class="mi">1</span><span class="p">]</span>
<span class="n">file</span> <span class="o">==</span> <span class="n">file_name</span> <span class="o">&&</span> <span class="n">source_lines</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="n">line</span><span class="p">.</span><span class="nf">to_i</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"nice try lol"</span><span class="p">)</span> <span class="k">unless</span> <span class="n">is_method_called</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">instance_method_info</span><span class="p">(</span><span class="n">klass</span><span class="p">,</span> <span class="n">method_name</span><span class="p">)</span>
<span class="c1"># same code as above</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">bar</span>
<span class="no">Guardian</span><span class="p">.</span><span class="nf">ensure_instance_method_called!</span><span class="p">(</span><span class="no">Work</span><span class="p">,</span> <span class="ss">:execute</span><span class="p">)</span>
<span class="s2">"bar"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Work</span>
<span class="k">def</span> <span class="nf">execute</span>
<span class="c1"># calling Foo.new.bar here should work</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">bar</span> <span class="o">+</span> <span class="s2">" from execute"</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">other_method</span>
<span class="c1"># calling Foo.new.bar here should raise error</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">bar</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="no">Work</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">execute</span>
<span class="nb">puts</span> <span class="no">Work</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">other_method</span>
</code></pre></div></div>
<p>When we will execute it, it will work as expected:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ruby test.rb
bar from execute
test.rb:18:in `ensure_instance_method_called!': nice try lol (ArgumentError)
from test.rb:66:in `bar'
from test.rb:79:in `other_method'
from test.rb:84:in `<main>'
shell returned 1
</code></pre></div></div>
<p>So there you go, we have a half-baked solution for a problem that barely exists!
That was fun! In all seriousness, if we were to implement this properly, we would
take a different approach. There is a category of tools that are perfectly aware
of what code calls what functions - profilers. So a “production” implementation
of this task would be to use a ruby tracing function to track function calls.</p>
<p>Here’s a link to a gist with the whole source in case you want to play with it:
<a href="https://gist.github.com/alisnic/1ccc6e1357e0365ee4ed8655f2e1d7dd">https://gist.github.com/alisnic/1ccc6e1357e0365ee4ed8655f2e1d7dd</a></p>Andrei Lisnicandrei.lisnic@gmail.comIf you, like me, get interested in tricky programming questions found randomly on twitter, here’s a nice one for you:Log filename, line and function name in ruby automatically2013-05-11T00:00:00+00:002013-05-11T00:00:00+00:00https://alisnic.github.io/posts/ruby-logs<p>Suppose you have a app with a logger:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s1">'logger'</span>
<span class="k">module</span> <span class="nn">MyApp</span>
<span class="no">Log</span> <span class="o">=</span> <span class="no">Logger</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">STDOUT</span><span class="p">)</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">hello</span>
<span class="no">Log</span><span class="p">.</span><span class="nf">info</span> <span class="s2">"test message"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">MyApp</span><span class="o">::</span><span class="no">Foo</span><span class="p">.</span><span class="nf">hello</span>
</code></pre></div></div>
<p>When you run it, everything is as usual:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">I, [2013-05-11T21:26:40.701590 #</span>4326] INFO <span class="nt">--</span> : <span class="nb">test </span>message
</code></pre></div></div>
<p>Now imagine you have a ton of such messages flooding the output. Wouldn’t be
nice if the logger would also include the filename, the line and the function
name where the Log output was issued? Well, you can do that in ruby:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s1">'logger'</span>
<span class="k">module</span> <span class="nn">MyApp</span>
<span class="no">Log</span> <span class="o">=</span> <span class="no">Logger</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="no">STDOUT</span><span class="p">)</span>
<span class="no">Log</span><span class="p">.</span><span class="nf">formatter</span> <span class="o">=</span> <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">severity</span><span class="p">,</span> <span class="n">datetime</span><span class="p">,</span> <span class="n">progname</span><span class="p">,</span> <span class="n">msg</span><span class="o">|</span>
<span class="s2">"</span><span class="si">#{</span><span class="n">severity</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="nb">caller</span><span class="p">[</span><span class="mi">4</span><span class="p">]</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">msg</span><span class="si">}</span><span class="se">\n</span><span class="s2">"</span>
<span class="p">}</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">hello</span>
<span class="no">Log</span><span class="p">.</span><span class="nf">info</span> <span class="s2">"test message"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">MyApp</span><span class="o">::</span><span class="no">Foo</span><span class="p">.</span><span class="nf">hello</span>
</code></pre></div></div>
<p>If we will run this, we’ll see the following output:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="go">INFO log_test.rb:14:in `hello': test message
</span></code></pre></div></div>
<h1 id="how-it-is-done">How it is done</h1>
<p>Ruby has a magic array - <code class="language-plaintext highlighter-rouge">caller</code>. It contains the ordered list of the files, lines,
and functions being executed.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">baz</span>
<span class="n">hello</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">hello</span>
<span class="nb">p</span> <span class="nb">caller</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Foo</span><span class="p">.</span><span class="nf">baz</span> <span class="c1">#=> ["/home/andrei/Temp/log_test.rb:21:in `baz'", "/home/andrei/Temp/log_test.rb:29:in `<main>'"]</span>
</code></pre></div></div>
<p>We used that magic array for our logger formatter, and we used its 4th element
because the code which calls the logger is 4 levels above in call stack relative
to formatter proc.</p>
<p><strong>Note</strong>: If you use a different version of logger, you might need to use a
different number, not 4. In any case, inspect the caller array and see at which
position in that array your code info is located.</p>Andrei Lisnicandrei.lisnic@gmail.comSuppose you have a app with a logger:Unity performance tweaks2013-03-20T00:00:00+00:002013-03-20T00:00:00+00:00https://alisnic.github.io/posts/unity-fly<p><strong>Prerequisites:</strong>
You want to use unity, we let the unity flame wars aside, and you don’t want to
use <a href="https://www.google.com/search?q=unity+llvmpipe">LLVMpipe</a>.</p>
<ol>
<li>Remove useless lens</li>
</ol>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get autoremove unity-lens-videos unity-lens-photos <span class="se">\</span>
unity-lens-gwibber unity-lens-shopping unity-lens-music
</code></pre></div></div>
<ol>
<li>Install compiz config</li>
</ol>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">sudo </span>apt-get <span class="nb">install </span>compizconfig-settings-manager
</code></pre></div></div>
<ol>
<li>Open <code class="language-plaintext highlighter-rouge">compizconfig-settings-manager</code></li>
<li>Uncheck “Animations” and “Fade windows”</li>
<li>Open “OpenGL”, and set the texture filter to “Fast”</li>
<li>Enjoy</li>
</ol>Andrei Lisnicandrei.lisnic@gmail.comPrerequisites: You want to use unity, we let the unity flame wars aside, and you don’t want to use LLVMpipe.Vim hotkey to run current file depending on the filetype2013-03-11T00:00:00+00:002013-03-11T00:00:00+00:00https://alisnic.github.io/posts/vim-run-hotkey<p>So, here’s the thing, you’re editing a file and you need to run it. And, since
you are in vim, you might want to be clever and do something like
<code class="language-plaintext highlighter-rouge">:map <F5> :!ruby %<cr></code> on the fly. But, you can’t ever be clever enough in vim.</p>
<p><a href="http://vimdoc.sourceforge.net/htmldoc/autocmd.html">Autocmd</a> is a feature of vim which allows to execute a command when an
event occurs. In our context, we need vim to map a key to execute the current
file in ruby if it is a ruby script. All we need is to add the following statement
to <code class="language-plaintext highlighter-rouge">.vimrc</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>autocmd FileType ruby nmap <F5> :!ruby %<cr>
</code></pre></div></div>
<p>This means that when the “FileType” variable in vim will be set to ruby, the
key <code class="language-plaintext highlighter-rouge">F5</code> will be mapped to run current file with ruby. This is very convenient
because usually that variable is set by syntax detectors.</p>
<p>Then, we can extend this and add new file types:</p>
<div class="language-vim highlighter-rouge"><div class="highlight"><pre class="highlight"><code>autocmd <span class="nb">FileType</span> <span class="k">ruby</span> nmap <span class="p"><</span>F5<span class="p">></span> <span class="p">:!</span><span class="k">ruby</span> %<span class="p"><</span><span class="k">cr</span><span class="p">></span>
autocmd <span class="nb">FileType</span> coffee nmap <span class="p"><</span>F5<span class="p">></span> <span class="p">:!</span>coffee %<span class="p"><</span><span class="k">cr</span><span class="p">></span>
</code></pre></div></div>
<p>Neat, huh? Based on the file type, vim will execute the current file in the
corresponding interpreter.</p>
<h3 id="taking-it-a-bit-further">Taking it a bit further</h3>
<p>Also, it would be nice to save the file each time you want to run it, and also
measure the time it took to run. For that, you will need a function:</p>
<div class="language-vim highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">function</span> RunWith <span class="p">(</span>command<span class="p">)</span>
<span class="nb">execute</span> <span class="s2">"w"</span>
<span class="nb">execute</span> <span class="s2">"!clear;time "</span> <span class="p">.</span> <span class="nv">a:command</span> <span class="p">.</span> <span class="s2">" "</span> <span class="p">.</span> <span class="nb">expand</span><span class="p">(</span><span class="s2">"%"</span><span class="p">)</span>
<span class="k">endfunction</span>
autocmd <span class="nb">FileType</span> coffee nmap <span class="p"><</span>F5<span class="p">></span> <span class="p">:</span><span class="k">call</span> RunWith<span class="p">(</span><span class="s2">"coffee"</span><span class="p">)<</span><span class="k">cr</span><span class="p">></span>
autocmd <span class="nb">FileType</span> <span class="k">ruby</span> nmap <span class="p"><</span>F5<span class="p">></span> <span class="p">:</span><span class="k">call</span> RunWith<span class="p">(</span><span class="s2">"ruby"</span><span class="p">)<</span><span class="k">cr</span><span class="p">></span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">RunWith</code> is a function which accepts the executable name which will be used to
execute the current file. It will save the file before executing it, and will
clear the console screen.</p>
<p><strong>Pro tip:</strong> auto map a rspec run hotkey.</p>
<div class="language-vim highlighter-rouge"><div class="highlight"><pre class="highlight"><code>autocmd <span class="nb">BufRead</span> *_spec<span class="p">.</span>rb nmap <span class="p"><</span>F6<span class="p">></span> <span class="p">:</span><span class="k">w</span>\<span class="p">|!</span>clear && rspec % <span class="p">--</span>format documentation <span class="p">--</span>color<span class="p"><</span><span class="k">cr</span><span class="p">></span>
</code></pre></div></div>
<p>(each time a file with <code class="language-plaintext highlighter-rouge">_spec.rb</code> is loaded, the editor will map the <code class="language-plaintext highlighter-rouge">F6</code> key
to execute the rspec on the current file)</p>Andrei Lisnicandrei.lisnic@gmail.comSo, here’s the thing, you’re editing a file and you need to run it. And, since you are in vim, you might want to be clever and do something like :map <F5> :!ruby %<cr> on the fly. But, you can’t ever be clever enough in vim.Fast Rails app prototyping2013-01-23T00:00:00+00:002013-01-23T00:00:00+00:00https://alisnic.github.io/posts/rails-prototyping<p>There are often times when you have an idea that will refuse to leave your mind.
It is the most beautiful sensation you can ever have.
As an any other idea, you must first see it shape before you can throw it away.
At this point it is the most important to establish a very effective and noise free channel between your idea and its implementation.
I will describe what I use and what I do to quickly make small Rails apps, and what I use for it.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git clone git@github.com:alisnic/naked_rail.git myapp
cd myapp
rm -rf .git
git init && git add . && git commit -a -m "initial commit"
</code></pre></div></div>
<h1 id="prototyping">Prototyping</h1>
<p>I use an <a href="https://github.com/alisnic/naked_rail">app template</a> for all my new apps. As many things that I created, it was done to write less, and includes the following libs:</p>
<ul>
<li><a href="http://haml.info/">HAML</a> + <a href="http://sass-lang.com/">SASS</a> + <a href="http://coffeescript.org/">CoffeeScript</a></li>
<li><a href="http://twitter.github.com/bootstrap/">Twitter Bootstrap</a></li>
<li>PagesController which renders its action. To add a view, all I need to do is to create a <code class="language-plaintext highlighter-rouge">foo.haml</code> file in <code class="language-plaintext highlighter-rouge">app/views/pages</code>, and it will be accessible at <code class="language-plaintext highlighter-rouge">/pages/foo</code>. No new routes, no new controllers. You first idea is static.</li>
<li><a href="https://github.com/guard/guard-livereload">guard-livereload</a>. I have a vim window alongside the browser on my FullHD monitor. Every time I change the code, the page reloads automatically. This is <strong>very</strong> convenient, especially when writing the markup.</li>
<li><a href="https://github.com/alisnic/naked_rail/blob/master/app/views/application/_flash_messages.html.haml">flash</a> and <a href="https://github.com/alisnic/naked_rail/blob/master/app/views/application/_validation_errors.html.haml">error</a> partials. To show a model validation errors in a form, all I have to do is add <code class="language-plaintext highlighter-rouge">render 'validation_errors', :resource => @entity</code></li>
<li><a href="https://github.com/charliesome/better_errors">better_errors</a>. Really cool gem, makes breaking things pleasant. It will open a ruby shell in the context of the error in the browser.</li>
</ul>
<h1 id="growing">Growing</h1>
<p>If my idea proved strong and stable, I have the tools to grow on the code I made in the prototyping step, and by that I mean I have all the testing tools I need:</p>
<ul>
<li><a href="http://rspec.info/">Rspec</a></li>
<li><a href="https://github.com/thoughtbot/capybara-webkit">Capybara-webkit</a> (can execute JS) + <a href="https://github.com/alisnic/naked_rail/blob/master/features/step_definitions/navigation_steps.rb">navigation steps</a></li>
<li><a href="https://github.com/thoughtbot/shoulda">Shoulda</a>. Testing models is plain easy and straightforward. The main idea - don’t test ActiveRecord, it has been tested for you. (ex: <code class="language-plaintext highlighter-rouge">it { should belong_to(:user) }</code>)</li>
<li><a href="https://github.com/thoughtbot/factory_girl">FactoryGirl</a></li>
</ul>
<h1 id="final-note">Final note</h1>
<p>I have presented a set of tools and practices to create a Rails app fast. As many other things out there, it is highly opinionated. Also, the repo which I created is not licensed in any way, so do whatever the hell to want to do with it.</p>Andrei Lisnicandrei.lisnic@gmail.comThere are often times when you have an idea that will refuse to leave your mind. It is the most beautiful sensation you can ever have. As an any other idea, you must first see it shape before you can throw it away. At this point it is the most important to establish a very effective and noise free channel between your idea and its implementation. I will describe what I use and what I do to quickly make small Rails apps, and what I use for it.If-less programming2012-12-28T00:00:00+00:002012-12-28T00:00:00+00:00https://alisnic.github.io/posts/ifless<p>I recently watched a Google tech talk called <a href="http://www.youtube.com/watch?v=4F72VULWFvc&feature=channel">“The Clean Code Talks – Inheritance, Polymorphism, & Testing”</a>, and I was amazed how <strong>Misko Hevery</strong> explained that (a lot of) ifs can be a smelly thing in a Object Oriented language.</p>
<p>Being fascinated by the idea, I decided to <a href="https://www.google.com/search?q=programming+without+ifs">google</a> it, and I was surprised that if-less programming is a pretty popular topic. I noticed <a href="http://stackoverflow.com/questions/1937362/can-you-write-any-algorithm-without-an-if-statement">a response to a stackoverflow</a> question which stated:</p>
<blockquote>
<p>An “if” statement is an abomination in an Object Oriented language.
Why? Well, an OO language is composed of classes, objects and methods, and an “if” statement is inescapably none of those. You can’t write “if” in an OO way. It shouldn’t exist. Conditional execution, like everything else, should be a method. A method of what? Boolean.</p>
</blockquote>
<p>Any Smalltalk-er knows about this thing, because there are no if statements in Smalltalk. In this language, the Boolean class has <code class="language-plaintext highlighter-rouge">ifTrue</code> and <code class="language-plaintext highlighter-rouge">ifFalse</code> methods, which accept blocks which will be executed depending on the value of the boolean expression. This feels at least, a bit weird and unclear to me, so I decided to investigate.</p>
<h1 id="the-reasons">The Reasons</h1>
<p>It is obvious that we can’t avoid conditionals, especially when comparing primitive data types. But most of the time it is not considered a good practice to use ifs in a Object-Oriented language. So what is really wrong with conditionals in a Object Oriented language?</p>
<h2 id="polymorphism">Polymorphism</h2>
<p>The main and most strong idea which I got from if-less programming is simple: If you use a lot of if statements, you’re doing polymorphism wrong. Here is a simple (and dumb) example:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Printer</span>
<span class="k">def</span> <span class="nf">print</span> <span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="k">case</span> <span class="n">file</span><span class="p">.</span><span class="nf">type</span>
<span class="k">when</span> <span class="ss">:docx</span>
<span class="n">print_office_word</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="k">when</span> <span class="ss">:pdf</span>
<span class="n">print_pdf</span><span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>Notice here that I used a <code class="language-plaintext highlighter-rouge">switch</code> statement, it’s basically the same as using ifs. But let’s concentrate on the example. Why this class is bad? Well, for several reasons.</p>
<h3 id="ctrl-c-ctrl-v">Ctrl-C, Ctrl-V</h3>
<p>If the behaviour in the described object is complex enough, this switch will pop up all over the place. Image you will add a new method to the <code class="language-plaintext highlighter-rouge">Printer</code> class:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">get_meta_info</span> <span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="c1"># gotta do that switch here</span>
<span class="c1"># good thing I have the clipboard</span>
<span class="k">end</span>
</code></pre></div></div>
<p>Besides the same <code class="language-plaintext highlighter-rouge">switch</code>, you will have to add methods to process each file type which your <code class="language-plaintext highlighter-rouge">Printer</code> knows about.</p>
<h3 id="extensibility">Extensibility</h3>
<p>It is very hard to extend code which has a lot of branches, because chances are that the difference in behaviour between these branches is pretty big.</p>
<h3 id="the-right-way">The right way</h3>
<p>To avoid unnecessary conditions and headaches, our <code class="language-plaintext highlighter-rouge">Printer</code> class should look like this:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Printer</span>
<span class="k">def</span> <span class="nf">print</span><span class="p">(</span><span class="n">file</span><span class="p">);</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">get_meta_info</span><span class="p">(</span><span class="n">file</span><span class="p">);</span> <span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">PdfPrinter</span> <span class="o"><</span> <span class="no">Printer</span>
<span class="k">def</span> <span class="nf">print</span> <span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="c1">#</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">get_meta_info</span> <span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="c1">#</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">MSWordPrinter</span> <span class="o"><</span> <span class="no">Printer</span>
<span class="k">def</span> <span class="nf">print</span> <span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="c1">#</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">get_meta_info</span> <span class="p">(</span><span class="n">file</span><span class="p">)</span>
<span class="c1">#</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<h2 id="language-features">Language features</h2>
<p>In a lot of cases, avoiding conditions is easy, because there are language constructs which can do the same thing. Most of the time these constructs are present for a important reason - it’s a better way to do things. Let’s look at several of them. I used Ruby in the examples, but this applicable to any good OO language.</p>
<h3 id="filter-data">Filter data</h3>
<p>Any decent OO languages has means to easily filter data, you don’t need ifs to do that:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># I slept during the functional classes</span>
<span class="n">collection</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span><span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">result</span> <span class="o"><<</span> <span class="n">item</span> <span class="k">if</span> <span class="n">item</span><span class="p">.</span><span class="nf">condition?</span> <span class="p">}</span>
</code></pre></div></div>
<p>A very stupid example, but it should make the point. What we should have used is:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">result</span> <span class="o">=</span> <span class="n">collection</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="o">&</span><span class="ss">:condition?</span><span class="p">)</span>
</code></pre></div></div>
<h3 id="processing-errors">Processing errors</h3>
<p>If you got a method which can fail, you might be tempted to do something like this:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">result</span> <span class="o">=</span> <span class="n">do_something</span><span class="p">()</span>
<span class="k">if</span> <span class="n">result</span> <span class="o">==</span> <span class="kp">nil</span>
<span class="c1">#something is wrong</span>
<span class="k">else</span>
<span class="c1">#process</span>
<span class="k">end</span>
</code></pre></div></div>
<p>It is better that you method raises errors in case something goes wrong. It improves readability, adds meaning, and describes what the system actually does:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">begin</span>
<span class="n">result</span> <span class="o">=</span> <span class="n">do_something</span><span class="p">()</span>
<span class="k">rescue</span> <span class="no">FileSystemError</span>
<span class="c1">#disk is full</span>
<span class="k">rescue</span> <span class="no">NetworkError</span>
<span class="c1">#no internet connection</span>
<span class="k">end</span>
</code></pre></div></div>
<h3 id="default-values">Default values</h3>
<p>You want to keep a default value for a variable unless it is assigned, you might want to do something like this:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">method</span> <span class="p">(</span><span class="n">object</span><span class="p">)</span>
<span class="k">if</span> <span class="n">object</span><span class="p">.</span><span class="nf">property</span>
<span class="n">param</span> <span class="o">=</span> <span class="n">object</span><span class="p">.</span><span class="nf">property</span>
<span class="k">else</span>
<span class="n">param</span> <span class="o">=</span> <span class="n">default_param</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p>You did repeat yourself, wrote 3 lines, what you should have written is:</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">method</span> <span class="p">(</span><span class="n">object</span><span class="p">)</span>
<span class="n">param</span> <span class="o">=</span> <span class="n">object</span><span class="p">.</span><span class="nf">property</span> <span class="o">||</span> <span class="n">default_param</span>
<span class="k">end</span>
</code></pre></div></div>
<h2 id="testing">Testing</h2>
<p>One of things which can suggest that things got to fishy in your implementation, is how hard is to test your objects. Classes with a lot of conditions require a lot of test cases and a lot of setup code. If your behaviour were properly isolated and subclassed, then your test would be very simple and with minimum setup code.</p>
<p>By having small, specific objects, each time you have to test a class, you are testing an aspect of you system, not a behaviour.</p>
<h1 id="conclusion">Conclusion</h1>
<p>The idea of if-less programming is very interesting and provokes to thought. As any other good idea, it should be not taken to extremes. Any language construct must be used when it is the more reasonable thing to do. I like the fact that the presence of if-s can indicate a bad OO design.</p>Andrei Lisnicandrei.lisnic@gmail.comI recently watched a Google tech talk called “The Clean Code Talks – Inheritance, Polymorphism, & Testing”, and I was amazed how Misko Hevery explained that (a lot of) ifs can be a smelly thing in a Object Oriented language.On logic in a Rails app2012-12-24T00:00:00+00:002012-12-24T00:00:00+00:00https://alisnic.github.io/posts/rails-logic<p>Recently, Grant Ammons wrote <a href="http://gammons.github.com/architecture/2012/12/22/where-the-logic-hides/">a nice article</a> about where logic should lie in a Rails app. I would like to complement his opinion, and probably add some real life arguments to it.</p>
<p>Grant extracted logic from the controller, and put it in a separate object, which I also do most of the time. However, a user named DHH (which probably is DHH) said:</p>
<blockquote>
<p>So all you’ve done here is extract the work of the controller action into a separate object. This adds needless indirection, makes the code base harder to follow, and is completely unnecessary.</p>
</blockquote>
<p>I strongly disagree, and I have good reasons for it.</p>
<p>You know what makes the code base hard to follow? Fat controllers with logic in them. I worked on a Rails app with Controllers of 800 lines of code, <strong>it. is. a. freaking. nightmare.</strong></p>
<h2 id="my-approach">My approach</h2>
<p>I look at Rails as web presentation layer, it makes my app work in the browser. This has some consequences to my codebase:</p>
<ul>
<li>data-only models (no logic should be in models)</li>
<li>logicless controllers (no logic should be there either)</li>
<li>anything else is in single-responsibility objects in <code class="language-plaintext highlighter-rouge">app/domain/</code></li>
</ul>
<p>You might think that this is a refactor pattern, and you are right. And you might say that this unnecessary to do from the start, and you may also be right. But the cost of creating a file and moving behaviour there is exactly 0, but the benefits are there from day 1.</p>
<h2 id="why-i-do-it">Why I do it</h2>
<h3 id="fast-tests">Fast tests</h3>
<p>The least I am coupled to Rails, the fastest my tests are. Currently, on a medium Rails project my tests run 2-3 seconds, where 90% of the time is wasted to boot rails and test models.</p>
<p>I don’t test my controllers, because they have no logic in them. My methods in controllers don’t have more than 4-5 lines of code.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">RatingsController</span> <span class="o"><</span> <span class="no">ApplicationController</span>
<span class="k">def</span> <span class="nf">create</span>
<span class="n">success</span> <span class="o">=</span> <span class="no">RatesBusiness</span><span class="p">.</span><span class="nf">add_rating</span><span class="p">(</span><span class="n">params</span><span class="p">[</span><span class="ss">:business_id</span><span class="p">],</span>
<span class="n">params</span><span class="p">[</span><span class="ss">:score</span><span class="p">],</span>
<span class="n">current_user</span><span class="p">)</span>
<span class="n">render</span> <span class="ss">json: </span><span class="p">{</span><span class="ss">success: </span><span class="n">success</span><span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">RatesBusiness</code> has some foursquare-related logic besides just creating a entry in the database. Using this approach, I have a <em>very</em> fast TDD flow, because most of the time I don’t need Rails to test my logic. (any dependency to models is stubbed, as any other external dependency).</p>
<p>Your controller only connects your logic to the web interface.</p>
<h3 id="code-and-forget">Code and forget</h3>
<p>If you have a well tested functionality that works, you don’t need see it in front of you when you code in your application. This is where single-responsibility objects kick in, I TDD them one time, I know about their existence and what their interface is, I will not ever see their code again.</p>
<h3 id="framework-agnostic">Framework agnostic</h3>
<p>When your app logic is not coupled with Rails, you do not depend on it, its version, or interface. Isolating some functionality to a service is a matter of moving some files around.</p>
<h3 id="reduced-stress-and-debug-times">Reduced stress and debug times</h3>
<p>Most of my classes fit in one screen, and have descriptive names as <code class="language-plaintext highlighter-rouge">CategorizesCampagins</code> or <code class="language-plaintext highlighter-rouge">FiltersBusinesses</code>, which makes debugging them very, very easy and pleasant. I don’t need to scroll the hell out of my screen to understand how an isolated piece of functionality works.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Rails is just a framework to make your app work on the web, don’t mix your logic with rails-y stuff. Your app domain should be defined anywhere besides Rails views, controllers, and models.</p>
<h2 id="inspiration">Inspiration</h2>
<p>First, and most influential person for me is <a href="https://twitter.com/garybernhardt">Gary Bernhardt</a> and his screencast series <a href="https://www.destroyallsoftware.com/screencasts">destroyallsoftware</a>. If you want to learn isolated testing - watch this guy, he is amazing. (He even test-drives bash scripts :D)</p>
<p><a href="http://blog.codeclimate.com/blog/2012/11/28/your-objects-the-unix-way/">Your objects the UNIX way</a>.</p>
<p>Also, my approach was influenced by <a href="http://www.youtube.com/watch?v=CGN4RFkhH2M">Hexagonal Rails</a> concept.</p>Andrei Lisnicandrei.lisnic@gmail.comRecently, Grant Ammons wrote a nice article about where logic should lie in a Rails app. I would like to complement his opinion, and probably add some real life arguments to it.Make it static2012-12-14T00:00:00+00:002012-12-14T00:00:00+00:00https://alisnic.github.io/posts/static<p>Finally, I made a static blog which actually works.</p>
<p>Thanks to <a href="http://zachholman.com/">Zach Holman</a> for <a href="http://zachholman.com/posts/left/">open sourcing his previous Jekyll blog</a>.</p>Andrei Lisnicandrei.lisnic@gmail.comFinally, I made a static blog which actually works.