<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://batsov.com/feeds/Ruby.xml" rel="self" type="application/atom+xml" /><link href="https://batsov.com/" rel="alternate" type="text/html" hreflang="en" /><updated>2026-03-11T23:32:49+02:00</updated><id>https://batsov.com/feeds/Ruby.xml</id><title type="html">(think)</title><subtitle>Bozhidar Batsov&apos;s personal blog</subtitle><entry><title type="html">Why I Chose Ruby over Python</title><link href="https://batsov.com/articles/2025/09/12/why-i-chose-ruby-over-python/" rel="alternate" type="text/html" title="Why I Chose Ruby over Python" /><published>2025-09-12T09:50:00+03:00</published><updated>2025-09-17T00:00:00+03:00</updated><id>https://batsov.com/articles/2025/09/12/why-i-chose-ruby-over-python</id><content type="html" xml:base="https://batsov.com/articles/2025/09/12/why-i-chose-ruby-over-python/"><![CDATA[<p>This year I spent a bit of time playing with Python, after
having mostly ignored it since 2005 when I was learning it
originally. I did like Python back then, but a few years afterwards
I discovered Ruby and quickly focused my entire attention on it.</p>

<p>There were many (mostly small) reasons why I leaned towards Ruby
back then and playing with Python now made me remember a few of
them. I thought it might be interesting to write a bit about those,
so here we go.</p>

<p><strong>Disclaimer:</strong> This is not a rant and I know that:</p>

<ul>
  <li>the things I prefer in Ruby over Python are super subjective</li>
  <li>for every thing that Ruby does “better” there’s something else that Python does better</li>
</ul>

<p>So, treat this as an amusing personal account and nothing more than that.</p>

<h2 id="built-in-functions">Built-in functions</h2>

<p>Probably the thing about Python that bothered me the most was stuff that would
normally be methods are global functions (that often call some object methods internally).
I’m referring to the likes of:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">len</code></li>
  <li><code class="language-plaintext highlighter-rouge">sum</code></li>
  <li><code class="language-plaintext highlighter-rouge">pow</code></li>
</ul>

<p>You can find the full list <a href="https://docs.python.org/3/library/functions.html">here</a>.</p>

<p>I’m guessing the reason for this (as usual) is historical, but I much prefer the way Ruby does things.
E.g. <code class="language-plaintext highlighter-rouge">str.length</code> instead of <code class="language-plaintext highlighter-rouge">len(str)</code> or <code class="language-plaintext highlighter-rouge">arr.sum</code> vs <code class="language-plaintext highlighter-rouge">sum(arr)</code>.</p>

<h2 id="the-del-keyword">The <code class="language-plaintext highlighter-rouge">del</code> keyword</h2>

<p><code class="language-plaintext highlighter-rouge">del</code> is a pretty weird beast as it can:</p>

<ul>
  <li>delete variables</li>
  <li>list items</li>
  <li>dictionary items</li>
</ul>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="n">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
<span class="k">del</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>
<span class="n">numbers</span>
<span class="c1"># =&gt; [1, 2, 4, 5]
</span>
<span class="k">del</span> <span class="n">numbers</span>
<span class="n">numbers</span>
<span class="c1"># =&gt; NameError: name 'numbers' is not defined
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Why would someone want a keyword for removing items from lists and dictionaries instead of some method is beyond me. Ruby’s arrays have methods like:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">delete</code> (to remove some values)</li>
  <li><code class="language-plaintext highlighter-rouge">delete_at</code> (to remove some index)</li>
</ul>

<h2 id="too-many-statements-and-functions-returning-none">Too many statements (and functions returning <code class="language-plaintext highlighter-rouge">None</code>)</h2>

<p>In Ruby almost everything is an expression (meaning that evaluating it would
result in a value). In Python a lot of things are consider “statements” -
something executed for their side effects only. If you haven’t used
languages like Ruby or Lisp this might sound a bit strange, but if we go back
to the previous section about <code class="language-plaintext highlighter-rouge">del</code>, we can observe that:</p>

<ul>
  <li>There’s no obvious way to determine if <code class="language-plaintext highlighter-rouge">del</code> actually removed something</li>
  <li>In Ruby, however, most deletions result in informative results</li>
</ul>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="n">arr</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">10</span><span class="p">).</span><span class="nf">to_a</span>
<span class="c1"># =&gt; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># =&gt; 1</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="c1"># =&gt; nil</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">delete_at</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<span class="c1"># =&gt; 2</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>That’s something that I really value and I consider it one of the bigger
practical advantages of Ruby over Python.</p>

<h2 id="semantic-indentation">Semantic indentation</h2>

<p>At first I thought the semantic indentation used by Python is super cool,
as it reduces a bit the typing one needs to do:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="k">if</span> <span class="n">a</span> <span class="o">&lt;</span> <span class="n">b</span><span class="p">:</span>
    <span class="nb">max</span> <span class="o">=</span> <span class="n">b</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nb">max</span> <span class="o">=</span> <span class="n">a</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>In hindsight, however, I quickly realized that it also:</p>

<ul>
  <li>makes things harder for tooling, as it can’t really rearrange indented code
sections</li>
  <li>in editors you can’t have much in terms of auto-indenting as you type (as the
editor can’t know when a block finishes without you outdenting explicitly)</li>
</ul>

<p>One more thing - 4 spaces by default seems a tad too much to me, although that’s obviously debatable.</p>

<p><strong>P.S.</strong> I feel obliged to admit I’m not a big fan of <code class="language-plaintext highlighter-rouge">do/end</code> either and would have preferred <code class="language-plaintext highlighter-rouge">{}</code> instead, but it is how it is.</p>

<h2 id="the-bool-type">The <code class="language-plaintext highlighter-rouge">bool</code> type</h2>

<p>I’m not a fan of Python’s <code class="language-plaintext highlighter-rouge">bool</code> type as for me it’s a pretty weird duck:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">bool</code> was added only in Python 2.3</li>
  <li>it inherits from <code class="language-plaintext highlighter-rouge">int</code></li>
  <li><code class="language-plaintext highlighter-rouge">True</code> and <code class="language-plaintext highlighter-rouge">False</code> are essentially 1 and 0</li>
