tag:blog.bmonkeys.net,2005:/tag/ruby-on-railsSlog postsmonkey knowledge!2021-03-08T22:00:35Ztag:blog.bmonkeys.net,2005:Post/282021-03-07T00:00:00Z2021-03-08T22:00:35ZAdvanced HTML sanitizing using custom scrubbers<p>You probably have used Rails' sanitize method before. A common use case that I have seen is to simply restrict tags and attributes to a "safe" whitelist.</p>
<div class="highlight"><pre><span id="Yf4VaV4fE71a9RbC6A62esJfU24=-1"><span class="n">sanitize</span><span class="p">(</span><span class="n">content</span><span class="p">,</span>
</span><span id="Yf4VaV4fE71a9RbC6A62esJfU24=-2"> <span class="ss">tags</span><span class="p">:</span> <span class="sx">%w(strong strike em a img)</span><span class="p">,</span>
</span><span id="Yf4VaV4fE71a9RbC6A62esJfU24=-3"> <span class="ss">attributes</span><span class="p">:</span> <span class="sx">%w(src type href target)</span>
</span><span id="Yf4VaV4fE71a9RbC6A62esJfU24=-4"><span class="p">)</span>
</span></pre></div>
<p>This can go a long way but we wanted to allow iframes in our markdown powered posts/comments to allow for embedment of certain content (e.g. YouTube). You maybe also want to allow images (but make sure it's https only or proxy them) or autolink only certain protocols and/or domains.</p>
<h2 id="custom-scrubbers">Custom scrubbers</h2>
<p>An easy way to get powerful scrubbing capabilities is to create a custom scrubber class and pass it to the sanitize method.</p>
<div class="highlight"><pre><span id="C3KUXc2nTaIi3dKjnqTwk/S+88o=-1"><span class="n">sanitize</span><span class="p">(</span><span class="n">content</span><span class="p">,</span> <span class="ss">scrubber</span><span class="p">:</span> <span class="no">PostScrubber</span><span class="o">.</span><span class="n">new</span><span class="p">)</span>
</span></pre></div>
<p>Let's take a look at the scrubber class, we will subclass the <a href="https://github.com/rails/rails-html-sanitizer/blob/master/lib/rails/html/scrubbers.rb">default PermitScrubber</a> which already handles<br>
the aforementioned tag/attribute whitelist. We just have to define our whitelist again, we could pass them as options or we do higher-level options like <code>allow_embed</code> and build our list inside the class. If you don't define any tags (e.g. <code>@tags</code> is nil) Loofah's default whitelist will be used, same goes for <code>@attributes</code>.</p>
<div class="highlight"><pre><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-1"><span class="k">class</span> <span class="nc">EntryScrubber</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Html</span><span class="o">::</span><span class="no">PermitScrubber</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-2"> <span class="k">def</span> <span class="nf">initialize</span> <span class="n">opts</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-3"> <span class="k">super</span><span class="p">()</span> <span class="c1"># with parantheses we can use custom `opts' parameter</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-4"> <span class="nb">self</span><span class="o">.</span><span class="n">tags</span> <span class="o">=</span> <span class="sx">%w(strong strike em a img)</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-5"> <span class="nb">self</span><span class="o">.</span><span class="n">attributes</span> <span class="o">=</span> <span class="sx">%w(src href target type)</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-6">
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-7"> <span class="k">if</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:allow_embed</span><span class="o">]</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-8"> <span class="nb">self</span><span class="o">.</span><span class="n">tags</span> <span class="o"><<</span> <span class="s2">"iframe"</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-9"> <span class="nb">self</span><span class="o">.</span><span class="n">attributes</span> <span class="o">+=</span> <span class="sx">%w(allowfullscreen frameborder)</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-10"> <span class="k">end</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-11"> <span class="k">end</span>
</span><span id="qF1y67fAjmVZLiMaPHXpeVWr850=-12"><span class="k">end</span>
</span></pre></div>
<p>Scrubbers will iterate over all nodes in the document using Nokogiri (refer to <a href="https://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Node">Nokogiri docs</a> for more information on how to use the node elements). For our needs we can skip text nodes which is also the default behavior of PermitScrubber so you can omit this method. I thought I just mention it as you might want to skip more or less.</p>
<div class="highlight"><pre><span id="30XY3EcKzV6JmOl6mIeJU7++TKc=-1"><span class="k">class</span> <span class="nc">EntryScrubber</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Html</span><span class="o">::</span><span class="no">PermitScrubber</span>
</span><span id="30XY3EcKzV6JmOl6mIeJU7++TKc=-2"> <span class="c1"># [..]</span>
</span><span id="30XY3EcKzV6JmOl6mIeJU7++TKc=-3"> <span class="k">def</span> <span class="nf">skip_node?</span> <span class="n">node</span>
</span><span id="30XY3EcKzV6JmOl6mIeJU7++TKc=-4"> <span class="n">node</span><span class="o">.</span><span class="n">text?</span>
</span><span id="30XY3EcKzV6JmOl6mIeJU7++TKc=-5"> <span class="k">end</span>
</span><span id="30XY3EcKzV6JmOl6mIeJU7++TKc=-6"><span class="k">end</span>
</span></pre></div>
<h3 id="the-meat-sweet-scrubbing-bacon">The meat: sweet scrubbing bacon</h3>
<p>Additionally we can override certain methods for all of our scrubbing needs. I will focus on <code>keep_node?</code> / <code>allowed_node?</code> but if you are into attribute scrubbing also take a look at <code>scrub_attribute?</code> and <code>scrub_attributes</code> (there's also something for CSS declarations in style attributes).</p>
<p>It's simple: You get a node, return true/false to either keep or strip it (subtree is preserved).</p>
<p>I personally prefer to think of keeping nodes but the documentation suggests to overload <code>allowed_node?</code> instead of <code>keep_node?</code> but since we are using <code>super</code> anyway it doesn't really matter.</p>
<div class="highlight"><pre><span id="jHHVLThW93Iq16AeCOOiochS1FY=-1"><span class="k">class</span> <span class="nc">EntryScrubber</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Html</span><span class="o">::</span><span class="no">PermitScrubber</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-2"> <span class="c1"># [..]</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-3">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-4"> <span class="no">EMBED_WHITELIST</span> <span class="o">=</span> <span class="sx">%w(</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-5"><span class="sx"> youtube.com</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-6"><span class="sx"> player.vimeo.com</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-7"><span class="sx"> player.twitch.tv</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-8"><span class="sx"> )</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-9">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-10"> <span class="k">def</span> <span class="nf">keep_node?</span> <span class="n">node</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-11"> <span class="c1"># if super returns false we already want to scrub based on tag whitelist</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-12"> <span class="k">return</span> <span class="kp">false</span> <span class="k">unless</span> <span class="k">super</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-13">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-14"> <span class="c1"># let's restrict link protocols (only allow http/https/mailto)</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-15"> <span class="k">if</span> <span class="n">src</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">attributes</span><span class="o">[</span><span class="s2">"href"</span><span class="o">]&.</span><span class="n">value</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-16"> <span class="k">return</span> <span class="kp">false</span> <span class="k">unless</span> <span class="n">src</span> <span class="o">=~</span> <span class="sr">/\A(http(s)?:\/\/|mailto:)/i</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-17"> <span class="k">end</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-18">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-19"> <span class="c1"># check sources (img/iframe)</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-20"> <span class="k">if</span> <span class="n">src</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">attributes</span><span class="o">[</span><span class="s2">"src"</span><span class="o">]&.</span><span class="n">value</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-21"> <span class="c1"># only allow https (embedding http wouldnt fly on a secure site anyway)</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-22"> <span class="k">return</span> <span class="kp">false</span> <span class="k">unless</span> <span class="n">src</span> <span class="o">=~</span> <span class="sr">/\Ahttps:\/\//i</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-23">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-24"> <span class="c1"># additionally whitelist domains for iframes</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-25"> <span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s2">"iframe"</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-26"> <span class="k">begin</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-27"> <span class="n">uri</span> <span class="o">=</span> <span class="no">URI</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span><span class="n">src</span><span class="p">)</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-28">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-29"> <span class="k">return</span> <span class="kp">false</span> <span class="k">unless</span> <span class="no">EMBED_WHITELIST</span><span class="o">.</span><span class="n">include?</span><span class="p">(</span><span class="n">uri</span><span class="o">.</span><span class="n">host</span><span class="o">.</span><span class="n">to_s</span><span class="o">.</span><span class="n">downcase</span><span class="p">)</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-30"> <span class="k">rescue</span> <span class="no">URI</span><span class="o">::</span><span class="no">InvalidURIError</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-31"> <span class="c1"># invalid URI => scrub</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-32"> <span class="k">return</span> <span class="kp">false</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-33"> <span class="k">end</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-34"> <span class="k">end</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-35"> <span class="k">end</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-36">
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-37"> <span class="c1"># seems good, don't scrub</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-38"> <span class="kp">true</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-39"> <span class="k">end</span>
</span><span id="jHHVLThW93Iq16AeCOOiochS1FY=-40"><span class="k">end</span>
</span></pre></div>
<p>You could even go as far as to allow certain script tags (for real Twitter, a script embed can't be the ultimate solution).</p>
<h2 id="using-scrubbers-to-modify-document">Using scrubbers to modify document</h2>
<p>Since we have tree write abilities as a necessity for scrubbing we can also use a scrubber to modify the document. As an example, let's rewrite image sources to proxy them through <a href="https://github.com/willnorris/imageproxy">imageproxy</a></p>
<div class="highlight"><pre><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-1"><span class="k">class</span> <span class="nc">ImageproxyScrubber</span> <span class="o"><</span> <span class="no">Rails</span><span class="o">::</span><span class="no">Html</span><span class="o">::</span><span class="no">PermitScrubber</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-2"> <span class="k">def</span> <span class="nf">keep_node?</span> <span class="n">node</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-3"> <span class="k">if</span> <span class="n">node</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="s2">"img"</span> <span class="o">&&</span> <span class="n">src</span> <span class="o">=</span> <span class="n">node</span><span class="o">.</span><span class="n">attributes</span><span class="o">[</span><span class="s2">"src"</span><span class="o">]&.</span><span class="n">value</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-4"> <span class="n">node</span><span class="o">.</span><span class="n">attributes</span><span class="o">[</span><span class="s2">"src"</span><span class="o">].</span><span class="n">value</span> <span class="o">=</span> <span class="s2">"https://imageproxy.local/0x0/</span><span class="si">#{</span><span class="n">src</span><span class="si">}</span><span class="s2">"</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-5"> <span class="k">end</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-6">
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-7"> <span class="kp">true</span> <span class="c1"># keep everything as we just rewrite and scrub somewhere else</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-8"> <span class="k">end</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-9">
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-10"> <span class="k">def</span> <span class="nf">scrub_attribute?</span> <span class="n">node</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-11"> <span class="kp">false</span> <span class="c1"># keep everything as we just rewrite and scrub somewhere else</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-12"> <span class="k">end</span>
</span><span id="UuJSZQvESfIKD9v/TH4BZMqP0r0=-13"><span class="k">end</span>
</span></pre></div><div class="highlight"><pre><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-1"><span class="n">h</span> <span class="o">=</span> <span class="no">ApplicationController</span><span class="o">.</span><span class="n">helpers</span>
</span><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-2"><span class="n">h</span><span class="o">.</span><span class="n">sanitize</span><span class="p">(</span>
</span><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-3"> <span class="n">h</span><span class="o">.</span><span class="n">image_tag</span><span class="p">(</span><span class="s2">"https://i.imgur.com/yed5Zfk.gif"</span><span class="p">),</span>
</span><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-4"> <span class="ss">scrubber</span><span class="p">:</span> <span class="no">ImageproxyScrubber</span><span class="o">.</span><span class="n">new</span>
</span><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-5"><span class="p">)</span>
</span><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-6">
</span><span id="HE6TsRd5XoiaQk9iU/8y0kYUiCU=-7"><span class="c1"># => "<img src=\"https://imageproxy.local/0x0/https://i.imgur.com/yed5Zfk.gif\">"</span>
</span></pre></div>Sven Pachnittag:blog.bmonkeys.net,2005:Post/272019-01-22T00:00:00Z2021-03-07T11:40:56ZUsing reCAPTCHA v3 with Turbolinks<p>You might have noticed that calls to <code>grecaptcha.execute</code> will timeout after a turbolinks navigation.</p>
<p>The reason for this is simple, the badge is not in the DOM anymore. If you delete this element (.grecaptcha-badge) on the first load the same problem will occur.</p>
<p>The solution is rather simple but not really documented, it's hidden in the FAQ "The JavaScript API available for Invisible reCAPTCHA also works for v3."</p>
<h3 id="so-what-do-we-need-to-do">So what do we need to do?</h3>
<p>Unfortunately you will have to write some extra code in order to get this to work.</p>
<p>I assume your include looks something like this (but loading it via JS is the same deal)</p>
<div class="highlight"><pre><span id="0udGj/lR5nGXNhK6zD8/ivOscG0=-1"><span class="p"><</span><span class="nt">head</span><span class="p">></span>
</span><span id="0udGj/lR5nGXNhK6zD8/ivOscG0=-2"> ...
</span><span id="0udGj/lR5nGXNhK6zD8/ivOscG0=-3"> <span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">'https://www.google.com/recaptcha/api.js?render=MY_PUBLIC_SITEKEY'</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
</span><span id="0udGj/lR5nGXNhK6zD8/ivOscG0=-4"><span class="p"></</span><span class="nt">head</span><span class="p">></span>
</span></pre></div>
<p>Let's change it up a little:</p>
<ul>
<li>replace your sitekey with "explicit"</li>
<li>define a onload parameter referencing a globally available callback function</li>
</ul>
<div class="highlight"><pre><span id="fAM4whMuUeeFcd3AFOB1tOvO0uQ=-1"><span class="p"><</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">'https://www.google.com/recaptcha/api.js?render=explicit&onload=myCallback'</span><span class="p">></</span><span class="nt">script</span><span class="p">></span>
</span></pre></div>
<p>In your layout add something like this (it must be on all sites you can "turbolinks" to, it must have an uniq ID in order for turbolinks-permanent to work)</p>
<div class="highlight"><pre><span id="O+4KBl037moBYaWgIJHS6dmtOvk=-1"><span class="p"><</span><span class="nt">div</span> <span class="na">id</span><span class="o">=</span><span class="s">"my-grecaptcha-badge"</span> <span class="na">data-turbolinks-permanent</span><span class="p">></</span><span class="nt">div</span><span class="p">></span>
</span></pre></div>
<p>Then, in your callback function you will have to do two things:</p>
<ul>
<li>Explicitely render the badge to your div created in the previous step</li>
<li>Save the result of the render in a variable that persists on turbolinks navigations (e.g. window, document)</li>
</ul>
<div class="highlight"><pre><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-1"><span class="kd">function</span> <span class="nx">myCallback</span><span class="p">()</span> <span class="p">{</span>
</span><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-2"> <span class="nb">document</span><span class="p">.</span><span class="nx">grecaptchaHandle</span> <span class="o">=</span> <span class="nx">grecaptcha</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">'my-grecaptcha-badge'</span><span class="p">,</span> <span class="p">{</span>
</span><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-3"> <span class="s1">'sitekey'</span><span class="o">:</span> <span class="s1">'MY_PUBLIC_SITEKEY'</span><span class="p">,</span>
</span><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-4"> <span class="s1">'badge'</span><span class="o">:</span> <span class="s1">'inline'</span><span class="p">,</span> <span class="c1">// must be inline</span>
</span><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-5"> <span class="s1">'size'</span><span class="o">:</span> <span class="s1">'invisible'</span> <span class="c1">// must be invisible</span>
</span><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-6"> <span class="p">});</span>
</span><span id="PjeL4kd6BGuOcMah5B+T/92Pg48=-7"><span class="p">}</span>
</span></pre></div>
<p>Then all you need to do is to make sure that your <code>grecaptcha.execute</code> calls don't use the sitekey as first parameter but the result of the render call.</p>
<div class="highlight"><pre><span id="lIvGRVaCWlM+KKr9Cntvg/UenAY=-1"> <span class="nx">grecaptcha</span><span class="p">.</span><span class="nx">execute</span><span class="p">(</span><span class="nb">document</span><span class="p">.</span><span class="nx">grecaptchaHandle</span><span class="p">).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">token</span><span class="p">)</span> <span class="p">{</span>
</span><span id="lIvGRVaCWlM+KKr9Cntvg/UenAY=-2"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">"executed"</span><span class="p">,</span> <span class="nx">token</span><span class="p">)</span>
</span><span id="lIvGRVaCWlM+KKr9Cntvg/UenAY=-3"> <span class="p">}</span>
</span></pre></div>
<p>Voilà!</p>
<p>PS: If you want you can take a look at my AppOS module (internal framework but class should make sense nevertheless) for reCAPTCHA v3 (written in coffee) here: <a href="https://gist.github.com/2called-chaos/da02da3af297d4e39715ddfdd81ce7d4">https://gist.github.com/2called-chaos/da02da3af297d4e39715ddfdd81ce7d4</a></p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/262018-03-09T00:00:00Z2021-03-07T11:41:04ZYour server might be faster than you think if you have a Hetzner server<p>If you have a Hetzner server with one of the recent CPU types you might be running in powersave mode. This is because the new CPUs don't support ondemand anymore. Also, some revisions of the ubuntu server image contain a typo which might cause this problem even with an older CPU.</p>
<ol>
<li><p>Verify you are on powersave</p>
<ul>
<li><code>cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor</code></li>
</ul></li>
<li><p>Check if you already have:</p>
<ul>
<li>service: <code>sudo service cpufrequtils status</code></li>
<li>file: <code>file /etc/default/cpufrequtils</code></li>
</ul></li>
<li><p>Check available governors (it probably doesn't have ondemand if it's a newer (intel?) CPU)</p>
<ul>
<li><code>cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_governors</code></li>
</ul></li>
<li><p>Edit file /etc/default/cpufrequtils (it has typo and nonexistant governor)<br>
REPLACE: GOVENOR="ondemand"<br>
WITH: GOVERNOR="performance"</p></li>
<li><p>Disable ondemand service (it doesn't know about performance and will always set it to powersave)</p>
<ul>
<li><code>sudo service ondemand stop</code></li>
<li><code>sudo update-rc.d ondemand disable</code> or <code>systemctl disable ondemand</code></li>
</ul></li>
<li><p>Restart the service and verify after a few seconds</p>
<ul>
<li><code>sudo service cpufrequtils restart</code></li>
<li><code>sudo service cpufrequtils status</code></li>
<li><code>cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor</code></li>
</ul></li>
<li><p>Make sure it stays that way</p>
<ul>
<li>After upgrading the Ubuntu release the ondemand service was back at work.</li>
<li>Monitoring this value is recommended, I'm using <a href="https://github.com/2called-chaos/watchmonkey_cli/blob/master/lib/watchmonkey_cli/application/configuration.tpl#L182">my poor man monitoring</a></li>
</ul></li>
</ol>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/242014-11-23T00:00:00Z2014-11-23T00:26:49ZEdit remote files with Sublime Text (over SSH)<p>If you love vim (or emacs) mor than Sublime just stop reading right here!</p>
<p>Wouldn't it be nice to edit remote files with Sublime sometimes? Well you can! There are just 3 things to do!</p>
<h2 id="1-install-rsub-package">1. Install rsub package</h2>
<p>Fire up your Sublime and install the package called <code>rsub</code>. If you don't know what I'm talking about refer to <a href="https://sublime.wbond.net/docs/usage">Package Control - Usage</a>.</p>
<h2 id="2-forward-port-over-ssh">2. Forward port over SSH</h2>
<p>You could forward the port manually as well but we want it convenient, right?</p>
<p>Edit your local SSH config with <code>subl ~/.ssh/config</code> and add the following. Note that you can use a hostname instead of <code>*</code> but unless you have port collisions I see no reason to do it.</p>
<div class="highlight"><pre><span id="fRV8zlZpz9v+5eDgqJWZXeJsoNo=-1">Host *
</span><span id="fRV8zlZpz9v+5eDgqJWZXeJsoNo=-2"> RemoteForward <span class="m">52698</span> <span class="m">127</span>.0.0.1:52698
</span></pre></div>
<h2 id="3-install-rsub-script-on-all-servers">3. Install rsub script on all servers</h2>
<p>A little drop of bitterness here. The magic requires a little helper script on the remote side. I hope this isn't a showstopper, luckily it's just a bash script and is installed as easy as</p>
<div class="highlight"><pre><span id="AP7G5Rro837RLwknnUJXxXYE59I=-1">curl https://raw.githubusercontent.com/aurora/rmate/master/rmate > /usr/local/bin/rsub
</span><span id="AP7G5Rro837RLwknnUJXxXYE59I=-2">chmod +x /usr/local/bin/rsub
</span></pre></div>
<h2 id="4-have-fun">4. Have fun!</h2>
<p>Want to edit or show a remote file? Just type <code>rsub my-file.txt</code> into your remote SSH session and wait for the magic to open up the file right there in your local Sublime.</p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/212014-10-17T00:00:00Z2014-10-17T03:11:17ZBuild pwntcha on Ubuntu 14.04<p>I had to collect some information in order to build pwntcha and these steps should make it work for you as well!</p>
<h2 id="1-install-prerequisites">1. Install prerequisites</h2>
<div class="highlight"><pre><span id="DO6UZYGOi3ZPgq/OMsIeuEIstcY=-1">aptitude update
</span><span id="DO6UZYGOi3ZPgq/OMsIeuEIstcY=-2">aptitude install build-essential git automake1.9 libsdl1.2-dev libimlib2-dev
</span><span id="DO6UZYGOi3ZPgq/OMsIeuEIstcY=-3">
</span><span id="DO6UZYGOi3ZPgq/OMsIeuEIstcY=-4"><span class="c1"># Choose 1.9 from the list if there are alternatives</span>
</span><span id="DO6UZYGOi3ZPgq/OMsIeuEIstcY=-5">update-alternatives --config automake
</span></pre></div>
<h2 id="2-clone-pwntcha">2. Clone pwntcha</h2>
<div class="highlight"><pre><span id="1nAJtNN+tP/IY+T9pAGa+4k6yqY=-1"><span class="nb">cd</span> /usr/local/src
</span><span id="1nAJtNN+tP/IY+T9pAGa+4k6yqY=-2">git clone http://caca.zoy.org/git/pwntcha.git
</span><span id="1nAJtNN+tP/IY+T9pAGa+4k6yqY=-3"><span class="nb">cd</span> pwntcha
</span></pre></div>
<h2 id="3-run-configure">3. Run configure</h2>
<div class="highlight"><pre><span id="Z59COXUkMRi7TiKeI5bqAksLyLw=-1">./bootstrap
</span><span id="Z59COXUkMRi7TiKeI5bqAksLyLw=-2">./configure
</span></pre></div>
<h2 id="4-make-pwntcha">4. Make pwntcha</h2>
<p>This part is a bit weird but it works :)<br>
<strong><code>make</code> will fail</strong> the first time but it's okay, we can fix it!</p>
<div class="highlight"><pre><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-1"><span class="nb">cd</span> src
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-2">make
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-3">
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-4">g++ <span class="sb">`</span>imlib2-config --cflags<span class="sb">`</span> -Wall -O6 -g -O2 -o pwntcha pwntcha-main.o <span class="se">\</span>
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-5">pwntcha-filter.o pwntcha-font.o pwntcha-image.o pwntcha-easter-eggs.o <span class="se">\</span>
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-6">pwntcha-test.o authimage/libdecoder.a clubic/libdecoder.a java/libdecoder.a <span class="se">\</span>
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-7">linuxfr/libdecoder.a livejournal/libdecoder.a lmt/libdecoder.a paypal/libdecoder.a <span class="se">\</span>
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-8">phpbb/libdecoder.a scode/libdecoder.a slashdot/libdecoder.a <span class="se">\</span>
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-9">ticketmaster/libdecoder.a tickets/libdecoder.a vbulletin/libdecoder.a <span class="se">\</span>
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-10">xanga/libdecoder.a <span class="sb">`</span>imlib2-config --libs<span class="sb">`</span> -lImlib2
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-11">
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-12">make
</span><span id="t2/cqXLHEQQLu3hkGQGyx+DGYGY=-13">make install
</span></pre></div>
<p><strong>Done!</strong></p>
<p>You can now use pwntcha like this (you need to specify the share directory)</p>
<div class="highlight"><pre><span id="3sMHi3xzS0ME4CRNIDAhxFllLV0=-1">pwntcha -s /usr/local/src/pwntcha/src/ my_image.jpg
</span><span id="3sMHi3xzS0ME4CRNIDAhxFllLV0=-2">
</span><span id="3sMHi3xzS0ME4CRNIDAhxFllLV0=-3"><span class="c1"># I aliased it</span>
</span><span id="3sMHi3xzS0ME4CRNIDAhxFllLV0=-4"><span class="nb">alias</span> <span class="nv">pwntcha</span><span class="o">=</span><span class="s1">'pwntcha -s /usr/local/src/pwntcha/src/'</span>
</span></pre></div>
<p><hr></p>
<p>Thanks to:</p>
<ul>
<li><a href="http://www.question-defense.com/2013/01/06/error-compiling-pwntcha-on-backtrack-linux-image-c285-error-error-no-imaging-library">http://www.question-defense.com/2013/01/06/error-compiling-pwntcha-on-backtrack-linux-image-c285-error-error-no-imaging-library</a></li>
<li><a href="https://github.com/iveney/pwntcha/issues/8">https://github.com/iveney/pwntcha/issues/8</a></li>
<li><a href="http://stackoverflow.com/questions/17433922/pwntcha-build-error-in-cygwin-undefined-reference-to-imlib-load-image">http://stackoverflow.com/questions/17433922/pwntcha-build-error-in-cygwin-undefined-reference-to-imlib-load-image</a></li>
<li><a href="http://hactheplanet.com/blog/132#comment-518">http://hactheplanet.com/blog/132#comment-518</a></li>
</ul>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/202014-09-26T00:00:00Z2014-09-27T01:52:24ZUTF-8 multibyte characters in Mac OS X filenames<p>I did a little CLI tool which listed files in a directory plus a few extra information in an ASCII table. To calculate it I need the longest filename and I had issues when UTF-8 multibyte characters were in them: The special characters were counted as two characters.</p>
<p>The issue here is that OS X use a slightly different UTF-8 than you would think. Look at this:</p>
<div class="highlight"><pre><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-1"><span class="o">[</span><span class="mi">1</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span> <span class="o">=</span> <span class="no">File</span><span class="o">.</span><span class="n">basename</span><span class="p">(</span><span class="no">Dir</span><span class="o">[</span><span class="s2">"Desktop/*"</span><span class="o">][</span><span class="mi">2</span><span class="o">]</span><span class="p">)</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-2"><span class="o">=></span> <span class="s2">"möp"</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-3">
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-4"><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span><span class="o">.</span><span class="n">length</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-5"><span class="o">=></span> <span class="mi">4</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-6">
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-7"><span class="o">[</span><span class="mi">3</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="s2">"möp"</span><span class="o">.</span><span class="n">length</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-8"><span class="o">=></span> <span class="mi">3</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-9">
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-10"><span class="o">[</span><span class="mi">4</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span><span class="o">.</span><span class="n">encoding</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-11"><span class="o">=></span> <span class="c1">#<Encoding:UTF-8></span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-12">
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-13"><span class="o">[</span><span class="mi">5</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="s2">"möp"</span><span class="o">.</span><span class="n">encoding</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-14"><span class="o">=></span> <span class="c1">#<Encoding:UTF-8></span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-15">
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-16"><span class="o">[</span><span class="mi">6</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span> <span class="o">==</span> <span class="s2">"möp"</span>
</span><span id="K1MKdzzpZJIi/PBvqBLjKmVJj+4=-17"><span class="o">=></span> <span class="kp">false</span>
</span></pre></div>
<p>At this point I was confused. It looked the same, it had the same encoding still it's not the same (and longer). So what's the trick here? Encode the path to <code>UTF-8-MAC</code> and everything is fine:</p>
<div class="highlight"><pre><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-1"><span class="o">[</span><span class="mi">7</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'UTF-8'</span><span class="p">,</span> <span class="s1">'UTF-8-MAC'</span><span class="p">)</span><span class="o">.</span><span class="n">length</span>
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-2"><span class="o">=></span> <span class="mi">3</span>
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-3">
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-4"><span class="o">[</span><span class="mi">8</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'UTF-8'</span><span class="p">,</span> <span class="s1">'UTF-8-MAC'</span><span class="p">)</span>
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-5"><span class="o">=></span> <span class="s2">"möp"</span>
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-6">
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-7"><span class="o">[</span><span class="mi">9</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">str</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'UTF-8'</span><span class="p">,</span> <span class="s1">'UTF-8-MAC'</span><span class="p">)</span> <span class="o">==</span> <span class="s2">"möp"</span>
</span><span id="godIOd63rDW4tf0ea3nAKCQ7Bd4=-8"><span class="o">=></span> <span class="kp">true</span>
</span></pre></div>Sven Pachnittag:blog.bmonkeys.net,2005:Post/192014-03-27T00:00:00Z2014-12-14T21:55:57ZHow I debug<p>Debugging is an ability every developer should have learned. It can be quite tricky to understand certain edge cases and sometime you have to think <a href="http://stackoverflow.com/questions/3282373/web-site-exhibits-javascript-error-on-ipad-iphone-under-3g-but-not-under-wifi">outside of the <del>box</del> provider</a>…</p>
<p>Especially with Ruby it can be quite confusing which method you actually call since there is inheritance, monkey patching, dynamic method definition, the evil but omnipresent <code>method_missing</code> and (possibly also dynamically) included modules.</p>
<p>The rails console which is a rather simple <a href="http://en.wikipedia.org/wiki/Read-eval-print_loop">REPL</a> called <a href="http://en.wikipedia.org/wiki/Interactive_Ruby_Shell">IRB</a> will help you a lot when it comes to play around with your code to <strong>reproduce</strong>, <strong>locate</strong> and <strong>understand</strong> bugs. And if you like IRB you will love <a href="http://pryrepl.org">Pry</a>! Just check the <a href="https://github.com/pry/pry/wiki">Wiki</a> or this <a href="http://banisterfiend.wordpress.com/2011/01/27/turning-irb-on-its-head-with-pry/">brief overview</a>. Or just install it, run it and type <code>help</code>. You might also want to read <a href="http://blog.bmonkeys.net/2014/monkey-devkit-a-collection-of-development-gems">A collection of development gems</a>.</p>
<p>Since we're all using Pry now let's get to the tips!</p>
<h3 id="so-what-do-we-have-here">So what do we have here…?</h3>
<p>First we need accessors to all the methods and variables an object has. These should be the most interesting ones:</p>
<div class="highlight"><pre><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-1"><span class="c1"># Returns array of instance methods for the given class.</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-2"><span class="no">User</span><span class="o">.</span><span class="n">instance_methods</span> <span class="c1"># => [:nil?, :===, :=~, :!~, :eql?, …]</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-3"><span class="vi">@user</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">instance_methods</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-4">
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-5"><span class="c1"># If you only want the methods of this particular class</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-6"><span class="c1"># (without inherited methods) pass false:</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-7"><span class="no">User</span><span class="o">.</span><span class="n">instance_methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-8">
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-9"><span class="c1"># To get a list of defined instance variables</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-10"><span class="vi">@user</span><span class="o">.</span><span class="n">instance_variables</span> <span class="c1"># => [:@name]</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-11">
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-12"><span class="c1"># To get the actual value of the variable (if there is no getter method)</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-13"><span class="vi">@user</span><span class="o">.</span><span class="n">instance_variable_get</span><span class="p">(</span><span class="ss">:@name</span><span class="p">)</span> <span class="c1"># => "Horst"</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-14">
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-15"><span class="c1"># With Pry you could also "cd" into the object:</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-16"><span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">cd</span> <span class="vi">@user</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-17"><span class="n">pry</span><span class="p">(</span><span class="c1">#<User>):1> @name</span>
</span><span id="/hMebZ8FqEbgXQWlARuD9Cbym6o=-18"><span class="o">=></span> <span class="s2">"Horst"</span>
</span></pre></div>
<p>Since you can define methods on individual instances the <code>object.class.instance_methods</code> might not yield correct results. Fortunately you can ask an object for a list of it's <code>#methods</code>:</p>
<div class="highlight"><pre><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-1"><span class="nv">foo</span> <span class="o">=</span> {}
</span><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-2"><span class="nv">def</span> <span class="nv">foo</span>.<span class="nv">bar</span>?
</span><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-3"> <span class="s2">"</span><span class="s">sure it's bar, what else should it be?</span><span class="s2">"</span>
</span><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-4"><span class="k">end</span>
</span><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-5">
</span><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-6"><span class="nv">Hash</span>.<span class="nv">instance_methods</span>.<span class="nv">grep</span> <span class="o">/^</span><span class="nv">bar</span><span class="o">/</span> # <span class="o">=></span> []
</span><span id="xELsbupyhb5HTC1R5ErA5/VhzdE=-7"><span class="nv">foo</span>.<span class="nv">methods</span>.<span class="nv">grep</span> <span class="o">/^</span><span class="nv">bar</span><span class="o">/</span> # <span class="o">=></span> [:<span class="nv">bar</span>?]
</span></pre></div>
<h3 id="dont-forget-about-grep">Don't forget about grep!</h3>
<p>You've seen it in the last tip, the <a href="http://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-grep">Enumerable#grep</a> method can be very handy when dealing with large arrays. Here are some examples for method lists:</p>
<div class="highlight"><pre><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-1"># <span class="k">Show</span> <span class="nv">all</span> <span class="nv">methods</span> <span class="nv">ending</span> <span class="nv">with</span> <span class="nv">a</span> <span class="nv">question</span> <span class="nv">mark</span> <span class="ss">(</span><span class="nv">they</span> <span class="nv">can</span> <span class="nv">only</span> <span class="nv">occur</span> <span class="nv">at</span> <span class="nv">the</span> <span class="k">end</span><span class="ss">)</span>
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-2"><span class="nv">User</span>.<span class="nv">instance_methods</span>.<span class="nv">grep</span> <span class="o">/</span>\?<span class="o">/</span>
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-3">
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-4"># <span class="nv">Same</span> <span class="nv">goes</span> <span class="k">for</span> <span class="nv">bang</span> <span class="nv">methods</span>
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-5"><span class="nv">User</span>.<span class="nv">instance_methods</span>.<span class="nv">grep</span> <span class="o">/!/</span>
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-6">
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-7"># <span class="k">Show</span> <span class="nv">the</span> <span class="nv">common</span> <span class="nv">to_</span> <span class="nv">casting</span> <span class="nv">methods</span>
</span><span id="8be6CHeUritV7xh0c5ESRCPsxRo=-8"><span class="nv">User</span>.<span class="nv">instance_methods</span>.<span class="nv">grep</span> <span class="o">/^</span><span class="nv">to_</span><span class="o">/</span>
</span></pre></div>
<h3 id="which-method-do-i-really-call">Which method do I really call?</h3>
<p>Due to the nature of Ruby to be very flexible you sometimes can't really tell which method you will actually call. But fortunately Ruby knows it:</p>
<div class="highlight"><pre><span id="b8Kg6dMYc7GRtMDnPQljSupJ9rE=-1"><span class="vi">@user</span><span class="o">.</span><span class="n">method</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span> <span class="c1"># => #<Method: User#name></span>
</span><span id="b8Kg6dMYc7GRtMDnPQljSupJ9rE=-2"><span class="vi">@user</span><span class="o">.</span><span class="n">method</span><span class="p">(</span><span class="ss">:puts</span><span class="p">)</span> <span class="c1"># => #<Method: User(Kernel)#puts></span>
</span></pre></div>
<p>It also keeps track of where the methods came from:</p>
<div class="highlight"><pre><span id="h2duYaKF2vDmlHle59qDvAxAY/k=-1"><span class="vi">@user</span><span class="o">.</span><span class="n">method</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span><span class="o">.</span><span class="n">source_location</span> <span class="c1"># => ["test.rb", 4]</span>
</span><span id="h2duYaKF2vDmlHle59qDvAxAY/k=-2">
</span><span id="h2duYaKF2vDmlHle59qDvAxAY/k=-3"><span class="c1"># Doesn't work with methods implemented in C</span>
</span><span id="h2duYaKF2vDmlHle59qDvAxAY/k=-4"><span class="vi">@user</span><span class="o">.</span><span class="n">method</span><span class="p">(</span><span class="ss">:puts</span><span class="p">)</span><span class="o">.</span><span class="n">source_location</span> <span class="c1"># => nil</span>
</span></pre></div>
<p>Note that the filename will sometimes be relative to the current directory of your ruby process (usually from where you've called the script) but in the case of Rails you propably will get the full path.</p>
<p>With Pry at your hand you can even show the method definition, in this case it will reveal that this method was dynamically defined through <code>attr_accessor</code>.</p>
<div class="highlight"><pre><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-1"><span class="o">[</span><span class="mi">2</span><span class="o">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">show</span><span class="o">-</span><span class="nb">method</span> <span class="vi">@user</span><span class="o">.</span><span class="n">name</span>
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-2">
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-3"><span class="ss">From</span><span class="p">:</span> <span class="nb">test</span><span class="o">.</span><span class="n">rb</span> <span class="err">@</span> <span class="n">line</span> <span class="mi">4</span><span class="p">:</span>
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-4"><span class="ss">Owner</span><span class="p">:</span> <span class="no">User</span>
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-5"><span class="ss">Visibility</span><span class="p">:</span> <span class="kp">public</span>
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-6"><span class="no">Number</span> <span class="n">of</span> <span class="ss">lines</span><span class="p">:</span> <span class="mi">1</span>
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-7">
</span><span id="SeluTplC18Cue8fC6XM6jGXVGiI=-8"><span class="kp">attr_accessor</span> <span class="ss">:name</span>
</span></pre></div>
<div class="pull-right" style="padding: 0 0 8px 8px">
<img src="/attach/b3e48883c49e43f0360e362ba2f6cb62/original_test-rb-2014-03-27-03-37-31-2014-03-27-03-44-24.png" alt="Sublime Text">
</div>
<p>If you've defined your favorite text editor you can directly jump to the file and line by using the edit command:</p>
<div class="highlight"><pre><span id="rgoRBzGRo4FOJM1F6hbsIxXMsfw=-1"><span class="n">edit</span> <span class="vi">@user</span><span class="o">.</span><span class="n">name</span>
</span></pre></div>
<h3 id="use-tests">Use tests</h3>
<p>When you can, add one or better multiple failing tests. This not only helps you finding the error it also helps you to prevent this error from happening again in future code updates.</p>
<h3 id="os-x-only-let-your-code-talk">OS X only: Let your code talk</h3>
<p>This is a rather odd one. Sometimes I don't really want breakpoints, I just want to know in which order callbacks are called or how the code flows. On Mac OS X there is a build-in terminal command <code>say</code> which reads text you pass as an argument.</p>
<p>So when I'm sitting there late at night, trying to figuring something out and my eyes need a short break I tend to add some of these lines instead of using text ouput (which is hard to spot in the rails log):</p>
<div class="highlight"><pre><span id="/4hy1z2FpzOuYXb2l6WbfySaq74=-1"><span class="sb">`say Processing item </span><span class="si">#{</span><span class="n">item</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="sb">`</span>
</span><span id="/4hy1z2FpzOuYXb2l6WbfySaq74=-2"><span class="sb">`say Found </span><span class="si">#{</span><span class="n">matches</span><span class="o">.</span><span class="n">count</span><span class="si">}</span><span class="sb"> matches`</span>
</span><span id="/4hy1z2FpzOuYXb2l6WbfySaq74=-3"><span class="n">before_filter</span> <span class="p">{</span> <span class="sb">`say You should go to bed now`</span> <span class="p">}</span>
</span></pre></div>
<h3 id="generally">Generally…</h3>
<p>…for those who are struggling with debugging in general:</p>
<p><strong>Reproduce</strong> the problem. In the best case you would have a consistently failing test. But bugs can be more nasty than that. If you're lucky you can sporadically trigger the error but sometimes it just flashes up randomly on your bug tracker and you have no clue whatsoever. You need to narrow it down and inspect every little detail in the suspected part of your code. Even if it appears totally plausible, double check it. Don't forget the "out of the box" thing. Let others take a look, maybe they will spot it at a glance.</p>
<p><strong>Understand</strong> the problem. If you can reproduce the problem it is usually easy to imagine possible reasons for it. You can also try to find the error by revisiting and rethinking the code but this can get complicated.</p>
<p><strong>Locate</strong> the problem and fix it. Sometimes you will need a workaround to fix things especially if the problem originates from outside your control. Hopefully the tips in this article will help you with this step.</p>
<hr>
<p>Do you have special tricks or techniques when dealing with bugs? Let us know!</p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/182014-03-16T00:00:00Z2016-11-19T12:24:40ZBe careful with params.merge()<p><a href="https://github.com/search?q=link_to+params.merge&ref=cmdform&type=Code">I've seen a lot of people</a> doing it and I used to do it too, use <code>params.merge(…)</code> in link_to or redirect_to calls. You do this because you want to change one ore more parameters (like the locale, current page or search query) but leave the rest as it is.</p>
<p>But heads up! There is an issue with this solution:</p>
<div class="highlight"><pre><span id="U6HENRaA4TKGZWhhyRgNzxJeqmQ=-1"><span class="n">link_to</span><span class="p">(</span><span class="s2">"Page 2"</span><span class="p">,</span> <span class="n">params</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">page</span><span class="p">:</span> <span class="mi">2</span><span class="p">))</span> <span class="c1"># /users?page=2</span>
</span><span id="U6HENRaA4TKGZWhhyRgNzxJeqmQ=-2"><span class="n">link_to</span><span class="p">(</span><span class="s2">"parlez vous français?"</span><span class="p">,</span> <span class="n">params</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">locale</span><span class="p">:</span> <span class="s2">"fr"</span><span class="p">))</span> <span class="c1"># /fr/about</span>
</span></pre></div>
<p>What do you think would this request url do to the second link? Hint: You won't get a french customer anymore :)</p>
<div class="highlight"><pre><span id="l9qYytn+VzxQyArVORD09YlwfgY=-1">http://localhost:3000/en/about?%68%6f%73%74=%77%77%77%2e%35%30%72%65%61%73%6f%6e%73%74%6f%68%61%74%65%74%68%65%66%72%65%6e%63%68%2e%63%6f%6d%2f%23&%70%6f%72%74=%38%30
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-2">
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-3">equals
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-4">
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-5">http://localhost:3000/en/about?host=www.50reasonstohatethefrench.com/%23&port=80
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-6">
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-7">which results in you link target being
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-8">
</span><span id="l9qYytn+VzxQyArVORD09YlwfgY=-9">http://www.50reasonstohatethefrench.com/#/fr/about
</span></pre></div>
<p>There is also <code>protocol</code> you could tamper with. So if you have french customers you might want to know how to get out of this misery.</p>
<p>Usually it is the best to explicitly define which parameters you want and strip the others away but in some cases it is really annoying or just impossible. You should be on the safe side if you pass <code>only_path: true</code> to the url_for method. This will ensure that you just get the path instead of the full URL. The three parameters protocol, host and port are getting stripped away entirely.</p>
<div class="highlight"><pre><span id="jX0b48NJegWQah5GR/Ind2CkTQw=-1"><span class="n">link_to</span><span class="p">(</span><span class="s2">"parlez vous français?"</span><span class="p">,</span> <span class="n">params</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">locale</span><span class="p">:</span> <span class="s2">"fr"</span><span class="p">,</span> <span class="ss">only_path</span><span class="p">:</span> <span class="kp">true</span><span class="p">))</span> <span class="c1"># /fr/about</span>
</span></pre></div>
<p>This can get a bit cumbersome so if you need this multiple times you might want to add this to your application controller:</p>
<div class="highlight"><pre><span id="84rvM+YRXVUsTsfhjl3SNcJewXE=-1"> <span class="c1"># safe url parameters to use instead of params.merge</span>
</span><span id="84rvM+YRXVUsTsfhjl3SNcJewXE=-2"> <span class="k">def</span> <span class="nf">safe_params</span> <span class="n">unsafe</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="84rvM+YRXVUsTsfhjl3SNcJewXE=-3"> <span class="n">params</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">unsafe</span><span class="p">)</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="ss">only_path</span><span class="p">:</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">script_name</span><span class="p">:</span> <span class="kp">nil</span><span class="p">)</span>
</span><span id="84rvM+YRXVUsTsfhjl3SNcJewXE=-4"> <span class="k">end</span>
</span><span id="84rvM+YRXVUsTsfhjl3SNcJewXE=-5"> <span class="n">helper_method</span> <span class="ss">:safe_params</span>
</span></pre></div>
<p>This way you can save a bit on the link_to side:</p>
<div class="highlight"><pre><span id="qI/EHpPs+rQGx0oC1Pulbv9pmQ8=-1"><span class="n">link_to</span><span class="p">(</span><span class="s2">"parlez vous français?"</span><span class="p">,</span> <span class="n">safe_params</span><span class="p">(</span><span class="ss">locale</span><span class="p">:</span> <span class="s2">"fr"</span><span class="p">))</span>
</span></pre></div>
<p>And don't think you can solve this with <code>default_url_params</code> as you can also pass this via the URL!</p>
<h3 id="link_to-homepage-user-homepage">link_to("Homepage", @user.homepage)</h3>
<p>Rails escapes the parameters good enough that you won't directly run into XSS issues here but there are exceptions in regard to <code>javascript:</code> or <code>data:</code> links. So if you link to a user defined webpage, be sure to blacklist or better whitelist and enforce the allowed protocols.</p>
<h2 id="update-script_name">Update: script_name</h2>
<p>There is another parameter which can alter the URL and is therefore dangerous to ignore. The popular pagination gem <a href="https://github.com/mislav/will_paginate">will_paginate</a> <a href="https://github.com/mislav/will_paginate/commit/ec9b9851901f8b74adc945302c0520320aaa7ead">ran into this problem</a> as well. The <code>safe_params</code> helper was modified accordingly.</p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/162014-03-15T00:00:00Z2014-10-30T12:32:55ZMonkey Devkit – A collection of development gems<p>We use a gem internally which is just a dependency to load even more dependencies which are helpful for developing/debugging Ruby (on Rails) applications. It also has some wrapper logic to maintain a Devkit-file to enable/disable components. They can get annoying... yeah I'm looking at you rack profiler :)</p>
<p>I don't know if it makes sense to release the gem but I will certainly unleash the list of productivity and here it is...</p>
<h3 id="must-have">Must have</h3>
<table class="table table-condensed">
<tr><th width="200"><a href="http://pryrepl.org/">pry</a></th><td>Powerful IRB replacement</td></tr>
<tr><th><a href="https://github.com/pry/pry-doc">pry-doc</a></th><td>provides MRI Core documentation and source code for pry</td></tr>
<tr><th><a href="https://github.com/nixme/pry-nav">pry-nav</a></th><td>teaches Pry about step, next and continue commands</td></tr>
<tr><th><a href="https://github.com/deivid-rodriguez/pry-byebug">pry-byebug</a></th><td><em>(similar to pry-nav)</em> Adds step, next, finish and continue commands and breakpoints to Pry using <a href="https://github.com/deivid-rodriguez/byebug">byebug</a>.</td></tr>
<tr><th><a href="https://github.com/rweng/pry-rails">pry-rails</a></th><td>Make Pry to your `rails console`</td></tr>
<tr><th><a href="https://github.com/michaeldv/awesome_print">awesome_print</a></th><td>Pretty print object for nice debugging output (especially with pry)</td></tr>
<tr><th><a href="https://github.com/brentd/xray-rails">xray-rails</a></th><td>Press a shortcut, click on whatever on your page, be in the view/partial</td></tr>
<tr><th><a href="https://github.com/evrone/quiet_assets">quiet_assets</a></th><td>Hides asset requests from your development.log</td></tr>
</table>
<h3 id="mail-mailer">Mail & Mailer</h3>
<p>Just two in this categoy. I would always, always, always install letter_opener when working with production data on your machine. Who would work with production data? We.. ehhh... don't!</p>
<table class="table table-condensed" style="width: auto">
<tr><th width="200"><a href="https://github.com/ryanb/letter_opener">letter_opener</a></td><td>Openes every delivered email in your browser, join the safe side ;)</td></tr>
<tr><th><a href="https://github.com/basecamp/mail_view">mail_view</a></td><td>mailer preview in your browser, perfect for designing these shitty HTML constructs!</td></tr>
<tr><th><a href="http://mailcatcher.me/">MailCatcher</a></td><td>Like a combination of the last two gems. "<em><quote>Catches mail and serves it through a dream.</quote></em>"</td></tr>
</table>
<h3 id="other-stuff">Other stuff</h3>
<table class="table table-condensed">
<tr><th width="200"><a href="https://github.com/flyerhzm/bullet">bullet</a></th><td>help to kill N+1 queries and unused eager loading</td></tr>
<tr><th><a href="https://github.com/charliesome/better_errors">better_errors</a></th><td>Don't know why they don't have Rails 4 route overview inside or why Rails doesn't have any of these cool features... Really weird error or stacktrace? Disable better_errors temporarly, that might help in edge cases.</td></tr>
<tr><th><a href="https://github.com/banister/binding_of_caller">binding_of_caller</a></th><td>Enables better_errors' awesome REPL right on your exception page!</td></tr>
<tr><th><a href="https://github.com/miniprofiler/rack-mini-profiler">rack-mini-profiler</a></th><td>Didn't really get the use of it and it can spam your javascript console but noteworthy</td></tr>
<tr><th><a href="https://github.com/railsbp/rails_best_practices">rails_best_practices</a></th><td>Provides executable to scan your app for improvements and vulnerabilities</td></tr>
<tr><th><a href="http://brakemanscanner.org/">brakeman</a></th><td>Powerful vulnerability scanner for rails applications</td></tr>
<tr><th><a href="https://github.com/markbates/coffee-rails-source-maps">coffee-rails-source-maps</a></th><td>Enable source maps for coffeescript files</td></tr>
<tr><th><a href="https://github.com/vhyza/sass-rails-source-maps">sass-rails-source-maps</a></th><td>Enable source maps for scss files</td></tr>
</table>
<p><strong>What are source maps?</strong> The web inspector and the javascript console displays the position in the original source file rather then in the compiled version so you directly know where to start hunting the bugs!</p>
<p><strong>Questions, suggestions or other cool gems we've missed? Leave a comment and let us know!</strong></p>
<p>Eat bananas every day!</p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/172014-03-13T00:00:00Z2014-03-16T00:13:15ZOverview about nil?, blank?, present?, presence, try and other basic things<p>This is a post about basic things and if you are an experienced user you might want to skip this one but I see a lot of beginners and also advanced users which are not using them.</p>
<p>First you should know that Ruby only knows of two falsy values which are <code>nil</code> and <code>false</code>. Anything else is evaluated to true.</p>
<p>Secondly the "or" operator in Ruby <code>||</code> always returns one of the values you are comparing. In PHP for example <code>$var = $foo || "bar"</code> would result in <code>$var</code> being a boolean value but in Ruby it's much nicer! <code>var = foo || "bar"</code> would result in <code>var</code> being <code>foo</code> if it is not falsy or the last value in the chain. The following two lines are basically identical:</p>
<div class="highlight"><pre><span id="3uldczeh+WwZvMPu2KpJlBjnGr0=-1"><span class="n">foo</span> <span class="o">=</span> <span class="n">a</span> <span class="o">||</span> <span class="n">b</span> <span class="o">||</span> <span class="n">c</span> <span class="o">||</span> <span class="s2">"other"</span>
</span><span id="3uldczeh+WwZvMPu2KpJlBjnGr0=-2"><span class="n">foo</span> <span class="o">=</span> <span class="n">a</span> <span class="p">?</span> <span class="n">a</span> <span class="p">:</span> <span class="n">b</span> <span class="p">?</span> <span class="n">b</span> <span class="p">:</span> <span class="n">c</span> <span class="p">?</span> <span class="n">c</span> <span class="p">:</span> <span class="s2">"other"</span>
</span></pre></div>
<p>If you're using <code>||</code> you might think <em>can't I just use <code>or</code> since that reads nicer?</em>. You can't. <code>||</code> isn't the same as <code>or</code> and <code>&&</code> isn't the same as <code>and</code> in terms of precendence.</p>
<p><strong>Consider using presenters (aka. decorators). They are really cool, even with these tricks.</strong></p>
<h3 id="nil">nil?</h3>
<p>I see beginners doing this:</p>
<div class="highlight"><pre><span id="x2R8jSMcgfonl0U7ke+zOTDzIdo=-1"><span class="n">link_to</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">job</span><span class="o">.</span><span class="n">nil?</span> <span class="p">?</span> <span class="s2">"Unemployed"</span> <span class="p">:</span> <span class="n">user</span><span class="o">.</span><span class="n">job</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<p>Since <code>nil</code> is already falsy you could omit this explicit check. A string attribute in ActiveRecord only returns either nil or the string. Checking <code>#nil?</code> explicitely is rarely used and you wont see this very often. So get rid of it:</p>
<div class="highlight"><pre><span id="k7JTTRkA+jVN7juekdkKBWXL8DU=-1"><span class="n">link_to</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">job</span> <span class="p">?</span> <span class="n">user</span><span class="o">.</span><span class="n">job</span> <span class="p">:</span> <span class="s2">"Unemployed"</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<p>But since we know how <code>||</code> works we could make it even shorter:</p>
<div class="highlight"><pre><span id="05/ohtORZBo9SiX/dEGTD2eJ8i0=-1"><span class="n">link_to</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">job</span> <span class="o">||</span> <span class="s2">"Unemployed"</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<p>Cool eh?</p>
<h3 id="blank-and-present-and-presence">blank? and present? (and presence)</h3>
<p>Side note: <code>blank?</code> is the exact opposite of <code>present?</code> and all three methods are defined on Object so you can use them on any object (there are some exceptions but this is another topic).</p>
<p>What if the job is an empty string? This will happen by default when your form field is left empty. We'd had to check for job being present. So we'd end up again with something like this:</p>
<div class="highlight"><pre><span id="7ov4afNgbQk1genaQeNoqDZY2nA=-1"><span class="n">link_to</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">job</span><span class="o">.</span><span class="n">present?</span> <span class="p">?</span> <span class="n">user</span><span class="o">.</span><span class="n">job</span> <span class="p">:</span> <span class="s2">"Unemployed"</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<p>But fortunately there is <code>presence</code> which will return the object when it's <code>present?</code> or <code>nil</code> otherwise. So we can use <code>||</code> again:</p>
<div class="highlight"><pre><span id="DWIL3q7ljGKov+Rm/idaUOXiwzg=-1"><span class="n">link_to</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">job</span><span class="o">.</span><span class="n">presence</span> <span class="o">||</span> <span class="s2">"Unemployed"</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<div class="alert alert-info">
<i class="fa fa-info-circle"></i> There is a handy gem called <a href="https://github.com/rubiety/nilify_blanks">nilify_blanks <small><i class="fa fa-external-link"></i></small></a> which optionally set attributes to nil when they are blank.
</div>
<h3 id="try-try">try, try!</h3>
<p><code>try</code> is a really cool helper to remove conditional code. The functionality has changed in Rails/ActiveSupport 4 so if you are using v3 then your <code>try</code> behaves like <code>try!</code> in version 4.</p>
<p>Try calls a method on an object (like <code>send</code>) but only when it is truthy and returns the result. You can chain these together but keep the <a href="http://en.wikipedia.org/wiki/Chain-of-responsibility_pattern">chain of responsibility</a> in mind.</p>
<p>So from the above example assume that the job is a relation and has an attribue "name". We now need additional conditions:</p>
<div class="highlight"><pre><span id="FZiB/gGWsfP167+Rf+W8Z2CvMvo=-1"><span class="n">link_to</span><span class="p">((</span><span class="n">user</span><span class="o">.</span><span class="n">job</span> <span class="p">?</span> <span class="n">user</span><span class="o">.</span><span class="n">job</span><span class="o">.</span><span class="n">name</span><span class="o">.</span><span class="n">presence</span> <span class="p">:</span> <span class="kp">nil</span><span class="p">)</span> <span class="o">||</span> <span class="s2">"Unemployed"</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<p>But with try it's as easy as:</p>
<div class="highlight"><pre><span id="daBiI7AmBIps+Hdxd7EEWlKywAs=-1"><span class="n">link_to</span><span class="p">(</span><span class="n">user</span><span class="o">.</span><span class="n">job</span><span class="o">.</span><span class="n">try</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span><span class="o">.</span><span class="n">presence</span> <span class="o">||</span> <span class="s2">"Unemployed"</span><span class="p">,</span> <span class="n">jobs_path</span><span class="p">)</span>
</span></pre></div>
<p>When there is no related job record <code>user.job</code> would be nil so <code>try</code> wouldn't call <code>name</code> on it and return <code>nil</code> instead.</p>
<p>With Rails 4 <code>try</code> also won't call the method if the object is truthy but doesn't respond to the method. If you don't want this use <code>try!</code>. Also take a look at <a href="http://api.rubyonrails.org/classes/Object.html#method-i-try">the documentation</a>.</p>
<div class="highlight"><pre><span id="DKoa5xfjbkX5Of9mm4q+scqBwPk=-1"><span class="s2">""</span><span class="o">.</span><span class="n">try</span><span class="p">(</span><span class="ss">:each</span><span class="p">)</span> <span class="p">{</span> <span class="s2">"we never get here"</span> <span class="p">}</span>
</span><span id="DKoa5xfjbkX5Of9mm4q+scqBwPk=-2"><span class="s2">""</span><span class="o">.</span><span class="n">try!</span><span class="p">(</span><span class="ss">:each</span><span class="p">)</span> <span class="c1"># NoMethodError undefined method `each' for "":String</span>
</span></pre></div>
<h3 id="tap">tap</h3>
<p>This is a Ruby core method and functions like the meanwhile gone <code>returning</code> method from ActiveSupport. It just returns the object it is called on after calling the block passed to the <code>tap</code> method. It sometimes can be really handy but don't overuse it. In some cases it's not even necessary.</p>
<p>The reason why it is so useful is that ruby always passes references to objects around. So it can be useful when working with mutable objects (which are most types). You cannot however change the type of the variable.</p>
<p>It is also good for inject logging in chained method calls. Actually that is the intended , <a href="http://ruby-doc.org/core-2.1.1/Object.html#method-i-tap">documented</a> use for it which also has a good example.</p>
<p>Now an example for how it could be used with mutable objects:</p>
<div class="highlight"><pre><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-1"><span class="k">def</span> <span class="nf">foo</span> <span class="n">opts</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-2"> <span class="n">result</span> <span class="o">=</span> <span class="o">[]</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-3"> <span class="n">result</span> <span class="o"><<</span> <span class="s2">"foo"</span> <span class="k">if</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:foo</span><span class="o">]</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-4"> <span class="n">result</span> <span class="o"><<</span> <span class="s2">"bar"</span> <span class="k">if</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:bar</span><span class="o">]</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-5"> <span class="n">result</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-6"><span class="k">end</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-7">
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-8"><span class="k">def</span> <span class="nf">foo</span> <span class="n">opts</span> <span class="o">=</span> <span class="p">{}</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-9"> <span class="o">[].</span><span class="n">tap</span> <span class="k">do</span> <span class="o">|</span><span class="n">result</span><span class="o">|</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-10"> <span class="n">result</span> <span class="o"><<</span> <span class="s2">"foo"</span> <span class="k">if</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:foo</span><span class="o">]</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-11"> <span class="n">result</span> <span class="o"><<</span> <span class="s2">"bar"</span> <span class="k">if</span> <span class="n">opts</span><span class="o">[</span><span class="ss">:bar</span><span class="o">]</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-12"> <span class="k">end</span>
</span><span id="LXeAGKbYqWrQxYUv/UQ4TYXjios=-13"><span class="k">end</span>
</span></pre></div>
<p>You can do this with strings, arrays, hashes and other objects on higher levels. Numeric values, symbols, nil or boolean values are not mutable and can't be changed in this manner. But note that many high level objects like the ActiveRecord model object are supporting this already:</p>
<div class="highlight"><pre><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-1"><span class="no">Post</span><span class="o">.</span><span class="n">new</span> <span class="k">do</span> <span class="o">|</span><span class="nb">p</span><span class="o">|</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-2"> <span class="nb">p</span><span class="o">.</span><span class="n">foo</span> <span class="o">=</span> <span class="s2">"bar"</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-3"> <span class="nb">p</span><span class="o">.</span><span class="n">save!</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-4"><span class="k">end</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-5">
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-6"><span class="vi">@user</span><span class="o">.</span><span class="n">comments</span><span class="o">.</span><span class="n">build</span> <span class="k">do</span> <span class="o">|</span><span class="n">c</span><span class="o">|</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-7"> <span class="n">c</span><span class="o">.</span><span class="n">subject</span> <span class="o">=</span> <span class="s2">"…"</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-8"> <span class="n">c</span><span class="o">.</span><span class="n">message</span> <span class="o">=</span> <span class="s2">"…"</span>
</span><span id="Le9hJ6sNtpdAZIlmHNiUgWm8fyk=-9"><span class="k">end</span>
</span></pre></div>Sven Pachnittag:blog.bmonkeys.net,2005:Post/92013-11-15T00:00:00Z2014-03-16T00:13:09ZTeamspeak 3 – Client application unresponsive on OS X<p>I always had problems with my Teamspeak 3 client application on OS X. The overall performance was very poor. Not the sound, I heard everbody loud and clear and I wasn't lagging too but everything else like switching channels or even just selecting them took seconds!</p>
<p>I think I've found the solution to this problem: <strong>Unicode characters</strong></p>
<p>Maybe not all but several special characters causing the application to significantly drop performance. The problem was mentioned in <a href="http://forum.teamspeak.com/showthread.php/78695-Huge-Client-Lag-with-Arrow-Icons">this thread on the Teamspeak forums</a> but they didn't found a solution though they gave me a hint.</p>
<p>I used a special character in almost all channel names on my server as separator. The character in my case was <code>⁞</code> or <code>&#8286;</code> <a href="http://www.fileformat.info/info/unicode/char/205e/index.htm">(info)</a>. After I've removed all these characters my client performed noticeable faster. The only downside is that you need to be able to rename the channels in order to solve the problem but hopefully they fix it soon.</p>
<p>This is a little demonstration I've put up for the TS3 support:</p>
<p> <iframe frameborder="0" allowfullscreen="allowfullscreen" width="600" height="337.5" src="//www.youtube.com/embed/bndJaeJrgz0?autohide=2&autoplay=0&color=red&disablekb=0&enablejsapi=0&end=&iv_load_policy=1&loop=0&modestbranding=0&origin=&playlist=&rel=0&showinfo=1&start=&theme=dark&vq=hd720" ></iframe> </p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/52013-02-28T00:00:00Z2014-03-16T00:18:09ZMac OS X application won't start (just bouncing)?<p>Do you have an OS X application which is <strong>just bouncing in your Dock</strong> when you're trying to launch it?<br><br>
<strong>Then this might help:</strong></p>
<h3 id="the-problem">The problem</h3>
<p>For some reason <strong>the executable</strong> file inside your .app file <strong>doesn't have the proper permissions</strong> to get executed. <em>The Unarchiver</em> was known to set the quarantine flag incorrectly or the app is just defect. Whatsoever, you'll need to utilize your Terminal if you want to fix it manually or the droplet for an automatic repair attempt:</p>
<h3 id="manual-fix">Manual fix</h3>
<ol>
<li>start your Terminal (if you don't now how to do so you should take a look at the automated version below)</li>
<li>type in <code>chmod +x</code> (<strong>with a trailing space!</strong>)</li>
<li>rightclick your application and select <strong>show package contents</strong></li>
<li>navigate to <strong>Contents » MacOS</strong></li>
<li>drag the file in the opened folder onto the Terminal window (this will insert the filepath there). If you have more than one file in the MacOS folder you have to decide which might be the right one and if you weren't lucky you'll have to try them one by one, sorry!</li>
<li>Press enter, you should be fine now. Have fun with your app ;-)</li>
</ol>
<h3 id="automatic-fix">Automatic fix</h3>
<p>I've build a little droplet which probably can solve your problem by just dropping the defect application onto it. If it does not work it's probably something different or there were too many files (see manual fix #5)</p>
<table><thead>
<tr>
<th style="text-align: right"></th>
<th>ReadMe is included</th>
</tr>
</thead><tbody>
<tr>
<td style="text-align: right"><strong>Download</strong></td>
<td><strong><a href="http://blog.bmonkeys.net/download/0937234172bd7aecd213c4ae8200acbb/app-executable-fixer-v1-0.zip">AppExecutableFixer v1.0</a></strong></td>
</tr>
<tr>
<td style="text-align: right">SHA checksum</td>
<td><code>72aae5359a4f3c623e839263dacc3421ad2554c6</code></td>
</tr>
<tr>
<td style="text-align: right">Source code</td>
<td><a href="https://github.com/bmonkeys/app-executable-fixer">is available on GitHub</a></td>
</tr>
<tr>
<td style="text-align: right">License</td>
<td><a href="https://github.com/bmonkeys/app-executable-fixer/blob/master/LICENSE.txt">is also on GitHub</a></td>
</tr>
</tbody></table>
<p><em>Thanks to the test bunny ;-)</em></p>
Sven Pachnittag:blog.bmonkeys.net,2005:Post/42013-02-13T00:00:00Z2014-03-16T00:12:57ZSlowdowns using VPN and Mac OS X?<p>Are you suffering from slow directory listings and/or file transfers using Apple's Finder while connected through VPN? You're at the right place, read on!</p>
<h2 id="some-background-first">Some Background First</h2>
<p>Our lovely file-server (Ubuntu Linux) in the office handles small, big and huge files, just about everything we need to work with and share. About 5 people are connected against the box transfering files back and forth. We use SMB shares as Samba is/was easy to setup and maintain. It felt like a natural choice. (We also tried Netatalk aka AFP, but it didn't work very well)</p>
<p>As we work remotely regularly we also installed a VPN service to access files from everywhere outside the office securely. Nobody is forced to be in the office, we might also work from home or whatever place we feel appropriate to get our things done.</p>
<p>From day one directory listings and file transfers have been slow like hell. In fact it was so slow, that two of my colleagues and myself started research and began our experiments on different VPN services, e.g. PPTP, IPSec, L2TP over IPSec, OpenVPN. You get to read about differences with those services, e.g. speed, security and what not – just forget about all that, except for the security thing, it didn't change anything on speed. The VPN server was not the issue!</p>
<h2 id="an-incidental-discovery">An Incidental Discovery</h2>
<p>We can login to the box via SSH for maintenance reasons. One day I needed to sync files between two locations, so I connected to the file-server using Forklift. Surprisingly it was fast and convenient, not the usual slow crappy connection... Would SSH be the solution? Let's give it a try!</p>
<h2 id="the-solution">The Solution</h2>
<p>I installed SSHFS (<a href="http://osxfuse.github.com" title="SSHFS Installation Package for Mac OS X">find the sshfs package on github</a>) on my Mac, went home in the afternoon to test the thing... It didn't change anything, same slowdowns. What's the difference then? Why is connecting through SFTP with Forklift so much faster then SSHFS? I started to explore options with SSHFS and MacFUSE and BOOM (in fact it felt like days and hours) there was my solution!</p>
<p><strong>Mount your share using the following command and options:</strong></p>
<div class="highlight"><pre><span id="+whbOyTwfIdWmdYkubUGPoSO3qU=-1"><span class="n">sshfs</span><span class="w"> </span><span class="k">USER</span><span class="nv">@DEST</span><span class="err">:</span><span class="n">REMOTE_PATH</span><span class="w"> </span><span class="n">LOCAL_PATH</span><span class="w"> </span><span class="o">-</span><span class="n">oauto_cache</span><span class="p">,</span><span class="n">reconnect</span><span class="p">,</span><span class="n">defer_permissions</span><span class="p">,</span><span class="n">noappledouble</span><span class="p">,</span><span class="n">volname</span><span class="o">=</span><span class="n">VOLNAME</span><span class="w"></span>
</span></pre></div>
<p>The option-flag that did the trick is <code>noappledouble</code>. It prevents Finder from reading all those <code>.DS_Store</code>, <code>._*</code>-whatever files that causes the slowdowns. Using that option does not only make AppleDotFiles invisble to Finder it simply disables the usage completely.</p>
<p>To make the long story short: I became a huge fan of SSHFS and do really enjoy remote work now. The connection has never been faster.</p>
<p><em>This solution has been tested using OS X 10.7. and 10.8.</em></p>
<h3 id="edit-additional-options-to-fix-encoding-issues">[EDIT] - Additional Options To Fix Encoding Issues</h3>
<p>While being happy with the solution I encoutered some issues with encodings. I was unable to use any data with umlauts. To make Finder work correctly with umlauts add those additional options to your mount command:</p>
<div class="highlight"><pre><span id="qdm2Eti0z8olyuSe2pK+dVMoExo=-1"><span class="n">modules</span>=<span class="n">iconv</span>,<span class="n">to_code</span>=<span class="n">UTF-8-MAC</span>
</span></pre></div>Chris Vandebroek