<?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 2.7</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-2-7/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/categories/ruby-2-7"/>
  <id>https://www.bigbinary.com/blog/categories/ruby-2-7</id>
  <updated>2020-08-25T00: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 2020 Big Binary LLC</rights>
  <generator uri="https://nextjs.org">Next.js</generator>
  <entry>
      <title type="text"><![CDATA[Ruby 2.7 adds Beginless Range]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-7-adds-beginless-range"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-beginless-range.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-7-adds-beginless-range</id>
      <published>2020-08-25T00:00:00.000Z</published>
      <updated>2020-08-25T00:00:00.000Z</updated>
      <author>
        <name>Ashwath Biradar</name>
        <uri>https://www.bigbinary.com/blog/authors/ashwath</uri>
      </author>
      <category term="Ruby 2.7"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-beginless-range.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.7 added support for Beginless Range which makes the start of range an optional parameter. (..100) is a Beginless Range and it is equivalent to (nil..100). Let's see how Beginless Range could...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-7-adds-beginless-range"><![CDATA[<p>Ruby 2.7 added support for
<a href="https://ruby-doc.org/core-2.7.0/Range.html#class-Range-label-Beginless-2FEndless+Ranges">Beginless Range</a>
which makes the start of range an optional parameter.</p>
<p><code>(..100)</code> is a Beginless Range and it is equivalent to <code>(nil..100)</code>.</p>
<p>Let's see how Beginless Range could be used.</p>
<pre><code class="language-ruby">&gt; array = (1..10).to_a

# Select first 6 elements
&gt; array[..5]
=&gt; [1, 2, 3, 4, 5, 6]

# Select first 5 elements
&gt; array[...5]
=&gt; [1, 2, 3, 4, 5]

# grep (INFINITY..5) in (1..5)
&gt; (1..10).grep(..5)
=&gt; [1, 2, 3, 4, 5]

# (..100) is equivalent to (nil..100)
&gt; (..100) == (nil..100)
=&gt; true
</code></pre>
<p>Here is another example where in the <code>case</code> statement the condition can be read
as <code>below the specified level</code>.</p>
<pre><code class="language-ruby">case temperature
when ..-15
  puts &quot;Deep Freeze&quot;
when -15..8
  puts &quot;Refrigerator&quot;
when 8..15
  puts &quot;Cold&quot;
when 15..25
  puts &quot;Room Temperature&quot;
when (25..)   # Kindly notice the brackets here
  puts &quot;Hot&quot;
end
</code></pre>
<p>It can also be used for defining constants for ranges.</p>
<pre><code class="language-ruby">TEMPERATURE = {
  ..-15  =&gt; :deep_freeze,
  -15..8 =&gt; :refrigerator,
  8..15  =&gt; :cold,
  15..25 =&gt; :room_temperature,
  25..   =&gt; :hot
end
</code></pre>
<p>Using Beginless Range in DSL makes it easier to write conditions and it looks
more natural.</p>
<pre><code class="language-ruby">
# In Rails
User.where(created_at: (..DateTime.now))
# User Load (2.2ms)  SELECT &quot;users&quot;.* FROM &quot;users&quot; WHERE &quot;users&quot;.&quot;created_at&quot; &lt;= $1 LIMIT $2  [[&quot;created_at&quot;, &quot;2020-08-05 15:00:19.111217&quot;], [&quot;LIMIT&quot;, 11]]


# In RubySpec
ruby_version(..'1.9') do
# Tests for old Ruby
end
</code></pre>
<p>Here is the relevant
<a href="https://github.com/ruby/ruby/commit/95f7992b89efd35de6b28ac095c4d3477019c583">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/14799">discussion</a> regarding this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.7 adds Enumerable#filter_map]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-7-adds-enumerable-filter-map"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-enumerable-filter-map.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-7-adds-enumerable-filter-map</id>
      <published>2020-05-08T00:00:00.000Z</published>
      <updated>2020-05-08T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 2.7"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-enumerable-filter-map.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.7 adds Enumerable#filtermap which is a combination of filter + map as the name indicates. The 'filtermap' method filters and map the enumerable elements within a single iteration. Before Ruby...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-7-adds-enumerable-filter-map"><![CDATA[<p>Ruby 2.7 adds
<a href="https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-filter_map">Enumerable#filter_map</a>
which is a combination of filter + map as the name indicates. The 'filter_map'
method filters and map the enumerable elements within a single iteration.</p>
<p>Before Ruby 2.7, we could have achieved the same with 2 iterations using
<code>select</code> &amp; <code>map</code> combination or <code>map</code> &amp; <code>compact</code> combination.</p>
<pre><code class="language-ruby">
irb&gt; numbers = [3, 6, 7, 9, 5, 4]

# we can use select &amp; map to find square of odd numbers

irb&gt; numbers.select { |x| x.odd? }.map { |x| x**2 }
=&gt; [9, 49, 81, 25]

# or we can use map &amp; compact to find square of odd numbers

irb&gt; numbers.map { |x| x**2 if x.odd? }.compact
=&gt; [9, 49, 81, 25]

</code></pre>
<h4>Ruby 2.7</h4>
<p>Ruby 2.7 adds <code>Enumerable#filter_map</code> which can be used to filter &amp; map the
elements in a single iteration and which is more faster when compared to other
options described above.</p>
<pre><code class="language-ruby">irb&gt; numbers = [3, 6, 7, 9, 5, 4]
irb&gt; numbers.filter_map { |x| x**2 if x.odd? }
=&gt; [9, 49, 81, 25]

</code></pre>
<p>The original discussion had started
<a href="https://bugs.ruby-lang.org/issues/5663">8 years back</a>. Here is the latest
<a href="https://bugs.ruby-lang.org/issues/15323">thread</a> and
<a href="https://github.com/ruby/ruby/pull/2017/commits/38e04e15bf1d4e67c52630fa3fca1d4a056ea768">github commit</a>
for reference.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.7 deprecates conversion of keyword arguments]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-7-deprecates-conversion-of-keyword-arguments"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-deprecates-conversion-of-keyword-arguments.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-7-deprecates-conversion-of-keyword-arguments</id>
      <published>2020-04-14T00:00:00.000Z</published>
      <updated>2020-04-14T00:00:00.000Z</updated>
      <author>
        <name>Taha Husain</name>
        <uri>https://www.bigbinary.com/blog/authors/taha</uri>
      </author>
      <category term="Ruby 2.7"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-deprecates-conversion-of-keyword-arguments.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.7 deprecates conversion of keyword arguments and positional arguments]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-7-deprecates-conversion-of-keyword-arguments"><![CDATA[<p>A notable change has been announced for Ruby 3 for which deprecation warning has
been added in Ruby 2.7. Ruby 2.7 deprecated automatic conversion of keyword
arguments and positional arguments. This conversion will be completely removed
in Ruby 3.</p>
<p><a href="https://github.com/ruby/ruby/blob/4643bf5d55af6f79266dd67b69bb6eb4ff82029a/doc/NEWS-2.7.0#the-spec-of-keyword-arguments-is-changed-towards-30-">Ruby 2.7 NEWS</a>
has listed the spec of keyword arguments for Ruby 3.0. We will take the examples
mentioned there and for each scenario we will look into how we can fix them in
the existing codebase.</p>
<h4>Scenario 1</h4>
<p><em>When method definition accepts keyword arguments as the last argument.</em></p>
<pre><code class="language-ruby">def sum(a: 0, b: 0)
  a + b
end
</code></pre>
<p>Passing exact keyword arguments in a method call is acceptable, but in
applications we usually pass a hash to a method call.</p>
<pre><code class="language-ruby">sum(a: 2, b: 4) # OK

sum({ a: 2, b: 4 }) # Warned
</code></pre>
<p>In this case, we can add a double splat operator to the hash to avoid
deprecation warning.</p>
<pre><code class="language-ruby">sum(**{ a: 2, b: 4 }) # OK
</code></pre>
<h4>Scenario 2</h4>
<p><em>When method call passes keyword arguments but does not pass enough required
positional arguments.</em></p>
<p>If the number of positional arguments doesn't match with method definition, then
keyword arguments passed in method call will be considered as the last
positional argument to the method.</p>
<pre><code class="language-ruby">def sum(num, x: 0)
  num.values.sum + x
end
</code></pre>
<pre><code class="language-ruby">sum(a: 2, b: 4) # Warned

sum(a: 2, b: 4, x: 6) # Warned
</code></pre>
<p>To avoid deprecation warning and for code to be compatible with Ruby 3, we
should pass hash instead of keyword arguments in method call.</p>
<pre><code class="language-ruby">sum({ a: 2, b: 4 }) # OK

sum({ a: 2, b: 4}, x: 6) # OK
</code></pre>
<h4>Scenario 3</h4>
<p><em>When a method accepts a hash and keyword arguments but method call passes only
hash or keyword arguments.</em></p>
<p>If a method arguments are a mix of symbol keys and non-symbol keys, and the
method definition accepts either one of them then Ruby splits the keyword
arguments but also raises a warning.</p>
<pre><code class="language-ruby">def sum(num={}, x: 0)
  num.values.sum + x
end
</code></pre>
<pre><code class="language-ruby">sum(&quot;x&quot; =&gt; 2, x: 4) # Warned

sum(x: 2, &quot;x&quot; =&gt; 4) # Warned
</code></pre>
<p>To fix this warning, we should pass hash separately as defined in the method
definition.</p>
<pre><code class="language-ruby">sum({ &quot;x&quot; =&gt; 4 }, x: 2) # OK
</code></pre>
<h4>Scenario 4</h4>
<p><em>When an empty hash with double splat operator is passed to a method that
doesn't accept keyword arguments.</em></p>
<p>Passing keyword arguments using double splat operator to a method that doesn't
accept keyword argument will send empty hash similar to earlier version of Ruby
but will raise a warning.</p>
<pre><code class="language-ruby">def sum(num)
  num.values.sum
end
</code></pre>
<pre><code class="language-ruby">numbers = {}
sum(**numbers) # Warned
</code></pre>
<p>To avoid this warning, we should change method call to pass hash instead of
using double splat operator.</p>
<pre><code class="language-ruby">numbers = {}
sum(numbers) # OK
</code></pre>
<hr>
<h3>Added support for non-symbol keys</h3>
<p>In Ruby 2.6.0, support for non-symbol keys in method call was removed. It is
added back in Ruby 2.7. When method accepts arbitrary keyword arguments using
double splat operator then non-symbol keys can also be passed.</p>
<pre><code class="language-ruby">def sum(**num)
  num.values.sum
end
</code></pre>
<h5>ruby 2.6.5</h5>
<pre><code class="language-ruby">sum(&quot;x&quot; =&gt; 4, &quot;y&quot; =&gt; 3)
=&gt; ArgumentError (wrong number of arguments (given 1, expected 0))

sum(x: 4, y: 3)
=&gt; 7
</code></pre>
<h5>ruby 2.7.0</h5>
<pre><code class="language-ruby">sum(&quot;x&quot; =&gt; 4, &quot;y&quot; =&gt; 3)
=&gt; 7

sum(x: 4, y: 3)
=&gt; 7
</code></pre>
<hr>
<h3>Added support for <code>**nil</code></h3>
<p>Ruby 2.7 added support for <code>**nil</code> to explicitly mention if a method doesn't
accept any keyword arguments in method call.</p>
<pre><code class="language-ruby">def sum(a, b, **nil)
  a + b
end

sum(2, 3, x: 4)
=&gt; ArgumentError (no keywords accepted)
</code></pre>
<hr>
<p>To suppress above deprecation warnings we can use
<a href="https://github.com/ruby/ruby/blob/4643bf5d55af6f79266dd67b69bb6eb4ff82029a/doc/NEWS-2.7.0#warning-option-"><code>-W:no-deprecated option</code></a>.</p>
<p>In conclusion, Ruby 2.7 has worked big steps towards changing specification of
keyword arguments which will be completely changed in Ruby 3.</p>
<p>For more information on discussion, code changes and official documentation,
please head to <a href="https://bugs.ruby-lang.org/issues/14183">Feature #14183</a>
discussion, <a href="https://github.com/ruby/ruby/pull/2395">pull request</a> and
<a href="https://github.com/ruby/ruby/blob/4643bf5d55af6f79266dd67b69bb6eb4ff82029a/doc/NEWS-2.7.0#the-spec-of-keyword-arguments-is-changed-towards-30-">NEWS release</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.7 adds Enumerator::Lazy#eager]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-7-adds-enumerator-lazy-eager"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-enumerator-lazy-eager.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-7-adds-enumerator-lazy-eager</id>
      <published>2020-03-18T00:00:00.000Z</published>
      <updated>2020-03-18T00:00:00.000Z</updated>
      <author>
        <name>Ashik Salman</name>
        <uri>https://www.bigbinary.com/blog/authors/ashiksp</uri>
      </author>
      <category term="Ruby 2.7"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-enumerator-lazy-eager.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.0 introduced Enumerator::Lazy, a special type of enumerator which helps us in processing chains of operations on a collection without actually executing it instantly. By applying...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-7-adds-enumerator-lazy-eager"><![CDATA[<p>Ruby 2.0 introduced
<a href="https://ruby-doc.org/core-2.7.0/Enumerator/Lazy.html"><code>Enumerator::Lazy</code></a>, a
special type of enumerator which helps us in processing chains of operations on
a collection without actually executing it instantly.</p>
<p>By applying
<a href="https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-lazy"><code>Enumerable#lazy</code></a>
method on any enumerable object, we can convert that object into
<code>Enumerator::Lazy</code> object. The chains of actions on this lazy enumerator will be
evaluated only when it is needed. It helps us in processing operations on large
collections, files and infinite sequences seamlessly.</p>
<pre><code class="language-ruby"># This line of code will hang and you will have to quit the console by Ctrl+C.
irb&gt; list = (1..Float::INFINITY).select { |i| i%3 == 0 }.reject(&amp;:even?)

# Just adding `lazy`, the above line of code now executes properly
# and returns result without going to infinite loop. Here the chains of
# operations are performed as and when it is needed.
irb&gt; lazy_list = (1..Float::INFINITY).lazy.select { |i| i%3 == 0 }.reject(&amp;:even?)
=&gt; #&lt;Enumerator::Lazy: ...&gt;

irb&gt; lazy_list.first(5)
=&gt; [3, 9, 15, 21, 27]

</code></pre>
<p>When we chain more operations on <code>Enumerable#lazy</code> object, it again returns lazy
object without executing it. So, when we pass lazy objects to any method which
expects a normal enumerable object as an argument, we have to force evaluation
on lazy object by calling
<a href="https://ruby-doc.org/core-2.7.0/Enumerator/Lazy.html#method-i-to_a"><code>to_a</code></a>
method or it's alias
<a href="https://ruby-doc.org/core-2.7.0/Enumerator/Lazy.html#method-i-force"><code>force</code></a>.</p>
<pre><code class="language-ruby">
# Define a lazy enumerator object.
irb&gt; list = (1..30).lazy.select { |i| i%3 == 0 }.reject(&amp;:even?)
=&gt; #&lt;Enumerator::Lazy: #&lt;Enumerator::Lazy: ... 1..30&gt;:select&gt;:reject&gt;

# The chains of operations will return again a lazy enumerator.
irb&gt; result = list.select { |x| x if x &lt;= 15 }
=&gt; #&lt;Enumerator::Lazy: #&lt;Enumerator::Lazy: ... 1..30&gt;:select&gt;:reject&gt;:map&gt;

# It returns error when we call usual array methods on result.
irb&gt; result.sample
irb&gt; NoMethodError (undefined method `sample'
irb&gt; for #&lt;Enumerator::Lazy:0x00007faab182a5d8&gt;)

irb&gt; result.length
irb&gt; NoMethodError (undefined method `length'
irb&gt; for #&lt;Enumerator::Lazy:0x00007faab182a5d8&gt;)

# We can call the normal array methods on lazy object after forcing
# its actual execution with methods as mentioned above.
irb&gt; result.force.sample
=&gt; 9

irb&gt; result.to_a.length
=&gt; 3

</code></pre>
<p>The
<a href="https://ruby-doc.org/core-2.7.0/Enumerator/Lazy.html#method-i-eager"><code>Enumerable#eager</code></a>
method returns a normal enumerator from a lazy enumerator, so that lazy
enumerator object can be passed to any methods which expects a normal enumerable
object as an argument. Also, we can call other usual array methods on the
collection to get desired results.</p>
<pre><code class="language-ruby">
# By adding eager on lazy object, the chains of operations would return
# actual result here. If lazy object is passed to any method, the
# processed result will be received as an argument.
irb&gt; eager_list = (1..30).lazy.select { |i| i%3 == 0 }.reject(&amp;:even?).eager
=&gt; #&lt;Enumerator: #&lt;Enumerator::Lazy: ... 1..30&gt;:select&gt;:reject&gt;:each&gt;

irb&gt; result = eager_list.select { |x| x if x &lt;= 15 }
irb&gt; result.sample
=&gt; 9

irb&gt; result.length
=&gt; 3

</code></pre>
<p>The same way, we can use <code>eager</code> method when we pass lazy enumerator as an
argument to any method which expects a normal enumerator.</p>
<pre><code class="language-ruby">irb&gt; list = (1..10).lazy.select { |i| i%3 == 0 }.reject(&amp;:even?)
irb&gt; def display(enum)
irb&gt;   enum.map { |x| p x }
irb&gt; end

irb&gt;  display(list)
=&gt; #&lt;Enumerator::Lazy: #&lt;Enumerator::Lazy: ... 1..30&gt;:select&gt;:reject&gt;:map&gt;

irb&gt; eager_list = (1..10).lazy.select { |i| i%3 == 0 }.reject(&amp;:even?).eager
irb&gt; display(eager_list)
=&gt; 3
=&gt; 9

</code></pre>
<p>Here's the relevant
<a href="https://github.com/ruby/ruby/commit/1d4bd229b898671328c2a942b04f08065c640c28">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/15901">feature discussion</a> for this
change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.7 adds numbered parameters for blocks]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-7-introduces-numbered-parameters-as-default-block-parameters"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-introduces-numbered-parameters-as-default-block-parameters.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-7-introduces-numbered-parameters-as-default-block-parameters</id>
      <published>2020-03-03T00:00:00.000Z</published>
      <updated>2020-03-03T00:00:00.000Z</updated>
      <author>
        <name>Taha Husain</name>
        <uri>https://www.bigbinary.com/blog/authors/taha</uri>
      </author>
      <category term="Ruby 2.7"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-introduces-numbered-parameters-as-default-block-parameters.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.7 introduces numbered parameters as default block parameters]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-7-introduces-numbered-parameters-as-default-block-parameters"><![CDATA[<p>At some point, all of us have used names like <code>a</code>, <code>n</code>, <code>i</code> etc for block
parameters. Below are few examples where numbered parameters can come in handy.</p>
<pre><code class="language-ruby">
&gt; (1..10).each { |n| p n * 3 }

&gt; { a: [1, 2, 3], b: [2, 4, 6], c: [3, 6, 9] }.each { |_k, v| p v }

&gt; [10, 100, 1000].each_with_index { |n, i| p n, i }

</code></pre>
<p>Ruby 2.7 introduces a new way to access block parameters. Ruby 2.7 onwards, if
block parameters are obvious and we wish to not use absurd names like <code>n</code> or <code>i</code>
etc, we can use numbered parameters which are available inside a block by
default.</p>
<p>We can use **1_ for first parameter, **2_ for second parameter and so on.</p>
<p>Here's how Ruby 2.7 provides numbered parameters inside a block. Below shown are
the examples from above, only this time using numbered parameters.</p>
<pre><code class="language-ruby">
&gt; (1..10).each { p _1 * 3 }

&gt; { a: [1, 2, 3], b: [2, 4, 6], c: [3, 6, 9] }.each { p _2 }

&gt; [10, 100, 1000].each_with_index { p _1, _2 }

</code></pre>
<p>Like mentioned in
<a href="https://github.com/ruby/ruby/blob/7f6bd6bb1c2220d2d7c17b77abf52fb4af548001/doc/NEWS-2.7.0#numbered-parameters">News-2.7.0 docs</a>,
Ruby now raises a warning if we try to define local variable in the format <code>_1</code>.
Local variable will have precedence over numbered parameter inside the block.</p>
<pre><code class="language-ruby">
&gt; _1 = 0
&gt; =&gt; warning: `_1' is reserved for numbered parameter; consider another name

&gt; [10].each { p _1 }
&gt; =&gt; 0

</code></pre>
<p>Numbered parameters are not accessible inside the block if we define ordinary
parameters. If we try to access <code>_1</code> when ordinary parameters are defined, then
ruby raises <code>SyntaxError</code> like shown below.</p>
<pre><code class="language-ruby">
&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;].each_with_index { |alphabet, index| p _1, _2}

=&gt; SyntaxError ((irb):1: ordinary parameter is defined)

</code></pre>
<p>This feature was suggested 9 years back and came back in discussion last year.
After many suggestions community agreed to use <code>_1</code> syntax.</p>
<p>Head to following links to read the discussion behind numbered parameters,
<a href="https://bugs.ruby-lang.org/issues/4475">Feature #4475</a> and
<a href="https://bugs.ruby-lang.org/issues/15723">Discussion #15723</a>.</p>
<p>Here's relevant
<a href="https://github.com/ruby/ruby/commit/12acc751e3e7fd6f8aec33abf661724ad76c862a">commit</a>
for this feature.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.7 adds Enumerable#tally]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-7-adds-enumerable-tally"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-enumerable-tally.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-7-adds-enumerable-tally</id>
      <published>2020-02-18T00:00:00.000Z</published>
      <updated>2020-02-18T00:00:00.000Z</updated>
      <author>
        <name>Akhil Gautam</name>
        <uri>https://www.bigbinary.com/blog/authors/akhilgautam</uri>
      </author>
      <category term="Ruby 2.7"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-7-adds-enumerable-tally.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Let's say that we have to find the frequency of each element of an array. Before Ruby 2.7, we could have achieved it using groupby or inject. Ruby 2.7 Ruby 2.7 adds Enumerable#tally which can be used...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-7-adds-enumerable-tally"><![CDATA[<p>Let's say that we have to find the frequency of each element of an array.</p>
<p>Before Ruby 2.7, we could have achieved it using <code>group_by</code> or <code>inject</code>.</p>
<pre><code class="language-ruby">irb&gt; scores = [100, 35, 70, 100, 70, 30, 35, 100, 45, 30]

# we can use group_by to group the scores

irb&gt; scores.group_by { |v| v }.map { |k, v| [k, v.size] }.to_h
=&gt; {100=&gt;3, 35=&gt;2, 70=&gt;2, 30=&gt;2, 45=&gt;1}

# or we can use inject to group the scores

irb&gt; scores.inject(Hash.new(0)) {|hash, score| hash[score] += 1; hash }
=&gt; {100=&gt;3, 35=&gt;2, 70=&gt;2, 30=&gt;2, 45=&gt;1}

</code></pre>
<h4>Ruby 2.7</h4>
<p>Ruby 2.7 adds <code>Enumerable#tally</code> which can be used to find the frequency.
<code>Tally</code> makes the code more readable and intuitive. It returns a hash where keys
are the unique elements and values are its corresponding frequency.</p>
<pre><code class="language-ruby">
irb&gt; scores = [100, 35, 70, 100, 70, 30, 35, 100, 45, 30]
irb&gt; scores.tally
=&gt; {100=&gt;3, 35=&gt;2, 70=&gt;2, 30=&gt;2, 45=&gt;1}

</code></pre>
<p>Check out the
<a href="https://github.com/ruby/ruby/commit/673dc51c251588be3c9f4b5b5486cd80d46dfeee">github commit</a>
for more details on this.</p>
]]></content>
    </entry>
</feed>