</ul>

<p>I get how things ended up the way they are, but for me it’s not OK to be able to write code like <code class="language-plaintext highlighter-rouge">True + 1</code>.
I’m also not a fan of treating empty collection literals as <code class="language-plaintext highlighter-rouge">False</code>, although I definitely have less issues
with this than with 0 and 1.</p>

<p>To compare this with Ruby:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">boolean</code> has nothing to do with numbers there</li>
  <li>the only things are considered logically false are <code class="language-plaintext highlighter-rouge">false</code> and <code class="language-plaintext highlighter-rouge">nil</code></li>
</ul>

<p>This definitely resonates better with me.</p>

<p><strong>Side note:</strong> Lately I’ve been playing a lot with languages like OCaml, F# and Rust, that’s why to
me it now feels extra strange to have a boolean type that works like an integer type.</p>

<h3 id="ranges">Ranges</h3>

<p>I really like the range literals in Ruby:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">1..n</code> (inclusive range)</li>
  <li><code class="language-plaintext highlighter-rouge">1...n</code> (exclusive range)</li>
</ul>

<p>Python has the <code class="language-plaintext highlighter-rouge">range</code> function that kind of gets the job done, but for whatever reason
it doesn’t have the option to mark something as inclusive range.</p>

<p>Definitely not a big deal, but one of the many small touches of Ruby’s syntax that I came to appreciate over time.</p>

<h3 id="passing-self-explicitly-everywhere">Passing <code class="language-plaintext highlighter-rouge">self</code> explicitly everywhere</h3>

<p>In Python one has to pass <code class="language-plaintext highlighter-rouge">self</code> to instance methods explicitly, which always seemed to me
like an excessive level of verbosity. Also, that’s quite uncommon in other object-oriented
programming languages.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="k">class</span> <span class="nc">MyClass</span><span class="p">:</span>
    <span class="sh">"""</span><span class="s">A simple example class</span><span class="sh">"""</span>
    <span class="n">i</span> <span class="o">=</span> <span class="mi">12345</span>

    <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="sh">'</span><span class="s">hello world</span><span class="sh">'</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<h3 id="too-many-underscores-eg-__init__">Too many underscores (e.g. <code class="language-plaintext highlighter-rouge">__init__</code>)</h3>

<p>Many special methods have names surrounded with <code class="language-plaintext highlighter-rouge">__</code>, which I find both odd and not very easy to type.
I get why this was chosen (to avoid naming conflicts), but I don’t like it regardless.</p>

<h3 id="explicit-return">Explicit <code class="language-plaintext highlighter-rouge">return</code></h3>

<p>I really like that in Ruby the return value of a method is the value of the last expression
that got evaluated in the method. There’s a <code class="language-plaintext highlighter-rouge">return</code> expression in Ruby, but it’s rarely
needed in practice.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
</pre></td><td class="rouge-code"><pre><span class="k">def</span> <span class="nf">fact</span><span class="p">(</span><span class="n">n</span><span class="p">)</span>
  <span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="n">n</span><span class="p">).</span><span class="nf">reduce</span><span class="p">(:</span><span class="o">*</span><span class="p">)</span>
<span class="k">end</span>

<span class="n">fact</span> <span class="mi">5</span>
<span class="c1"># =&gt; 120</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>In Python, by comparison, you always have to use <code class="language-plaintext highlighter-rouge">return</code>, otherwise your method will
return <code class="language-plaintext highlighter-rouge">None</code>.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="rouge-code"><pre><span class="k">def</span> <span class="nf">fact</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="n">res</span> <span class="o">=</span> <span class="mi">1</span>

    <span class="k">for</span> <span class="n">n</span> <span class="ow">in</span> <span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
        <span class="n">res</span> <span class="o">*=</span> <span class="n">n</span>

    <span class="n">res</span> <span class="c1"># notice the forgotten return
</span>
<span class="nf">fact</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="c1"># =&gt; None
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Not a big deal in general, but as I spend a lot of time with Ruby and
various functional programming languages, it’s definitely something that bothers me.</p>

<h3 id="lambda-verbosity"><code class="language-plaintext highlighter-rouge">lambda</code> verbosity</h3>

<p>Admittedly that’s a very small one, but I would have preferred if anonymous functions were
created with a keyword like <code class="language-plaintext highlighter-rouge">fn</code> or <code class="language-plaintext highlighter-rouge">fun</code> instead of <code class="language-plaintext highlighter-rouge">lambda</code>. In Ruby historically they
were created with <code class="language-plaintext highlighter-rouge">lambda</code> as well, but afterwards the <code class="language-plaintext highlighter-rouge">-&gt;</code> shorthand was introduced as well.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="c1"># classic Ruby lambda</span>
<span class="n">a_lambda</span> <span class="o">=</span> <span class="nb">lambda</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"Hello world!"</span> <span class="p">}</span>

<span class="c1"># lambda shorthand</span>
<span class="n">s_lambda</span> <span class="o">=</span> <span class="o">-&gt;</span> <span class="p">{</span> <span class="nb">puts</span> <span class="s2">"I rock!"</span> <span class="p">}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>There’s nothing wrong with the Python syntax per se, but I think that in general for
lambdas it’s better to have a more compact syntax.</p>

<h3 id="naming-conventions">Naming conventions</h3>

<p>Ruby predicates typically have names ending in <code class="language-plaintext highlighter-rouge">?</code> - e.g. <code class="language-plaintext highlighter-rouge">even?</code>, <code class="language-plaintext highlighter-rouge">odd?</code>, <code class="language-plaintext highlighter-rouge">digit?</code>. This makes them
really easy to spot while reading some code. Python sticks to the more common convention of prefixing
such methods with <code class="language-plaintext highlighter-rouge">is_</code>, <code class="language-plaintext highlighter-rouge">has_</code>, etc and that’s fine. One thing that bothers me a bit is that often
there’s no space between the prefix and the rest of the name (e.g. <code class="language-plaintext highlighter-rouge">str.isdigit()</code>), which doesn’t
read great in my opinion.</p>

