<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xml:lang="en-US">
  <title>BigBinary Blog: Ruby 3.1</title>
  <subtitle>Deep technical writing on Ruby on Rails, performance, scaling, monitoring and engineering.</subtitle>
  <link rel="self" type="application/atom+xml" href="https://www.bigbinary.com/blog/categories/ruby-3-1/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/categories/ruby-3-1"/>
  <id>https://www.bigbinary.com/blog/categories/ruby-3-1</id>
  <updated>2021-12-27T00:00:00.000Z</updated>
  <author>
    <name>BigBinary</name>
    <uri>https://www.bigbinary.com/</uri>
  </author>
  <icon>https://www.bigbinary.com/favicon.ico</icon>
  <logo>https://www.bigbinary.com/images/bigbinary_square_big_logo.png</logo>
  <rights>Copyright 2021 Big Binary LLC</rights>
  <generator uri="https://nextjs.org">Next.js</generator>
  <entry>
      <title type="text"><![CDATA[Ruby 3.1 adds Class#subclasses]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-3-1-adds-class-subclasses"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-class-subclasses.png"/>
      <id>https://www.bigbinary.com/blog/ruby-3-1-adds-class-subclasses</id>
      <published>2021-12-27T00:00:00.000Z</published>
      <updated>2021-12-27T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 3.1"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-class-subclasses.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 3.1 introduces the Class#subclasses method, which returns all classes directly inheriting from the receiver without including singleton classes. We can see many implementations for calculating...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-3-1-adds-class-subclasses"><![CDATA[<p>Ruby 3.1 introduces the <code>Class#subclasses</code> method, which returns all classes
directly inheriting from the receiver without including singleton classes.</p>
<p>We can see many implementations for calculating all subclasses of a particular
class from the Ruby community with different gems. The
<a href="https://api.rubyonrails.org/classes/ActiveSupport/DescendantsTracker.html#method-c-subclasses">ActiveSupport::DescendantsTracker</a>
is one of such implementations used in Rails framework. Finally, Ruby has added
the <code>Class#subclasses</code> native implementation for it's 3.1 version release.</p>
<h2>After Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; class User; end
=&gt; class Employee &lt; User; end
=&gt; class Client &lt; User; end

=&gt; class Manager &lt; Employee; end
=&gt; class Developer &lt; Employee; end

=&gt; User.subclasses
=&gt; [Employee, Client]

=&gt; Employee.subclasses
=&gt; [Manager, Developer]

=&gt; Developer.subclasses
=&gt; []
</code></pre>
<p>Here's the relevant <a href="https://github.com/ruby/ruby/pull/5045">pull request</a> and
<a href="https://bugs.ruby-lang.org/issues/18273">feature discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 3.1 adds MatchData#match & MatchData#match_length]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-3-1-adds-match-data-methods"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-match-data-methods.png"/>
      <id>https://www.bigbinary.com/blog/ruby-3-1-adds-match-data-methods</id>
      <published>2021-11-09T00:00:00.000Z</published>
      <updated>2021-11-09T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 3.1"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-match-data-methods.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 3.1 introduces the MatchData#match & MatchData#matchlength methods which returns the substring matched against a regular expression & it's length respectively. Before Ruby 3.1 We have...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-3-1-adds-match-data-methods"><![CDATA[<p>Ruby 3.1 introduces the <code>MatchData#match</code> &amp; <code>MatchData#match_length</code> methods
which returns the substring matched against a regular expression &amp; it's length
respectively.</p>
<pre><code class="language-ruby">=&gt; str = &quot;Ruby 3.1 introduces MatchData#match method&quot;
=&gt;  m = /(?&lt;lang&gt;\S+)(\s)(?&lt;version&gt;[\d\.]+)/.match(str)
=&gt; #&lt;MatchData &quot;Ruby 3.1&quot; lang:&quot;Ruby&quot; version:&quot;3.1&quot;&gt;
</code></pre>
<h3>Before Ruby 3.1</h3>
<p>We have <code>MatchData#[]</code> method to access all the substring groups that are
matched. We can access either a single match or multiple matches by giving a
single index or a range of indexes, respectively, using <code>MatchData#[]</code> method.</p>
<pre><code class="language-ruby">=&gt; m[:lang]
=&gt; &quot;Ruby&quot;

=&gt; m[1]
=&gt; &quot;Ruby&quot;
=&gt; m[:version]
=&gt; &quot;3.1&quot;

=&gt; m[0..2]
=&gt; [&quot;Ruby 3.1&quot;, &quot;Ruby&quot;, &quot;3.1&quot;]

=&gt; m[1..2]
=&gt; [&quot;Ruby&quot;, &quot;3.1&quot;]


=&gt; m[0].length
=&gt; 8
</code></pre>
<h3>After Ruby 3.1</h3>
<p>We have two new methods now to access the match data &amp; its length. The
<code>MatchData#match</code> &amp; <code>MatchData#match_length</code> methods accepts either an index or
a symbol as an argument to return the match data &amp; its length.</p>
<pre><code class="language-ruby">=&gt; m.match(0)
=&gt; &quot;Ruby 3.1&quot;

=&gt; m.match(:version)
=&gt; &quot;3.1&quot;

=&gt; m.match(3)
=&gt; nil

=&gt; m.match_length(0)
=&gt; 8

=&gt; m.match_length(:version)
=&gt; 3

=&gt; m.match_length(3)
=&gt; nil
</code></pre>
<p>Please note that <code>MatchData#match</code> is not same as <code>MatchData#[]</code> method. The
later accepts an optional length or range as an argument to return the matched
data but the former doesn't accept it, instead it allows only a single index or
symbol as an argument.</p>
<p>Here's the relevant <a href="https://github.com/ruby/ruby/pull/4851">pull request</a> and
<a href="https://bugs.ruby-lang.org/issues/18172">feature discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 3.1 adds Array#intersect?]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-3-1-adds-array-intersect"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-array-intersect.png"/>
      <id>https://www.bigbinary.com/blog/ruby-3-1-adds-array-intersect</id>
      <published>2021-05-11T00:00:00.000Z</published>
      <updated>2021-05-11T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 3.1"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-array-intersect.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 3.1 introduces the Array#intersect? method which returns boolean value true or false based on the given input arrays have common elements in it. We already know Array#intersection or Array#&...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-3-1-adds-array-intersect"><![CDATA[<p>Ruby 3.1 introduces the <code>Array#intersect?</code> method which returns boolean value
<code>true</code> or <code>false</code> based on the given input arrays have common elements in it.</p>
<p>We already know
<a href="https://ruby-doc.org/core-3.0.1/Array.html#method-i-intersection">Array#intersection or Array#&amp;</a>
methods which are used to find the common elements between arrays.</p>
<pre><code class="language-ruby">=&gt; x = [1, 2, 5, 8]
=&gt; y = [2, 4, 5, 9]
=&gt; z = [3, 7]

=&gt; x.intersection(y) # x &amp; y
=&gt; [2, 5]

=&gt; x.intersection(z) # x &amp; z
=&gt; []
</code></pre>
<p>The <code>intersection</code> or <code>&amp;</code> methods return an empty array or array having the
common elements in it as result. We have to further call <code>empty?</code>, <code>any?</code> or
<code>blank?</code> like methods to check whether two arrays intersect each other or not.</p>
<h2>Before Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; x.intersection(y).empty?
=&gt; false

=&gt; (x &amp; z).empty?
=&gt; true

=&gt; (y &amp; z).any?
=&gt; false
</code></pre>
<h2>After Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; x.intersect?(y)
=&gt; true

=&gt; y.intersect?(z)
=&gt; false
</code></pre>
<p>The <code>Array#intersect?</code> method accepts only single array as argument, but
<code>Array#intersection</code> method can accept multiple arrays as arguments.</p>
<pre><code class="language-ruby">=&gt; x.intersection(y, z) # x &amp; y &amp; z
=&gt; []
</code></pre>
<p>The newly introduced <code>intersect?</code> method is faster than the above described
checks using <code>intersection</code> or <code>&amp;</code> since the new method avoids creating an
intermediate array while evaluating for common elements. Also new method returns
<code>true</code> as soon as it finds a common element between arrays.</p>
<p>Here's the relevant <a href="https://github.com/ruby/ruby/pull/1972">pull request</a> and
<a href="https://bugs.ruby-lang.org/issues/15198">feature discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 3.1 accumulates Enumerable#tally results]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-3-1-accumulates-enumerable-tally-results"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-accumulates-enumerable-tally-results.png"/>
      <id>https://www.bigbinary.com/blog/ruby-3-1-accumulates-enumerable-tally-results</id>
      <published>2021-04-20T00:00:00.000Z</published>
      <updated>2021-04-20T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 3.1"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-accumulates-enumerable-tally-results.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[We already know the Enumerable#tally method is used to count the occurrences of each element in an Enumerable collection. The #tally method was introduced in ruby 2.7.0. Please check our blog for...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-3-1-accumulates-enumerable-tally-results"><![CDATA[<p>We already know the
<a href="https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-tally">Enumerable#tally</a>
method is used to count the occurrences of each element in an <code>Enumerable</code>
collection. The <code>#tally</code> method was introduced in ruby 2.7.0. Please check
<a href="https://bigbinary.com/blog/ruby-2-7-adds-enumerable-tally">our blog</a> for more
details on it.</p>
<p>Ruby 3.1 introduces an optional hash argument for the <code>Enumerable#tally</code> method
to count. If a hash is given, the total number of occurrences of each element is
added to the hash values and the final hash is returned.</p>
<h2>Ruby 2.7.0+</h2>
<pre><code class="language-ruby">=&gt; letters = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;a&quot;, &quot;d&quot;, &quot;c&quot;, &quot;a&quot;, &quot;c&quot;, &quot;a&quot;]
=&gt; result = letters.tally
=&gt; {&quot;a&quot;=&gt;4, &quot;b&quot;=&gt;1, &quot;c&quot;=&gt;3, &quot;d&quot;=&gt;1}
</code></pre>
<h2>Before Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; new_letters = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;a&quot;, &quot;c&quot;, &quot;a&quot;]
=&gt; new_letters.tally(result)
=&gt; ArgumentError (wrong number of arguments (given 1, expected 0))
</code></pre>
<h2>After Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; new_letters = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;a&quot;, &quot;c&quot;, &quot;a&quot;]
=&gt; new_letters.tally(result)
=&gt; {&quot;a&quot;=&gt;7, &quot;b&quot;=&gt;2, &quot;c&quot;=&gt;5, &quot;d&quot;=&gt;1}
</code></pre>
<p>The value corresponding to each element in the hash must be an integer.
Otherwise, the method raises <code>TypeError</code> on execution.</p>
<p>If the default value is defined for the given hash, it will be ignored and the
count of occurrences will be added in the returned hash.</p>
<pre><code class="language-ruby">=&gt; letters = [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;a&quot;]
=&gt; letters.tally(Hash.new(10))
=&gt; {&quot;a&quot;=&gt;2, &quot;b&quot;=&gt;1, &quot;c&quot;=&gt;1}
</code></pre>
<p>Here's the relevant <a href="https://github.com/ruby/ruby/pull/4318">pull request</a> and
<a href="https://bugs.ruby-lang.org/issues/17744">feature discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 3.1 adds Enumerable#compact and Lazy#compact]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-3-1-adds-enumerable-compact"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-enumerable-compact.png"/>
      <id>https://www.bigbinary.com/blog/ruby-3-1-adds-enumerable-compact</id>
      <published>2021-04-06T00:00:00.000Z</published>
      <updated>2021-04-06T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 3.1"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-3-1-adds-enumerable-compact.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 3.1 adds Enumerable#compact and Enumerator::Lazy#compact]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-3-1-adds-enumerable-compact"><![CDATA[<p>We are familiar with the
<a href="https://apidock.com/ruby/v1_9_3_392/Array/compact">compact</a> method associated
with arrays. The <code>compact</code> method returns a copy of the array after removing all
<code>nil</code> elements.</p>
<p>Ruby 3.1 introduces the <code>compact</code> method in the <code>Enumerable</code> module. Now we can
use the <code>compact</code> method along with the <code>Enumerator</code> and <code>Enumerator::Lazy</code>
classes which include the <code>Enumerable</code> module.</p>
<h2>Before Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; enum = [1, nil, 3, nil, 5].to_enum
=&gt; #&lt;Enumerator: ...&gt;

=&gt; enum.compact
=&gt; NoMethodError (undefined method `compact' for #&lt;Enumerator: [1, nil, 3, nil, 5]:each&gt;)

=&gt;  enum.reject { |x| x.nil? }
=&gt; [1, 3, 5]
</code></pre>
<h2>After Ruby 3.1</h2>
<pre><code class="language-ruby">=&gt; enum = [1, nil, 3, nil, 5].to_enum
=&gt; #&lt;Enumerator: ...&gt;

=&gt; enum.compact
=&gt; [1, 3, 5]
</code></pre>
<p>We can access the <code>compact</code> method to remove all <code>nil</code> occurrences from any
classes where we include the <code>Enumerable</code> module.</p>
<pre><code class="language-ruby">class Person
  include Enumerable

  attr_accessor :names

  def initialize(names = [])
    @names = names
  end

  def each &amp;block
    @names.each(&amp;block)
  end
end

=&gt; list = Person.new([&quot;John&quot;, nil, &quot;James&quot;, nil])
=&gt; #&lt;Person:0x0000000101cd3de8 @names=[&quot;John&quot;, nil, &quot;James&quot;, nil]&gt;

=&gt; list.compact
=&gt; [&quot;John&quot;, &quot;James&quot;]
</code></pre>
<p>Similarly, lazy evaluation can be chained with the <code>compact</code> method to remove
all <code>nil</code> entries from the <code>Enumerator</code> collection.</p>
<pre><code class="language-ruby">=&gt; enum = [1, nil, 3, nil, 5].to_enum.lazy.compact
=&gt; #&lt;Enumerator::Lazy: ...&gt;

=&gt; enum.force
=&gt; [1, 3, 5]


=&gt; list = Person.new([&quot;John&quot;, nil, &quot;James&quot;, nil]).lazy.compact
=&gt; #&lt;Enumerator::Lazy: ...&gt;

=&gt; list.force
=&gt; [&quot;John&quot;, &quot;James&quot;]
</code></pre>
<p>Here's the relevant <a href="https://github.com/ruby/ruby/pull/3851">pull request</a> and
<a href="https://bugs.ruby-lang.org/issues/17312">feature discussion</a> for this change.</p>
]]></content>
    </entry>
</feed>