<p>More importantly, in Ruby and Python it’s common to have destructive and
non-destructive versions of some methods. E.g. - <code class="language-plaintext highlighter-rouge">arr.sort!</code> vs <code class="language-plaintext highlighter-rouge">arr.sort</code> in
Ruby, and <code class="language-plaintext highlighter-rouge">list.sort</code> vs <code class="language-plaintext highlighter-rouge">sorted(list)</code> in Python.</p>

<p>I don’t know about you, but to me it seems that:</p>

<ul>
  <li>Ruby encourages you to favor the non-destructive versions of the methods, unlike Python</li>
  <li>Ruby’s more consistent than Python</li>
</ul>

<p>I’m guessing the reasons here are also historical.</p>

<h3 id="triple-quoted-string-literals">Triple-quoted string literals</h3>

<p>Multi-line text literals are common in many languages, but I’m not super fond of:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="n">x</span> <span class="o">=</span> <span class="sh">"""</span><span class="s">a multi-line text
enclosed by
triple quotes
</span><span class="sh">"""</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Who thought that typing those would be easy?</p>

<p>It’s not that HEREDOCS in Ruby are great either, but I guess they are at least more common in various programming languages.</p>

<h2 id="the-million-python-package-managers">The million Python package managers</h2>

<p>Ruby has <code class="language-plaintext highlighter-rouge">rubygems</code> and <code class="language-plaintext highlighter-rouge">bundler</code>. That’s it. Everyone uses them. Life is simple.
Things are a lot more complicated in the realm of Python where several different tools
have been in fashion over the years:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">easy_install</code></li>
  <li><code class="language-plaintext highlighter-rouge">pip</code></li>
  <li><code class="language-plaintext highlighter-rouge">pipx</code></li>
  <li><code class="language-plaintext highlighter-rouge">poetry</code></li>
</ul>

<p>Now it seems that <code class="language-plaintext highlighter-rouge">uv</code> might replace them all. Until something replaces <code class="language-plaintext highlighter-rouge">uv</code> I guess…</p>

<h2 id="epilogue">Epilogue</h2>

<p>And that’s a wrap. I’m guessing at this point most Rubyists reading this would probably agree with
my perspective (shocking, right?) and most Pythonistas won’t. And that’s fine.
I’m not trying to convince anyone that Ruby’s a better language than Python, I’m just
sharing the story of how I ended up in team Ruby almost 20 years ago.</p>

<p>Back in the day I felt that Ruby’s syntax was more elegant and more consistent than Python’s, and
today my sentiment is more or less the same. Don’t get me wrong, though - I like Python overall
and enjoy using it occasionally. It just doesn’t make me as happy as Ruby does.</p>

<p>I’ve long written about my frustrations with Ruby, so it feels pretty good to write for once about the aspects
of Ruby that I really enjoy. Keep hacking!</p>

<p><strong>P.S.</strong> After writing this I realized I had already written a <a href="/articles/2011/05/03/ruby-or-python/">similar article</a> 14 years ago, but I had totally forgotten about it! Oh, well…</p>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><category term="Python" /><summary type="html"><![CDATA[This year I spent a bit of time playing with Python, after having mostly ignored it since 2005 when I was learning it originally. I did like Python back then, but a few years afterwards I discovered Ruby and quickly focused my entire attention on it.]]></summary></entry><entry><title type="html">Wayward Predicates in Ruby</title><link href="https://batsov.com/articles/2025/09/04/wayward-predicates-in-ruby/" rel="alternate" type="text/html" title="Wayward Predicates in Ruby" /><published>2025-09-04T15:21:00+03:00</published><updated>2025-09-04T15:21:00+03:00</updated><id>https://batsov.com/articles/2025/09/04/wayward-predicates-in-ruby</id><content type="html" xml:base="https://batsov.com/articles/2025/09/04/wayward-predicates-in-ruby/"><![CDATA[<p>Recently I’ve been wondering how to name Ruby methods that have predicate
looking names (e.g. <code class="language-plaintext highlighter-rouge">foo?</code>), but don’t behave like predicates - namely they
return other values besides the canonical <code class="language-plaintext highlighter-rouge">true</code> and <code class="language-plaintext highlighter-rouge">false</code>.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>Here are a few classic examples:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
</pre></td><td class="rouge-code"><pre><span class="no">Float</span><span class="o">::</span><span class="no">INFINITY</span><span class="p">.</span><span class="nf">infinite?</span> <span class="c1"># =&gt; 1</span>

<span class="mi">0</span><span class="p">.</span><span class="nf">nonzero?</span> <span class="c1"># =&gt; nil</span>
<span class="mi">1</span><span class="p">.</span><span class="nf">nonzero?</span> <span class="c1"># =&gt; 1</span>

<span class="c1"># funny enough...</span>
<span class="mi">0</span><span class="p">.</span><span class="nf">zero?</span> <span class="c1"># =&gt; true</span>
<span class="mi">5</span><span class="p">.</span><span class="nf">zero?</span> <span class="c1"># =&gt; false</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Naming is hard and it took me a while to narrow my list of ideas to two options:</p>

<ul>
  <li>wayward predicates</li>
  <li>deviant predicates</li>
</ul>

<p>In the end I felt that “wayward predicates” was the way to go, as it sounds
less deviant.<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup></p>

<p>Common vocabulary is important when discussing domain-specific
topics and it makes it easier for people to refer to things within the domains.
That’s why I’m writing this short article - perhaps it will be a first step to
establishing a common name for a pretty common thing.</p>

<p>I’ve always been a believer that naming should be both informative and fun,
and that’s certainly one fun name. Wayward predicates can surprise us unpleasantly
every now and then, but they are also a classic example of the flexibility of Ruby
and its continued resistance to sticking to narrowly defined rules and guidelines.</p>

<p>That’s all I have for you today. Keep hacking!</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>This came up in the context of RuboCop, in case someone’s wondering. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
    <li id="fn:2">
      <p>See also <a href="https://docs.rubocop.org/rubocop/cops_naming.html#namingpredicatemethod">https://docs.rubocop.org/rubocop/cops_naming.html#namingpredicatemethod</a> for the first “official” usage of the term. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><summary type="html"><![CDATA[Recently I’ve been wondering how to name Ruby methods that have predicate looking names (e.g. foo?), but don’t behave like predicates - namely they return other values besides the canonical true and false.1 This came up in the context of RuboCop, in case someone’s wondering. &#8617;&#xfe0e;]]></summary></entry><entry><title type="html">Running Jekyll on Ruby 3.4</title><link href="https://batsov.com/articles/2025/01/12/running-jekyll-on-ruby-3-4/" rel="alternate" type="text/html" title="Running Jekyll on Ruby 3.4" /><published>2025-01-12T11:03:00+02:00</published><updated>2025-01-12T11:03:00+02:00</updated><id>https://batsov.com/articles/2025/01/12/running-jekyll-on-ruby-3-4</id><content type="html" xml:base="https://batsov.com/articles/2025/01/12/running-jekyll-on-ruby-3-4/"><![CDATA[<p>Yesterday I’ve installed the newly released Ruby 3.4, but this caused an issue with Jekyll:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
</pre></td><td class="rouge-code"><pre>bundler: failed to load command: jekyll (/Users/bbatsov/.rbenv/versions/3.4.1/bin/jekyll)
&lt;internal:/Users/bbatsov/.rbenv/versions/3.4.1/lib/ruby/3.4.0/rubygems/core_ext/kernel_require.rb&gt;:37:in 'Kernel#require': cannot load such file -- csv (LoadError)
        from &lt;internal:/Users/bbatsov/.rbenv/versions/3.4.1/lib/ruby/3.4.0/rubygems/core_ext/kernel_require.rb&gt;:37:in 'Kernel#require'
        from /Users/bbatsov/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/jekyll-4.3.4/lib/jekyll.rb:28:in '&lt;top (required)&gt;'
        from &lt;internal:/Users/bbatsov/.rbenv/versions/3.4.1/lib/ruby/3.4.0/rubygems/core_ext/kernel_require.rb&gt;:37:in 'Kernel#require'
        from &lt;internal:/Users/bbatsov/.rbenv/versions/3.4.1/lib/ruby/3.4.0/rubygems/core_ext/kernel_require.rb&gt;:37:in 'Kernel#require'
        from /Users/bbatsov/.rbenv/versions/3.4.1/lib/ruby/gems/3.4.0/gems/jekyll-4.3.4/exe/jekyll:8:in '&lt;top (required)&gt;'
        from /Users/bbatsov/.rbenv/versions/3.4.1/bin/jekyll:25:in 'Kernel#load'
        from /Users/bbatsov/.rbenv/versions/3.4.1/bin/jekyll:25:in '&lt;top (required)&gt;'
</pre></td></tr></tbody></table></code></pre></div></div>

<p>At first I thought that updating to the latest version of Jekyll<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> with
<code class="language-plaintext highlighter-rouge">bundle update</code> would be enough to address this problem, but it turned out that
wasn’t the case.</p>

<p>It wasn’t hard to guess that the <code class="language-plaintext highlighter-rouge">csv</code> library has been removed from Ruby’s <code class="language-plaintext highlighter-rouge">stdlib</code> in Ruby 3.4, as the process to
move non-essential libraries out of the standard library has been ongoing for years now. So, I’ve added <code class="language-plaintext highlighter-rouge">csv</code> to
my <code class="language-plaintext highlighter-rouge">Gemfile</code>, did a <code class="language-plaintext highlighter-rouge">bundle install</code> and… got an error that <code class="language-plaintext highlighter-rouge">base64</code> was missing as well… Oh, well…</p>

<p>At the end of the day the solution to the problem is to add these 2 lines to your <code class="language-plaintext highlighter-rouge">Gemfile</code>:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="c1"># TODO: Remove when this gets fixed in Jekyll</span>
<span class="n">gem</span> <span class="s2">"csv"</span>
<span class="n">gem</span> <span class="s2">"base64"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Don’t forget to run <code class="language-plaintext highlighter-rouge">bundle install</code> afterwards.</p>

<p>Eventually those libraries will be made Jekyll runtime dependencies and when a
new version of Jekyll is released with this change, you can remove them from your
<code class="language-plaintext highlighter-rouge">Gemfile</code>. I’ve noticed there’s already <a href="https://github.com/jekyll/jekyll/pull/9736">a Jekyll
PR</a> to address this problem, but it might be
a while until it’s merged and a new release is cut. Sadly, Jekyll is pretty
close to abandonware these days and every time something like this happens I’m
thinking that I should probably look more closely into the alternatives.</p>

<p>That’s all I have for you today. Keep hacking!</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>That’s Jekyll 4.3 at the time I’m writing this. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Bozhidar Batsov</name></author><category term="Jekyll" /><category term="Ruby" /><summary type="html"><![CDATA[Yesterday I’ve installed the newly released Ruby 3.4, but this caused an issue with Jekyll:]]></summary></entry><entry><title type="html">Updating the Bundler Version Specified in Gemfile.lock</title><link href="https://batsov.com/articles/2023/04/09/updating-the-bundler-version-specified-in-gemfile-lock/" rel="alternate" type="text/html" title="Updating the Bundler Version Specified in Gemfile.lock" /><published>2023-04-09T19:29:00+03:00</published><updated>2023-04-09T19:29:00+03:00</updated><id>https://batsov.com/articles/2023/04/09/updating-the-bundler-version-specified-in-gemfile-lock</id><content type="html" xml:base="https://batsov.com/articles/2023/04/09/updating-the-bundler-version-specified-in-gemfile-lock/"><![CDATA[<p>You might have noticed one change introduced with Bundler 2.3 - it now requires you to run the version of Bundler that’s specified in your <code class="language-plaintext highlighter-rouge">Gemfile.lock</code>.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> This means that occasionally you might see something like this:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>bundle
<span class="go">Bundler 2.4.6 is running, but your lockfile was generated with 1.17.2. Installing Bundler 1.17.2 and restarting using that version.
Fetching gem metadata from https://rubygems.org/.
Fetching bundler 1.17.2
Installing bundler 1.17.2
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Bundler does the safe thing automatically, but you can easily update the required Bundler version like this:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>bundle update <span class="nt">--bundler</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Pretty meta, right?</p>

<p>I needed to do this earlier today, when I noticed that Bundler 1.x is not
compatible with Ruby 3. It took me a few minutes to recall the right way to update
the required version of Bundler, so I thought to write this short article for
posterity’s sake.</p>

<p>That’s all I have for you today. Keep hacking!</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p><a href="https://bundler.io/blog/2022/01/23/bundler-v2-3.html">https://bundler.io/blog/2022/01/23/bundler-v2-3.html</a> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><category term="Bundler" /><summary type="html"><![CDATA[You might have noticed one change introduced with Bundler 2.3 - it now requires you to run the version of Bundler that’s specified in your Gemfile.lock.1 This means that occasionally you might see something like this: https://bundler.io/blog/2022/01/23/bundler-v2-3.html &#8617;&#xfe0e;]]></summary></entry><entry><title type="html">Bad Ruby: Hash Value Omission</title><link href="https://batsov.com/articles/2022/01/20/bad-ruby-hash-value-omission/" rel="alternate" type="text/html" title="Bad Ruby: Hash Value Omission" /><published>2022-01-20T14:09:00+02:00</published><updated>2022-01-21T00:00:00+02:00</updated><id>https://batsov.com/articles/2022/01/20/bad-ruby-hash-value-omission</id><content type="html" xml:base="https://batsov.com/articles/2022/01/20/bad-ruby-hash-value-omission/"><![CDATA[<p>Ruby 3.1 was recently released and it features one major syntax addition - you can now omit values in hash literals and keyword arguments in certain cases.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> The <a href="https://www.ruby-lang.org/en/news/2021/12/25/ruby-3-1-0-released/">release notes</a> give the following examples:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">{x:, y:}</code> is syntax sugar for <code class="language-plaintext highlighter-rouge">{x: x, y: y}</code>.</li>
  <li><code class="language-plaintext highlighter-rouge">foo(x:, y:)</code> is syntax sugar for <code class="language-plaintext highlighter-rouge">foo(x: x, y: y)</code>.</li>
</ul>

<p>Note that <code class="language-plaintext highlighter-rouge">x</code> and <code class="language-plaintext highlighter-rouge">y</code> are local variables that are in scope. My first reaction was “WTF???”. My second reaction was to check how this made it to the language.</p>

<p>The <a href="https://bugs.ruby-lang.org/issues/14579">feature request ticket</a> has a few more usage examples:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
</pre></td><td class="rouge-code"><pre><span class="n">x</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">y</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">{</span><span class="n">x</span><span class="p">:,</span> <span class="n">y</span><span class="p">:}</span>
<span class="nb">p</span> <span class="n">h</span> <span class="c1"># =&gt; {:x=&gt;1, :y=&gt;2}</span>

<span class="k">def</span> <span class="nf">login</span><span class="p">(</span><span class="ss">username: </span><span class="no">ENV</span><span class="p">[</span><span class="s2">"USER"</span><span class="p">],</span> <span class="n">password</span><span class="p">:)</span>
  <span class="nb">p</span><span class="p">(</span><span class="n">username</span><span class="p">:,</span> <span class="n">password</span><span class="p">:)</span>
<span class="k">end</span>

<span class="n">login</span><span class="p">(</span><span class="ss">password: </span><span class="s2">"xxx"</span><span class="p">)</span> <span class="c1"># =&gt; {:username=&gt;"shugo", :password=&gt;"xxx"}</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>What it doesn’t have, however, is any rationale behind the proposed change. Weird. I get that the idea is to emulate the syntax of JavaScript’s object punning, but I find this to be quite misguided if the end result is reduced code readability.<sup id="fnref:2"><a href="#fn:2" class="footnote" rel="footnote" role="doc-noteref">2</a></sup> What’s the point in copying features from other languages if they don’t add value to Ruby itself? What’s the point
of shaving off a few characters/keystrokes if the reader of the code might struggle to understand it?</p>

<p>I’ve noticed that everyone reacted negatively to the proposal initially, including <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/86123">Matz</a>:</p>

<blockquote>
  <p>I prefer this syntax to #11105, but this introduces a Ruby-specific syntax different from ES6 syntax.</p>

  <p>Besides that, I don’t like both anyway because they are not intuitive (for me).</p>

  <p>– Matz</p>
</blockquote>

<p>This was in 2018. 4 years later, however, he changed his mind:</p>

<blockquote>
  <p>After the RubyKaigi 2021 sessions, we have discussed this issue and I was finally persuaded.
Our mindset has been updated (mostly due to mandatory keyword arguments).
Accepted.</p>
</blockquote>

<p>Oh, well… Sadly, no one bothered to share those convincing arguments in the ticket itself. I’m disappointed that in the end of the day the result is more complexity in the core language that serves mostly to allow writing shorter, but harder to read code. We should never forget the following words of wisdom:</p>

<blockquote>
  <p>Programs must be written for people to read, and only incidentally for machines to execute.</p>

  <p>– Harold Abelson, Structure and Interpretation of Computer Programs</p>
</blockquote>

<p>So, why do I feel that the new syntax makes things harder to read?</p>

<ul>
  <li>at a glance <code class="language-plaintext highlighter-rouge">{x:, y:}</code> seems like a hash without values. Simple as that. Yeah, when I know about the new syntax I’ll infer that there are some
locals with the same names as the keys that are currently in scope, but why bother with all of this? Explicit is (almost always) better than implicit when it
comes to code readability/maintainability!</li>
  <li>modern editors and IDEs are already quite smart - if you want to type less, such a problem can be solved at this level (e.g. IDEs would infer that you probably want to put <code class="language-plaintext highlighter-rouge">x</code> after <code class="language-plaintext highlighter-rouge">x:</code>).</li>
  <li>how can I jump the local variable at point (e.g. I want to inspect it) if there’s no local variable at point?</li>
  <li>there are also some “fun” cases to consider:</li>
</ul>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="rouge-code"><pre><span class="c1"># the shorthand somewhat surprisingly works with methods without params</span>
<span class="k">def</span> <span class="nf">destroy</span> <span class="p">();</span> <span class="nb">puts</span> <span class="s2">"surprise"</span><span class="p">;</span> <span class="k">end</span>

<span class="p">{</span><span class="n">destroy</span><span class="p">:}</span> <span class="c1"># this will print "surprise"</span>

<span class="c1"># do you think this code behaved the same way before Ruby 3.1 and in Ruby 3.1?</span>
<span class="c1"># see - https://github.com/rubocop/rubocop/issues/10359</span>
<span class="k">def</span> <span class="nf">some_method</span><span class="p">(</span><span class="n">token</span><span class="p">)</span>
  <span class="n">user</span> <span class="o">=</span> <span class="n">double</span> <span class="ss">:user</span><span class="p">,</span> <span class="ss">id: </span><span class="mi">42</span><span class="p">,</span> <span class="ss">token:
  </span><span class="n">described_class</span><span class="p">.</span><span class="nf">build</span><span class="p">(</span><span class="n">user</span><span class="p">)</span>
<span class="k">end</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Not to mention that this complicated further Ruby’s already complicated parsers
and created a boatload of work for me and the other members of RuboCop’s team.
Observing some of the interactions of the new syntax with other Ruby code
(e.g. method calls using the new syntax followed by conditional modifiers) left
me believing that the full implications of this were not carefully thought out.</p>

<p>I’m left pondering if I’d feel differently about the feature if it was
implemented in terms of a different syntax, that’s not so ambiguous. Probably
yes.  Still, I’ve decided to give this syntax the benefit of the doubt and not
discourage it in the default RuboCop configuration (RuboCop introduced support
for Ruby 3.1 in version 1.24). As usual I’ll leave it to the broader community
to figure out if something will become a Ruby idiom in the long run or not.</p>

<blockquote>
  <p>Adopting new syntax is usually the least effective productivity improvement.</p>

  <p>And a language where the most easy path of change is such syntax additions is not providing the evolutionary path for meaningful improvements.</p>

  <p>– Markus Schirp</p>
</blockquote>

<p>This episode is just a continuation of the all the language changes in Ruby in recent years that I’ve found detrimental and that eventually prompted me to write my short essay <a href="https://metaredux.com/posts/2019/04/02/ruby-s-creed.html">Ruby’s Creed</a> in 2019. It’s clear to me at this point that Ruby’s direction hasn’t changed and is unlikely to change. That makes me sad. I thought Ruby was all about programmer happiness.<sup id="fnref:3"><a href="#fn:3" class="footnote" rel="footnote" role="doc-noteref">3</a></sup></p>

<p>I can only hope that I’m in the minority and the hash punning syntax makes the majority of the Ruby programmers happy. Be happy!</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>The feature is officially named “hash value omission”. It’s also known as “hash punning” after the similar “object punning” in JavaScript. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
    <li id="fn:2">
      <p>There is a bit more rationale in <a href="https://bugs.ruby-lang.org/issues/17292">another ticket</a>. <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
    <li id="fn:3">
      <p>I have no doubt this change made someone happy, but I also wonder how many people did it leave as frustrated as me. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><category term="Language Design" /><category term="Code Style" /><summary type="html"><![CDATA[Ruby 3.1 was recently released and it features one major syntax addition - you can now omit values in hash literals and keyword arguments in certain cases.1 The release notes give the following examples: The feature is officially named “hash value omission”. It’s also known as “hash punning” after the similar “object punning” in JavaScript. &#8617;&#xfe0e;]]></summary></entry><entry><title type="html">Inspecting the Contents of a Ruby Gem</title><link href="https://batsov.com/articles/2020/12/16/inspecting-the-contents-of-a-ruby-gem/" rel="alternate" type="text/html" title="Inspecting the Contents of a Ruby Gem" /><published>2020-12-16T10:17:00+02:00</published><updated>2020-12-16T10:17:00+02:00</updated><id>https://batsov.com/articles/2020/12/16/inspecting-the-contents-of-a-ruby-gem</id><content type="html" xml:base="https://batsov.com/articles/2020/12/16/inspecting-the-contents-of-a-ruby-gem/"><![CDATA[<p>From time to time you’ll need to inspect the contents of a locally
installed Ruby gem. For instance - I needed to check the contents
of my Jekyll theme (<code class="language-plaintext highlighter-rouge">minima</code>) earlier today, so I could override something
that was hardcoded there.</p>

<p>Each installed gem corresponds to a directory
in your local file system, so all you need to do is find out where
a particular gem resides. There are several ways to do this.
The first option is to use Ruby’s <code class="language-plaintext highlighter-rouge">gem</code> command directly:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>gem info minima
<span class="go">
*** LOCAL GEMS ***

minima (2.5.1)
    Author: Joel Glovier
    Homepage: https://github.com/jekyll/minima
    License: MIT
    Installed at: /home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0

    A beautiful, minimal theme for Jekyll.

</span><span class="gp">$</span><span class="w"> </span>gem contents minima
<span class="go">/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/LICENSE.txt
/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/README.md
/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/_includes/disqus_comments.html
/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/_includes/footer.html
/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/_includes/google-analytics.html
/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/_includes/head.html
/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1/_includes/header.html
</span><span class="c">...
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">gem contents</code> command is extra useful as it effectively combines something like this in a single step:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>gem info gem-name
<span class="gp">$</span><span class="w"> </span><span class="nb">cd </span>gem-dir
<span class="gp">$</span><span class="w"> </span><span class="nb">ls</span> <span class="nt">-l</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>You don’t really have to visit the folder in which the installed gem
resides to play with its contents. With <code class="language-plaintext highlighter-rouge">gem unpack</code> you can dump the
contents of any gem in the current folder:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>gem unpack minima
<span class="go">Unpacked gem: '/home/bozhidar/minima-2.5.1'
</span><span class="gp">#</span><span class="w"> </span>You can also specify the folder <span class="k">in </span>which to unpack the gem like this
<span class="gp">$</span><span class="w"> </span>gem unpack minima <span class="nt">--target</span> ~/unpacked-gems
</pre></td></tr></tbody></table></code></pre></div></div>

<p>The main benefit of using <code class="language-plaintext highlighter-rouge">gem unpack</code> is that you can’t modify some gem by accident, with the added bonus that you’ll
get an easier to remember directory path.</p>

<p>An alternative option is to use <code class="language-plaintext highlighter-rouge">bundler</code> to procure the gem installation directory information (assuming you’re using it):</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>bundle info minima
<span class="go">
 * minima (2.5.1)
        Summary: A beautiful, minimal theme for Jekyll.
        Homepage: https://github.com/jekyll/minima
        Path: /home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1

</span><span class="gp">#</span><span class="w"> </span>This is a variant of the previous <span class="nb">command </span>that returns only the gem path
<span class="gp">$</span><span class="w"> </span>bundle info <span class="nt">--path</span> minima
<span class="go">/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1
</span><span class="gp">#</span><span class="w"> </span>Alternatively you can use Bundler<span class="s1">'s show command
</span><span class="gp">$</span><span class="w"> </span><span class="s1">bundle show minima
</span><span class="go">/home/bozhidar/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/minima-2.5.1
</span></pre></td></tr></tbody></table></code></pre></div></div>

<p>Unfortunately, there’s no <code class="language-plaintext highlighter-rouge">bundler</code> equivalent of the <code class="language-plaintext highlighter-rouge">gem contents</code> command, but that’s not
that big of a deal.</p>

<p>Bundler and <code class="language-plaintext highlighter-rouge">gem</code> actually have one more
extremely useful command that will directly open the gem’s folder in
your default editor:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>gem open minima
<span class="gp">#</span><span class="w"> </span>or alternatively
<span class="gp">$</span><span class="w"> </span>bundle open minima
</pre></td></tr></tbody></table></code></pre></div></div>

<p>Probably that’s my favorite way to navigate to an installed gem’s contents.</p>

<p>As you can imagine it’s pretty straight-forward to change the behavior of a gem - just go to its directory and
edit some of its contents. That’s a useful debugging technique, but it opens up one question - how to restore
a gem to its original pristine state? Well, turns out there’s a command for this as well:</p>

<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
</pre></td><td class="rouge-code"><pre><span class="gp">$</span><span class="w"> </span>gem pristine gem-name
<span class="gp">#</span><span class="w"> </span>or alternatively
<span class="gp">$</span><span class="w"> </span>bundle pristine
</pre></td></tr></tbody></table></code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">bundler</code> command will restore all installed gems for a particular bundle to their original state.</p>

<p>That’s all I have for you today. I hope you learned something useful! Keep hacking!</p>]]></content><author><name>Bozhidar Batsov</name></author><category term="Tips" /><category term="Ruby" /><summary type="html"><![CDATA[From time to time you’ll need to inspect the contents of a locally installed Ruby gem. For instance - I needed to check the contents of my Jekyll theme (minima) earlier today, so I could override something that was hardcoded there.]]></summary></entry><entry><title type="html">Going Rogue</title><link href="https://batsov.com/articles/2018/11/17/going-rogue/" rel="alternate" type="text/html" title="Going Rogue" /><published>2018-11-17T12:45:00+02:00</published><updated>2018-11-17T12:45:00+02:00</updated><id>https://batsov.com/articles/2018/11/17/going-rogue</id><content type="html" xml:base="https://batsov.com/articles/2018/11/17/going-rogue/"><![CDATA[<p>For many years I’ve enjoyed listening to programming podcasts - it’s
the perfect way to make a commute a bit more fun and
educational.<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> <a href="https://devchat.tv/ruby-rogues/">RubyRogues</a> was always
one of my favourite Ruby shows and I find it very amusing that
recently I ended up being their guest. I certainly didn’t see this coming!
Seems that a lot has changed since the days I followed it actively, but it
was still fun to make an appearance there.</p>

<p>If you’d like to listen to our conversation about RuboCop, Emacs and
the future of Ruby be sure to check out <a href="https://devchat.tv/ruby-rogues/rr-388-rubocop-and-emacs-i-guess-with-bozhidar-batsov/">this
episode</a>.</p>

<p>Until next time!</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>Since I started working remotely I practically stopped listening to any podcasts. One of the few downsides of remote work. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;&#xfe0e;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Bozhidar Batsov</name></author><category term="Meta" /><category term="Ruby" /><category term="Podcasts" /><summary type="html"><![CDATA[For many years I’ve enjoyed listening to programming podcasts - it’s the perfect way to make a commute a bit more fun and educational.1 RubyRogues was always one of my favourite Ruby shows and I find it very amusing that recently I ended up being their guest. I certainly didn’t see this coming! Seems that a lot has changed since the days I followed it actively, but it was still fun to make an appearance there. Since I started working remotely I practically stopped listening to any podcasts. One of the few downsides of remote work. &#8617;&#xfe0e;]]></summary></entry><entry><title type="html">RuboCop Logo</title><link href="https://batsov.com/articles/2014/09/05/rubocop-logo/" rel="alternate" type="text/html" title="RuboCop Logo" /><published>2014-09-05T14:16:00+03:00</published><updated>2014-09-05T14:16:00+03:00</updated><id>https://batsov.com/articles/2014/09/05/rubocop-logo</id><content type="html" xml:base="https://batsov.com/articles/2014/09/05/rubocop-logo/"><![CDATA[<p>Meet <a href="https://github.com/bbatsov/rubocop">RuboCop</a>’s brand new official logo!</p>

<p><img src="/assets/img/rubocop-logo.png" alt="RuboCop Logo" /></p>

<p>RuboCop’s logo was created by
<a href="https://www.chadomoto.com/">Dimiter Petrov</a> (the best designer I’ve
ever worked with!). You can find the logo in various formats
<a href="https://github.com/bbatsov/rubocop/tree/master/logo">here</a>.</p>

<p>The logo is licensed under a
<a href="http://creativecommons.org/licenses/by-nc/4.0/deed.en_GB">Creative Commons Attribution-NonCommercial 4.0 International License</a>.</p>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><category term="RuboCop" /><summary type="html"><![CDATA[Meet RuboCop’s brand new official logo!]]></summary></entry><entry><title type="html">The Elements of Style in Ruby #14: Variable Interpolation</title><link href="https://batsov.com/articles/2014/08/13/the-elements-of-style-in-ruby-number-14-variable-interpolation/" rel="alternate" type="text/html" title="The Elements of Style in Ruby #14: Variable Interpolation" /><published>2014-08-13T16:27:00+03:00</published><updated>2014-08-13T16:27:00+03:00</updated><id>https://batsov.com/articles/2014/08/13/the-elements-of-style-in-ruby-number-14-variable-interpolation</id><content type="html" xml:base="https://batsov.com/articles/2014/08/13/the-elements-of-style-in-ruby-number-14-variable-interpolation/"><![CDATA[<p>Most experienced Rubyists probably know that there are two ways to interpolate instance, class and global variables into
strings.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="c1"># compact notation (works only for instance/class/global vars)</span>
<span class="s2">"this is </span><span class="si">#$some_var</span><span class="s2">"</span>

<span class="c1"># standard notation (works for any expression)</span>
<span class="s2">"this is </span><span class="si">#{</span><span class="vg">$some_var</span><span class="si">}</span><span class="s2">"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>As you’ve noticed you can leave out the <code class="language-plaintext highlighter-rouge">{}</code> which can’t be left out for any other expression. Some people find this
interpolation syntax concise and elegant, but I’ll argue that it should be avoided. Here’s why:</p>

<ul>
  <li>You can’t use this notation in every possible scenario:</li>
</ul>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
</pre></td><td class="rouge-code"><pre><span class="c1"># this is fine</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="vi">@variable</span><span class="si">}</span><span class="s2">string_straight_after_without_space"</span>

<span class="c1"># but this means something totally different</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#@variablestring_straight_after_without_space</span><span class="s2">"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<p>This means that using the compact notation only when applicable forces you to introduce some inconsistency in your code.
This is rarely good…</p>

<ul>
  <li>You’re using different notations for the same basic operation (interpolation), without getting anything in return.
That’s not the same with semantic use of single and double quoted strings or <code class="language-plaintext highlighter-rouge">fail</code> and <code class="language-plaintext highlighter-rouge">raise</code>.</li>
</ul>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><table class="rouge-table"><tbody><tr><td class="rouge-gutter gl"><pre class="lineno">1
2
3
4
5
6
7
</pre></td><td class="rouge-code"><pre><span class="c1"># using compact</span>
<span class="s2">"this is </span><span class="si">#@x</span><span class="s2">"</span>
<span class="s2">"this is </span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="s2">"</span>

<span class="c1"># using standard</span>
<span class="s2">"this is </span><span class="si">#{</span><span class="vi">@x</span><span class="si">}</span><span class="s2">"</span>
<span class="s2">"this is </span><span class="si">#{</span><span class="n">x</span><span class="si">}</span><span class="s2">"</span>
</pre></td></tr></tbody></table></code></pre></div></div>

<ul>
  <li>It’s easy to make a mistake in the context of a regular expression
(as interpolation works in regexp literals).  Recently I saw the
following regexp - <code class="language-plaintext highlighter-rouge">/[0-9.(),;:!?%#$?\x27\x22_+=\\\/\-]*/</code>. There’s a
subtle problem with it, that’s not obvious (unless you have a good
editor, that is). The sequence <code class="language-plaintext highlighter-rouge">#$?</code> is interpreted as interpolation
of the global variable <code class="language-plaintext highlighter-rouge">$?</code> (a.k.a. <code class="language-plaintext highlighter-rouge">$CHILD_STATUS</code>) and this regexp doesn’t work as intended.</li>
</ul>

<p>This scenario shows that the syntax was ill-conceived.</p>

<ul>
  <li>Inexperienced Rubyists probably don’t know about the compact interpolation notation.
Few books and tutorials mention it these days, so using it your code will confuse at least
some of the people reading it.</li>
</ul>

<hr />

<p>It seems to me that Ruby will be better off without a special syntax
for variable interpolation. Ideally it would be removed in Ruby 3 and
we’ll have one less thing to worry about in our Ruby code.</p>

<p>That’s all for today, folks!</p>

<p>As usual I’m looking forward to hearing your thoughts here and on
<a href="http://twitter.com/bbatsov">Twitter</a>!</p>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><category term="Style" /><summary type="html"><![CDATA[Most experienced Rubyists probably know that there are two ways to interpolate instance, class and global variables into strings.]]></summary></entry><entry><title type="html">Permalinks in the Ruby and Rails style guides</title><link href="https://batsov.com/articles/2014/07/25/permalinks-in-the-ruby-and-rails-style-guides/" rel="alternate" type="text/html" title="Permalinks in the Ruby and Rails style guides" /><published>2014-07-25T16:34:00+03:00</published><updated>2014-07-25T16:34:00+03:00</updated><id>https://batsov.com/articles/2014/07/25/permalinks-in-the-ruby-and-rails-style-guides</id><content type="html" xml:base="https://batsov.com/articles/2014/07/25/permalinks-in-the-ruby-and-rails-style-guides/"><![CDATA[<p>I’m happy to report that now you can use permalinks to the rules listed in the
community <a href="https://github.com/rubocop/ruby-style-guide">Ruby</a> and <a href="https://github.com/rubocop/rails-style-guide">Rails</a> style guides.</p>

<p>Here’s an
<a href="https://github.com/rubocop/ruby-style-guide#indent-when-to-case">example</a>.
Now you can easily refer to rules in heated style debates with your
friends and co-workers.</p>

<p>This is an addition that was way overdue (for which I take all the
blame). I’d like to say a big <code class="language-plaintext highlighter-rouge">THANKS!!!</code> to <a href="https://github.com/todb">Tod Beardsley</a> who
found the time I never did and got the job done (in style).</p>

<p><strong>P.S.</strong> Hopefully soon the permalinks will be leveraged by RuboCop.</p>]]></content><author><name>Bozhidar Batsov</name></author><category term="Ruby" /><summary type="html"><![CDATA[I’m happy to report that now you can use permalinks to the rules listed in the community Ruby and Rails style guides.]]></summary></entry></feed>