<?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.4</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-4/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/categories/ruby-2-4"/>
  <id>https://www.bigbinary.com/blog/categories/ruby-2-4</id>
  <updated>2017-09-28T00: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 2017 Big Binary LLC</rights>
  <generator uri="https://nextjs.org">Next.js</generator>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 has optimized enumerable min max methods]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-0-has-optimized-enumerable-min-max-methods"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-0-has-optimized-enumerable-min-max-methods.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-0-has-optimized-enumerable-min-max-methods</id>
      <published>2017-09-28T00:00:00.000Z</published>
      <updated>2017-09-28T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-0-has-optimized-enumerable-min-max-methods.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[min, max and minmax methods for enumerable class have been optimized in ruby 2.4]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-0-has-optimized-enumerable-min-max-methods"><![CDATA[<p>Enumerables in Ruby have <code>min</code>, <code>max</code> and <code>minmax</code> comparison methods which are
quite convenient to use.</p>
<pre><code class="language-ruby">
(1..99).min #=&gt; 1
(1..99).max #=&gt; 99
(1..99).minmax #=&gt; [1, 99]

</code></pre>
<p>In Ruby 2.4, <code>Enumurable#min</code>, <code>Enumurable#max</code>
<a href="https://github.com/ruby/ruby/commit/3dcd4b2a98e">methods</a> and
<code>Enumurable#minmax</code> <a href="https://github.com/ruby/ruby/commit/9f44b77a18d">method</a>
are now more optimized.</p>
<p>We would run the following benchmark snippet for both Ruby 2.3 and Ruby 2.4 and
observe the results</p>
<pre><code class="language-ruby">
require 'benchmark/ips'

Benchmark.ips do |bench|
NUM1 = 1_000_000.times.map { rand }

ENUM_MIN = Enumerable.instance_method(:min).bind(NUM1)
ENUM_MAX = Enumerable.instance_method(:max).bind(NUM1)
ENUM_MINMAX = Enumerable.instance_method(:minmax).bind(NUM1)

bench.report('Enumerable#min') do
ENUM_MIN.call
end

bench.report('Enumerable#max') do
ENUM_MAX.call
end

bench.report('Enumerable#minmax') do
ENUM_MINMAX.call
end
end

</code></pre>
<h4>Results for Ruby 2.3</h4>
<pre><code class="language-ruby">
Warming up --------------------------------------
Enumerable#min 1.000 i/100ms
Enumerable#max 1.000 i/100ms
Enumerable#minmax 1.000 i/100ms
Calculating -------------------------------------
Enumerable#min 14.810 (±13.5%) i/s - 73.000 in 5.072666s
Enumerable#max 16.131 (± 6.2%) i/s - 81.000 in 5.052324s
Enumerable#minmax 11.758 (± 0.0%) i/s - 59.000 in 5.026007s

</code></pre>
<h4>Ruby 2.4</h4>
<pre><code class="language-ruby">
Warming up --------------------------------------
Enumerable#min 1.000 i/100ms
Enumerable#max 1.000 i/100ms
Enumerable#minmax 1.000 i/100ms
Calculating -------------------------------------
Enumerable#min 18.091 (± 5.5%) i/s - 91.000 in 5.042064s
Enumerable#max 17.539 (± 5.7%) i/s - 88.000 in 5.030514s
Enumerable#minmax 13.086 (± 7.6%) i/s - 66.000 in 5.052537s

</code></pre>
<p>From the above benchmark results, it can be seen that there has been an
improvement in the run times for the methods.</p>
<p>Internally Ruby has changed the logic by which objects are compared, which
results in these methods being optimized. You can have a look at the commits
<a href="https://github.com/ruby/ruby/commit/9f44b77a18d">here</a> and
<a href="https://github.com/ruby/ruby/commit/3dcd4b2a98e">here</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[CSV::Row#each etc. return enumerator when no block given]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/csv-row-each-and-delete-if-return-enumerator-when-no-block-given"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/csv-row-each-and-delete-if-return-enumerator-when-no-block-given.png"/>
      <id>https://www.bigbinary.com/blog/csv-row-each-and-delete-if-return-enumerator-when-no-block-given</id>
      <published>2017-09-25T00:00:00.000Z</published>
      <updated>2017-09-25T00:00:00.000Z</updated>
      <author>
        <name>Sushant Mittal</name>
        <uri>https://www.bigbinary.com/blog/authors/sushantmittal</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/csv-row-each-and-delete-if-return-enumerator-when-no-block-given.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[CSV::Row#each, CSV::Row#delete_if, CSV::Table#each and CSV::Table#delete_if return enumerator when no block given]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/csv-row-each-and-delete-if-return-enumerator-when-no-block-given"><![CDATA[<p>In Ruby 2.3, These methods do not return enumerator when no block is given.</p>
<h3>Ruby 2.3</h3>
<pre><code class="language-ruby">
CSV::Row.new(%w(banana mango), [1,2]).each #=&gt; #&lt;CSV::Row &quot;banana&quot;:1 &quot;mango&quot;:2&gt;

CSV::Row.new(%w(banana mango), [1,2]).delete_if #=&gt; #&lt;CSV::Row &quot;banana&quot;:1 &quot;mango&quot;:2&gt;

</code></pre>
<p>Some methods raise exception because of this behavior.</p>
<pre><code class="language-ruby">
&gt; ruby -rcsv -e 'CSV::Table.new([CSV::Row.new(%w{banana mango}, [1, 2])]).by_col.each'
 #=&gt; /Users/sushant/.rbenv/versions/2.3.0/lib/ruby/2.3.0/csv.rb:850:in `block in each': undefined method `[]' for nil:NilClass (NoMethodError)
  from /Users/sushant/.rbenv/versions/2.3.0/lib/ruby/2.3.0/csv.rb:850:in `each'
  from /Users/sushant/.rbenv/versions/2.3.0/lib/ruby/2.3.0/csv.rb:850:in `each'
  from -e:1:in `&lt;main&gt;'

</code></pre>
<p>Ruby 2.4
<a href="https://github.com/ruby/ruby/commit/b425d4f19ad9efaefcb1a767a6ea26e6d40e3985">fixed this issue</a>.</p>
<h3>Ruby 2.4</h3>
<pre><code class="language-ruby">
CSV::Row.new(%w(banana mango), [1,2]).each #=&gt; #&lt;Enumerator: #&lt;CSV::Row &quot;banana&quot;:1 &quot;mango&quot;:2&gt;:each&gt;

CSV::Row.new(%w(banana mango), [1,2]).delete_if #=&gt; #&lt;Enumerator: #&lt;CSV::Row &quot;banana&quot;:1 &quot;mango&quot;:2&gt;:delete_if&gt;

</code></pre>
<p>As we can see, these methods now return an enumerator when no block is given.</p>
<p>In Ruby 2.4 following code will not raise any exception.</p>
<pre><code class="language-ruby">
&gt; ruby -rcsv -e 'CSV::Table.new([CSV::Row.new(%w{banana mango}, [1, 2])]).by_col.each'

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 DateTime#to_time & Time#to_time keeps info]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/to-time-preserves-time-zone-info-in-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/to-time-preserves-time-zone-info-in-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/to-time-preserves-time-zone-info-in-ruby-2-4</id>
      <published>2017-09-19T00:00:00.000Z</published>
      <updated>2017-09-19T00:00:00.000Z</updated>
      <author>
        <name>Sushant Mittal</name>
        <uri>https://www.bigbinary.com/blog/authors/sushantmittal</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/to-time-preserves-time-zone-info-in-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[DateTime#to_time and Time#to_time preserves receiver's timezone offset info in Ruby 2.4]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/to-time-preserves-time-zone-info-in-ruby-2-4"><![CDATA[<p>In Ruby, <code>DateTime#to_time</code> and <code>Time#to_time</code> methods can be used to return a
Time object.</p>
<p>In Ruby 2.3, these methods convert time into system timezone offset instead of
preserving timezone offset of the receiver.</p>
<h3>Ruby 2.3</h3>
<pre><code class="language-ruby">
&gt; datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
 #=&gt; #&lt;DateTime: 2017-05-16T10:15:30+09:00 ((2457890j,4530s,0n),+32400s,2299161j)&gt;
&gt; datetime.to_time
 #=&gt; 2017-05-16 06:45:30 +0530

&gt; time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
 #=&gt; 2017-05-16 10:15:30 +0900
&gt; time.to_time
 #=&gt; 2017-05-16 06:45:30 +0530

</code></pre>
<p>As you can see, <code>DateTime#to_time</code> and <code>Time#to_time</code> methods return time in
system timezone offset <code>+0530</code>.</p>
<p>Ruby 2.4 fixed
<a href="https://github.com/ruby/ruby/commit/5f11a6eb6cca740b08384d1e4a68df643d98398c">DateTime#to_time</a>
and
<a href="https://github.com/ruby/ruby/commit/456523e2ede3073767fd8cb73cc4b159c3608890">Time#to_time</a>.</p>
<p>Now, <code>DateTime#to_time</code> and <code>Time#to_time</code> preserve receiver's timezone offset
info.</p>
<h3>Ruby 2.4</h3>
<pre><code class="language-ruby">
&gt; datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
 #=&gt; #&lt;DateTime: 2017-05-16T10:15:30+09:00 ((2457890j,4530s,0n),+32400s,2299161j)&gt;
&gt; datetime.to_time
 #=&gt; 2017-05-16 10:15:30 +0900

&gt; time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
 #=&gt; 2017-05-16 10:15:30 +0900
&gt; time.to_time
 #=&gt; 2017-05-16 10:15:30 +0900

</code></pre>
<p>Since this is a breaking change for Rails application upgrading to ruby 2.4,
Rails 4.2.8 built a compatibility layer by adding a
<a href="https://github.com/rails/rails/commit/c9c5788a527b70d7f983e2b4b47e3afd863d9f48">config option</a>.
<code>ActiveSupport.to_time_preserves_timezone</code> was added to control how <code>to_time</code>
handles timezone offsets.</p>
<p>Here is an example of how application behaves when <code>to_time_preserves_timezone</code>
is set to <code>false</code>.</p>
<pre><code class="language-ruby">&gt; ActiveSupport.to_time_preserves_timezone = false

&gt; datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
 #=&gt; Tue, 16 May 2017 10:15:30 +0900
&gt; datetime.to_time
 #=&gt; 2017-05-16 06:45:30 +0530

&gt; time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
 #=&gt; 2017-05-16 10:15:30 +0900
&gt; time.to_time
 #=&gt; 2017-05-16 06:45:30 +0530
</code></pre>
<p>Here is an example of how application behaves when <code>to_time_preserves_timezone</code>
is set to <code>true</code>.</p>
<pre><code class="language-ruby">&gt; ActiveSupport.to_time_preserves_timezone = true

&gt; datetime = DateTime.strptime('2017-05-16 10:15:30 +09:00', '%Y-%m-%d %H:%M:%S %Z')
 #=&gt; Tue, 16 May 2017 10:15:30 +0900
&gt; datetime.to_time
 #=&gt; 2017-05-16 10:15:30 +0900

&gt; time = Time.new(2017, 5, 16, 10, 15, 30, '+09:00')
 #=&gt; 2017-05-16 10:15:30 +0900
&gt; time.to_time
 #=&gt; 2017-05-16 10:15:30 +0900
</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Avoid exception for dup on Integer]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/avoid-exceptions-for-dup-on-interger-and-similar-cases"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/avoid-exceptions-for-dup-on-interger-and-similar-cases.png"/>
      <id>https://www.bigbinary.com/blog/avoid-exceptions-for-dup-on-interger-and-similar-cases</id>
      <published>2017-08-01T00:00:00.000Z</published>
      <updated>2017-08-01T00:00:00.000Z</updated>
      <author>
        <name>Rohit Arolkar</name>
        <uri>https://www.bigbinary.com/blog/authors/rohitakshar</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/avoid-exceptions-for-dup-on-interger-and-similar-cases.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[dup now silently fails for Integer]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/avoid-exceptions-for-dup-on-interger-and-similar-cases"><![CDATA[<p>Prior to Ruby 2.4, if we were to <code>dup</code> an <code>Integer</code>, it would fail with a
<code>TypeError</code>.</p>
<pre><code class="language-ruby">
&gt; 1.dup
TypeError: can't dup Fixnum
	from (irb):1:in `dup'
	from (irb):1

</code></pre>
<p>This was confusing because <code>Integer#dup</code> is actually implemented.</p>
<pre><code class="language-ruby">
&gt; Integer.respond_to? :dup
=&gt; true

</code></pre>
<p>However, if we were to freeze an <code>Integer</code> it would fail silently.</p>
<pre><code class="language-ruby">
&gt; 1.freeze
=&gt; 1

</code></pre>
<p>Ruby 2.4 has now included dup-ability for <code>Integer</code> as well.</p>
<pre><code class="language-ruby">
&gt; 1.dup
=&gt; 1

</code></pre>
<p>In Ruby, some object types are immediate variables and therefore cannot be
duped/cloned. Yet, there was no graceful way of averting the error thrown by the
sanity check when we attempt to dup/clone them.</p>
<p>So now <code>Integer#dup</code> functions exactly the way <code>freeze</code> does -- fail silently
and return the object itself. It makes sense because nothing about these objects
can be changed in the first place.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 no exception for objects converted to IPAddr]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-ip-addr-methods-do-not-throw-exception-for-objects-that-cant-be-converted-to-ipaddr"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-ip-addr-methods-do-not-throw-exception-for-objects-that-cant-be-converted-to-ipaddr.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-ip-addr-methods-do-not-throw-exception-for-objects-that-cant-be-converted-to-ipaddr</id>
      <published>2017-06-21T00:00:00.000Z</published>
      <updated>2017-06-21T00:00:00.000Z</updated>
      <author>
        <name>Sushant Mittal</name>
        <uri>https://www.bigbinary.com/blog/authors/sushantmittal</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-ip-addr-methods-do-not-throw-exception-for-objects-that-cant-be-converted-to-ipaddr.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[IPAddr#== and IPAddr#<=> do not throw exception for objects that can't be converted to IPAddr anymore in Ruby 2.4]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-ip-addr-methods-do-not-throw-exception-for-objects-that-cant-be-converted-to-ipaddr"><![CDATA[<p>In Ruby,
<a href="https://docs.ruby-lang.org/en/2.4.0/IPAddr.html#method-i-3D-3D"><code>IPAddr#==</code></a>
method is used to check whether two IP addresses are equal or not. Ruby also has
<a href="https://docs.ruby-lang.org/en/2.4.0/IPAddr.html#method-i-3C-3D-3E"><code>IPAddr#&lt;=&gt;</code></a>
method which is used to compare two IP addresses.</p>
<p>In Ruby 2.3, behavior of these methods was inconsistent. Let's see an example.</p>
<pre><code class="language-ruby">
# Ruby 2.3

&gt;&gt; IPAddr.new(&quot;1.2.1.3&quot;) == &quot;Some ip address&quot;
=&gt; IPAddr::InvalidAddressError: invalid address
</code></pre>
<p>But if the first argument is invalid IP address and second is valid IP address,
then it would return <code>false</code>.</p>
<pre><code class="language-ruby">
# Ruby 2.3

&gt;&gt; &quot;Some ip address&quot; == IPAddr.new(&quot;1.2.1.3&quot;)
=&gt; false

</code></pre>
<p>The <code>&lt;=&gt;</code> method would raise exception in both the cases.</p>
<pre><code class="language-ruby">
# Ruby 2.3

&gt;&gt; &quot;Some ip address&quot; &lt;=&gt; IPAddr.new(&quot;1.2.1.3&quot;)
=&gt; IPAddr::InvalidAddressError: invalid address

&gt;&gt; IPAddr.new(&quot;1.2.1.3&quot;) &lt;=&gt; &quot;Some ip address&quot;
=&gt; IPAddr::InvalidAddressError: invalid address

</code></pre>
<p>In Ruby 2.4, <a href="https://bugs.ruby-lang.org/issues/12799">this issue</a> is
<a href="https://github.com/ruby/ruby/pull/1435/files#diff-3504e08cf251c76a597c727011315dd1">fixed</a>
for both the methods to return the result without raising exception, if the
objects being compared can't be converted to an IPAddr object.</p>
<pre><code class="language-ruby">
# Ruby 2.4

&gt;&gt; IPAddr.new(&quot;1.2.1.3&quot;) == &quot;Some ip address&quot;
=&gt; false

&gt;&gt; &quot;Some ip address&quot; == IPAddr.new(&quot;1.2.1.3&quot;)
=&gt; false

&gt;&gt; IPAddr.new(&quot;1.2.1.3&quot;) &lt;=&gt; &quot;Some ip address&quot;
=&gt; nil

&gt;&gt; &quot;Some ip address&quot; &lt;=&gt; IPAddr.new(&quot;1.2.1.3&quot;)
=&gt; nil
</code></pre>
<p>This might cause some backward compatibility if our code is expecting the
exception which is no longer raised in Ruby 2.4.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 deprecated constants TRUE, FALSE & NIL]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-has-depecated-constants-true-false-and-nil"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-depecated-constants-true-false-and-nil.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-has-depecated-constants-true-false-and-nil</id>
      <published>2017-06-19T00:00:00.000Z</published>
      <updated>2017-06-19T00:00:00.000Z</updated>
      <author>
        <name>Akshay Vishnoi</name>
        <uri>https://www.bigbinary.com/blog/authors/akshayvishnoi</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-depecated-constants-true-false-and-nil.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 has deprecated toplevel constants TRUE, FALSE and NIL]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-has-depecated-constants-true-false-and-nil"><![CDATA[<p>Ruby has top level constants like <code>TRUE</code>, <code>FALSE</code> and <code>NIL</code>. These constants are
just synonyms for <code>true</code>, <code>false</code> and <code>nil</code> respectively.</p>
<p>In Ruby 2.4, these constants are
<a href="https://bugs.ruby-lang.org/issues/12574">deprecated</a> and will be removed in
future version.</p>
<pre><code class="language-ruby"># Ruby 2.3

2.3.1 :001 &gt; TRUE
 =&gt; true
2.3.1 :002 &gt; FALSE
 =&gt; false
2.3.1 :003 &gt; NIL
 =&gt; nil
</code></pre>
<pre><code class="language-ruby"># Ruby 2.4

2.4.0 :001 &gt; TRUE
(irb):1: warning: constant ::TRUE is deprecated
 =&gt; true
2.4.0 :002 &gt; FALSE
(irb):2: warning: constant ::FALSE is deprecated
 =&gt; false
2.4.0 :003 &gt; NIL
(irb):3: warning: constant ::NIL is deprecated
 =&gt; nil
</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 allows custom suffix of rotated log files]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-allows-to-customize-suffix-of-the-rotated-log-files"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-allows-to-customize-suffix-of-the-rotated-log-files.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-allows-to-customize-suffix-of-the-rotated-log-files</id>
      <published>2017-06-15T00:00:00.000Z</published>
      <updated>2017-06-15T00:00:00.000Z</updated>
      <author>
        <name>Sushant Mittal</name>
        <uri>https://www.bigbinary.com/blog/authors/sushantmittal</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-allows-to-customize-suffix-of-the-rotated-log-files.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 has added ability to pass custom date format for the suffix of log files rotated daily, weekly or monthly]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-allows-to-customize-suffix-of-the-rotated-log-files"><![CDATA[<p>In Ruby, The
<a href="http://ruby-doc.org/stdlib-2.4.0/libdoc/logger/rdoc/Logger.html#method-c-new">Logger</a>
class can be used for rotating log files daily, weekly or monthly.</p>
<pre><code class="language-ruby">
daily_logger = Logger.new('foo.log', 'daily')

weekly_logger = Logger.new('foo.log', 'weekly')

monthly_logger = Logger.new('foo.log', 'monthly')

</code></pre>
<p>At the end of the specified period, Ruby will change the file extension of the
log file as follows:</p>
<pre><code class="language-ruby">
foo.log.20170615

</code></pre>
<p>The format of the suffix for the rotated log file is <code>%Y%m%d</code>. In Ruby 2.3,
there was no way to customize this suffix format.</p>
<p>Ruby 2.4
<a href="https://github.com/ruby/ruby/commit/2c6f15b1ad90af37d7e0eefff7b3f5262e0a4c0b">added the ability</a>
to customize the suffix format by passing an extra argument
<code>shift_period_suffix</code>.</p>
<pre><code class="language-ruby">
# Ruby 2.4

logger = Logger.new('foo.log', 'weekly', shift_period_suffix: '%d-%m-%Y')

</code></pre>
<p>Now, suffix of the rotated log file will use the custom date format which we
passed.</p>
<pre><code class="language-ruby">
foo.log.15-06-2017

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 Hash#transform_values & destructive version]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-added-hash-transform-values-and-its-destructive-version-from-active-support"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-added-hash-transform-values-and-its-destructive-version-from-active-support.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-added-hash-transform-values-and-its-destructive-version-from-active-support</id>
      <published>2017-06-14T00:00:00.000Z</published>
      <updated>2017-06-14T00:00:00.000Z</updated>
      <author>
        <name>Sushant Mittal</name>
        <uri>https://www.bigbinary.com/blog/authors/sushantmittal</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-added-hash-transform-values-and-its-destructive-version-from-active-support.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[In Ruby 2.4, Hash#transform_values and Hash#transform_values! can be used to transform the values after executing passed block for each value]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-added-hash-transform-values-and-its-destructive-version-from-active-support"><![CDATA[<p>It is a common use case to transform the values of a hash.</p>
<pre><code class="language-ruby">
{ a: 1, b: 2, c: 3 } =&gt; { a: 2, b: 4, c: 6 }

{ a: &quot;B&quot;, c: &quot;D&quot;, e: &quot;F&quot; } =&gt; { a: &quot;b&quot;, c: &quot;d&quot;, e: &quot;f&quot; }

</code></pre>
<p>We can transform the values of a hash destructively (i.e. modify the original
hash with new values) or non-destructively (i.e. return a new hash instead of
modifying the original hash).</p>
<p>Prior to Ruby 2.4, we need to use following code to transform the values of a
hash.</p>
<pre><code class="language-ruby">
# Ruby 2.3 Non-destructive version

&gt; hash = { a: 1, b: 2, c: 3 }
 #=&gt; {:a=&gt;1, :b=&gt;2, :c=&gt;3}

&gt; hash.inject({}) { |h, (k, v)| h[k] = v * 2; h }
 #=&gt; {:a=&gt;2, :b=&gt;4, :c=&gt;6}

&gt; hash
 #=&gt; {:a=&gt;1, :b=&gt;2, :c=&gt;3}

&gt; hash = { a: &quot;B&quot;, c: &quot;D&quot;, e: &quot;F&quot; }
 #=&gt; {:a=&gt;&quot;B&quot;, :c=&gt;&quot;D&quot;, :e=&gt;&quot;F&quot;}

&gt; hash.inject({}) { |h, (k, v)| h[k] = v.downcase; h }
 #=&gt; {:a=&gt;&quot;b&quot;, :c=&gt;&quot;d&quot;, :e=&gt;&quot;f&quot;}

&gt; hash
 #=&gt; {:a=&gt;&quot;B&quot;, :c=&gt;&quot;D&quot;, :e=&gt;&quot;F&quot;}

</code></pre>
<pre><code class="language-ruby">
# Ruby 2.3 Destructive version

&gt; hash = { a: 1, b: 2, c: 3 }
 #=&gt; {:a=&gt;1, :b=&gt;2, :c=&gt;3}

&gt; hash.each { |k, v| hash[k] = v * 2 }
 #=&gt; {:a=&gt;2, :b=&gt;4, :c=&gt;6}

&gt; hash
 #=&gt; {:a=&gt;2, :b=&gt;4, :c=&gt;6}

&gt; hash = { a: &quot;B&quot;, c: &quot;D&quot;, e: &quot;F&quot; }
 #=&gt; {:a=&gt;&quot;B&quot;, :c=&gt;&quot;D&quot;, :e=&gt;&quot;F&quot;}

&gt; hash.each { |k, v| hash[k] = v.downcase }
 #=&gt; {:a=&gt;&quot;b&quot;, :c=&gt;&quot;d&quot;, :e=&gt;&quot;f&quot;}

&gt; hash
 #=&gt; {:a=&gt;&quot;b&quot;, :c=&gt;&quot;d&quot;, :e=&gt;&quot;f&quot;}

</code></pre>
<h2>transform_values and transform_values! from Active Support</h2>
<p>Active Support has already implemented handy methods
<a href="https://github.com/rails/rails/commit/b2cf8b251aac39c1e3ce71bc1de34a2ce5ef52b1">Hash#transform_values and Hash#transform_values!</a>
to transform hash values.</p>
<p>Now, Ruby 2.4 has also implemented
<a href="https://github.com/ruby/ruby/commit/ea5184b939ec3dbdcbd7013da350b8dcb6ca6107">Hash#map_v and Hash#map_v!</a>
and then renamed to
<a href="https://github.com/ruby/ruby/commit/eaa0a27f6149a9afa2b29729307ff9cc7b0bc95f">Hash#transform_values and Hash#transform_values!</a>
for the same purpose.</p>
<pre><code class="language-ruby">
# Ruby 2.4 Non-destructive version

&gt; hash = { a: 1, b: 2, c: 3 }
 #=&gt; {:a=&gt;1, :b=&gt;2, :c=&gt;3}

&gt; hash.transform_values { |v| v * 2 }
 #=&gt; {:a=&gt;2, :b=&gt;4, :c=&gt;6}

&gt; hash
 #=&gt; {:a=&gt;1, :b=&gt;2, :c=&gt;3}

&gt; hash = { a: &quot;B&quot;, c: &quot;D&quot;, e: &quot;F&quot; }
 #=&gt; {:a=&gt;&quot;B&quot;, :c=&gt;&quot;D&quot;, :e=&gt;&quot;F&quot;}

&gt; hash.transform_values(&amp;:downcase)
 #=&gt; {:a=&gt;&quot;b&quot;, :c=&gt;&quot;d&quot;, :e=&gt;&quot;f&quot;}

&gt; hash
 #=&gt; {:a=&gt;&quot;B&quot;, :c=&gt;&quot;D&quot;, :e=&gt;&quot;F&quot;}

</code></pre>
<pre><code class="language-ruby">
# Ruby 2.4 Destructive version

&gt; hash = { a: 1, b: 2, c: 3 }
 #=&gt; {:a=&gt;1, :b=&gt;2, :c=&gt;3}

&gt; hash.transform_values! { |v| v * 2 }
 #=&gt; {:a=&gt;2, :b=&gt;4, :c=&gt;6}

&gt; hash
 #=&gt; {:a=&gt;2, :b=&gt;4, :c=&gt;6}

&gt; hash = { a: &quot;B&quot;, c: &quot;D&quot;, e: &quot;F&quot; }
 #=&gt; {:a=&gt;&quot;B&quot;, :c=&gt;&quot;D&quot;, :e=&gt;&quot;F&quot;}

&gt; hash.transform_values!(&amp;:downcase)
 #=&gt; {:a=&gt;&quot;b&quot;, :c=&gt;&quot;d&quot;, :e=&gt;&quot;f&quot;}

&gt; hash
 #=&gt; {:a=&gt;&quot;b&quot;, :c=&gt;&quot;d&quot;, :e=&gt;&quot;f&quot;}

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Binding irb - Runtime Invocation for IRB]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/binding-irb"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/binding-irb.png"/>
      <id>https://www.bigbinary.com/blog/binding-irb</id>
      <published>2017-04-18T00:00:00.000Z</published>
      <updated>2017-04-18T00:00:00.000Z</updated>
      <author>
        <name>Rohit Arolkar</name>
        <uri>https://www.bigbinary.com/blog/authors/rohitakshar</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/binding-irb.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby now has a core IRB library for better debugging]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/binding-irb"><![CDATA[<p>It's very common to see a ruby programmer write a few <code>puts</code> or <code>p</code> statements,
either for debugging or for knowing the value of variables.</p>
<p><a href="https://github.com/pry/pry">pry</a> did make our lives easier with the usage of
<code>binding.pry</code>. However, it was still a bit of an inconvenience to have it
installed at runtime, while working with the <code>irb</code>.</p>
<p>Ruby 2.4 has now introduced <code>binding.irb</code>. By simply adding <code>binding.irb</code> to our
code we can open an IRB session.</p>
<pre><code class="language-ruby">
class ConvolutedProcess
def do_something
@variable = 10

    binding.irb
    # opens a REPL here

end
end

irb(main):029:0\* ConvolutedProcess.new.do_something
irb(#&lt;ConvolutedProcess:0x007fc55c827f48&gt;):001:0&gt; @variable
=&gt; 10

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 has added additional parameters for Logger#new]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-has-added-additional-parameters-for-logger-new"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-added-additional-parameters-for-logger-new.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-has-added-additional-parameters-for-logger-new</id>
      <published>2017-04-10T00:00:00.000Z</published>
      <updated>2017-04-10T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-added-additional-parameters-for-logger-new.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 makes it possible to specify logger level, progname, formatter and datetime_format in logger constructor.]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-has-added-additional-parameters-for-logger-new"><![CDATA[<p>The
<a href="http://ruby-doc.org/stdlib-2.4.0/libdoc/logger/rdoc/Logger.html#method-c-new">Logger</a>
class in Ruby provides a simple but sophisticated logging utility.</p>
<p>After creating the logger object we need to set its level.</p>
<h3>Ruby 2.3</h3>
<pre><code class="language-ruby">
require 'logger'
logger = Logger.new(STDOUT)
logger.level = Logger::INFO

</code></pre>
<p>If we are working with <code>ActiveRecord::Base.logger</code>, then same code would look
something like this.</p>
<pre><code class="language-ruby">
require 'logger'
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.logger.level = Logger::INFO

</code></pre>
<p>As we can see in the both the cases we need to set the level separately after
instantiating the object.</p>
<h3>Ruby 2.4</h3>
<p>In Ruby 2.4, <code>level</code> can now be specified in the constructor.</p>
<pre><code class="language-ruby">
#ruby 2.4
require 'logger'
logger = Logger.new(STDOUT, level: Logger::INFO)

# let's verify it
logger.level      #=&gt; 1

</code></pre>
<p>Similarly, other options such as <code>progname</code>, <code>formatter</code> and <code>datetime_format</code>,
which prior to Ruby 2.4 had to be explicitly set, can now be set during the
instantiation.</p>
<pre><code class="language-ruby">#ruby 2.3
require 'logger'
logger = Logger.new(STDOUT)
logger.level = Logger::INFO
logger.progname = 'bigbinary'
logger.datetime_format = '%Y-%m-%d %H:%M:%S'
logger.formatter = proc do |severity, datetime, progname, msg|
  &quot;#{severity} #{datetime} ==&gt; App: #{progname}, Message: #{msg}\n&quot;
end

logger.info(&quot;Program started...&quot;)
#=&gt; INFO 2017-03-16 18:43:58 +0530 ==&gt; App: bigbinary, Message: Program started...
</code></pre>
<p>Here is same stuff in Ruby 2.4.</p>
<pre><code class="language-ruby">#ruby 2.4
require 'logger'
logger = Logger.new(STDOUT,
  level: Logger::INFO,
  progname: 'bigbinary',
  datetime_format: '%Y-%m-%d %H:%M:%S',
  formatter: proc do |severity, datetime, progname, msg|
    &quot;#{severity} #{datetime} ==&gt; App: #{progname}, Message: #{msg}\n&quot;
  end
)

logger.info(&quot;Program started...&quot;)
#=&gt; INFO 2017-03-16 18:47:39 +0530 ==&gt; App: bigbinary, Message: Program started...

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 has default basename for Tempfile#create]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-has-default-basename-for-tempfile-create"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-default-basename-for-tempfile-create.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-has-default-basename-for-tempfile-create</id>
      <published>2017-04-04T00:00:00.000Z</published>
      <updated>2017-04-04T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-default-basename-for-tempfile-create.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Tempfile#create method now has a default empty basename]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-has-default-basename-for-tempfile-create"><![CDATA[<h3>Tempfile class</h3>
<p><a href="http://ruby-doc.org/stdlib-2.4.0/libdoc/tempfile/rdoc/Tempfile.html">Tempfile</a>
is used for managing temporary files in Ruby. A Tempfile object creates a
temporary file with a unique filename. It behaves just like a File object, and
therefore we can perform all the usual file operations on it.</p>
<h3>Why Tempfile when we can use File</h3>
<p>These days it is common to store file on services like S3. Let's say that we
have a <code>users.csv</code> file on S3. Working with this file remotely is problematic.
In such cases it is desirable to download the file on local machine for
manipulation. After the work is done then file should be deleted. Tempfile is
ideal for such cases.</p>
<h3>Basename for tempfile</h3>
<p>If we want to create a temporary file then we needed to pass parameter to it
prior to Ruby 2.3.</p>
<pre><code class="language-ruby">
require 'tempfile'
file = Tempfile.new('bigbinary')
#=&gt; #&lt;Tempfile:/var/folders/jv/fxkfk9_10nb_964rvrszs2540000gn/T/bigbinary-20170304-10828-1w02mqi&gt;

</code></pre>
<p>As we can see above the generated file name begins with &quot;bigbinary&quot; word.</p>
<p>Since Tempfile ensures that the generate filename will always be unique the
point of passing the argument is meaningless. Ruby doc calls this passing
&quot;basename&quot;.</p>
<p>So in Ruby 2.3.0 it was <a href="https://github.com/ruby/ruby/pull/523">decided</a> that
the basename parameter was meaningless for <code>Tempfile#new</code> and an empty string
will be the default value.</p>
<pre><code class="language-ruby">
require 'tempfile'
file = Tempfile.new
#=&gt; #&lt;Tempfile:/var/folders/jv/fxkfk9_10nb_964rvrszs2540000gn/T/20170304-10828-1v855bf&gt;

</code></pre>
<p>But the same was not implemented for <code>Tempfile#create</code>.</p>
<pre><code class="language-ruby">
# Ruby 2.3.0
require 'tempfile'
Tempfile.create do |f|
  f.write &quot;hello&quot;
end

ArgumentError: wrong number of arguments (given 0, expected 1..2)

</code></pre>
<p>This was <a href="https://bugs.ruby-lang.org/issues/11965">fixed</a> in Ruby 2.4. So now
the basename parameter for <code>Tempfile.create</code> is set to empty string by default,
to keep it consistent with the <code>Tempfile#new</code> method.</p>
<pre><code class="language-ruby">
# Ruby 2.4
require 'tempfile'
Tempfile.create do |f|
  f.write &quot;hello&quot;
end
=&gt; 5

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[New arguments support for float & integer modifiers]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/new-ndigits-arguments-supported-for-float-modifiers-in-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/new-ndigits-arguments-supported-for-float-modifiers-in-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/new-ndigits-arguments-supported-for-float-modifiers-in-ruby-2-4</id>
      <published>2017-03-28T00:00:00.000Z</published>
      <updated>2017-03-28T00:00:00.000Z</updated>
      <author>
        <name>Abhishek Jain</name>
        <uri>https://www.bigbinary.com/blog/authors/abhishek</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/new-ndigits-arguments-supported-for-float-modifiers-in-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Optional argument ndigits added to ceil, floor, truncate]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/new-ndigits-arguments-supported-for-float-modifiers-in-ruby-2-4"><![CDATA[<p>In Ruby, there are many methods available which help us to modify a float or
integer value.</p>
<h3>Ruby 2.3.x</h3>
<p>In the previous versions of Ruby, we could use methods such as <code>floor</code>, <code>ceil</code>
and <code>truncate</code> in following ways.</p>
<pre><code class="language-ruby">
5.54.floor          #=&gt; 5
5.54.ceil           #=&gt; 6
5.54.truncate       #=&gt; 5

</code></pre>
<p>Providing an argument to these methods would result in <code>ArgumentError</code>
exception.</p>
<h3>Ruby 2.4</h3>
<p>Ruby community decided to come up with an option to
<a href="https://bugs.ruby-lang.org/issues/12245">add precision argument</a> .</p>
<p>The precision argument, which can be negative, helps us to get result to the
required precision to either side of the decimal point.</p>
<p>The default value for the precision argument is 0.</p>
<pre><code class="language-ruby">
876.543.floor(-2)       #=&gt; 800
876.543.floor(-1)       #=&gt; 870
876.543.floor           #=&gt; 876
876.543.floor(1)        #=&gt; 876.5
876.543.floor(2)        #=&gt; 876.54

876.543.ceil(-2)        #=&gt; 900
876.543.ceil(-1)        #=&gt; 880
876.543.ceil            #=&gt; 877
876.543.ceil(1)         #=&gt; 876.6
876.543.ceil(2)         #=&gt; 876.55

876.543.truncate(-2)    #=&gt; 800
876.543.truncate(-1)    #=&gt; 870
876.543.truncate        #=&gt; 876
876.543.truncate(1)     #=&gt; 876.5
876.543.truncate(2)     #=&gt; 876.54

</code></pre>
<p>These methods all work the same on Integer as well.</p>
<pre><code class="language-ruby">
5.floor(2)              #=&gt; 5.0
5.ceil(2)               #=&gt; 5.0
5.truncate(2)           #=&gt; 5.0

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 adds Enumerable#uniq & Enumerable::Lazy#uniq]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/enumerable-uniq-and-enumerable-lazy-uniq-part-of-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/enumerable-uniq-and-enumerable-lazy-uniq-part-of-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/enumerable-uniq-and-enumerable-lazy-uniq-part-of-ruby-2-4</id>
      <published>2017-03-21T00:00:00.000Z</published>
      <updated>2017-03-21T00:00:00.000Z</updated>
      <author>
        <name>Mohit Natoo</name>
        <uri>https://www.bigbinary.com/blog/authors/mohit</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/enumerable-uniq-and-enumerable-lazy-uniq-part-of-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[In Ruby 2.4, uniq elements can be iterated upon for enumerable and lazy objects without creating an array.]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/enumerable-uniq-and-enumerable-lazy-uniq-part-of-ruby-2-4"><![CDATA[<p>In Ruby, we commonly use <code>uniq</code> method on an array to fetch the collection of
all unique elements. But there may be cases where we might need elements in a
hash by virtue of uniqueness of its values.</p>
<p>Let's consider an example of countries that have hosted the Olympics. We only
want to know when was the first time a country hosted it.</p>
<pre><code class="language-ruby">
# given object
{ 1896 =&gt; 'Athens',
  1900 =&gt; 'Paris',
  1904 =&gt; 'Chicago',
  1906 =&gt; 'Athens',
  1908 =&gt; 'Rome' }

# expected outcome
{ 1896 =&gt; 'Athens',
  1900 =&gt; 'Paris',
  1904 =&gt; 'Chicago',
  1908 =&gt; 'Rome' }

</code></pre>
<p>One way to achieve this is to have a collection of unique country names and then
check if that value is already taken while building the result.</p>
<pre><code class="language-ruby">
olympics =
{ 1896 =&gt; 'Athens',
  1900 =&gt; 'Paris',
  1904 =&gt; 'Chicago',
  1906 =&gt; 'Athens',
  1908 =&gt; 'Rome' }

unique_nations = olympics.values.uniq

olympics.select{ |year, country| !unique_nations.delete(country).nil? }
#=&gt; {1896=&gt;&quot;Athens&quot;, 1900=&gt;&quot;Paris&quot;, 1904=&gt;&quot;Chicago&quot;, 1908=&gt;&quot;Rome&quot;}

</code></pre>
<p>As we can see, the above code requires constructing an additional array
<code>unique_nations</code>.</p>
<p>In processing larger data, loading an array of considerably big size in memory
and then carrying out further processing on it, may result in performance and
memory issues.</p>
<p>In Ruby 2.4, <code>Enumerable</code> class introduces <code>uniq</code>
<a href="https://bugs.ruby-lang.org/issues/11090">method</a> that collects unique elements
while iterating over the enumerable object.</p>
<p>The usage is similar to that of Array#uniq. Uniqueness can be determined by the
elements themselves or by a value yielded by the block passed to the <code>uniq</code>
method.</p>
<pre><code class="language-ruby">
olympics = {1896 =&gt; 'Athens', 1900 =&gt; 'Paris', 1904 =&gt; 'Chicago', 1906 =&gt; 'Athens', 1908 =&gt; 'Rome'}

olympics.uniq { |year, country| country }.to_h
#=&gt; {1896=&gt;&quot;Athens&quot;, 1900=&gt;&quot;Paris&quot;, 1904=&gt;&quot;Chicago&quot;, 1908=&gt;&quot;Rome&quot;}

</code></pre>
<p>Similar method is also implemented in <code>Enumerable::Lazy</code> class. Hence we can now
call <code>uniq</code> on lazy enumerables.</p>
<pre><code class="language-ruby">
(1..Float::INFINITY).lazy.uniq { |x| (x**2) % 10 }.first(6)
#=&gt; [1, 2, 3, 4, 5, 10]

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 optimized lstrip & strip for ASCII strings]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-has-optimized-lstrip-and-strip-methods"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-optimized-lstrip-and-strip-methods.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-has-optimized-lstrip-and-strip-methods</id>
      <published>2017-03-14T00:00:00.000Z</published>
      <updated>2017-03-14T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-has-optimized-lstrip-and-strip-methods.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[lstrip and rstrip methods have been optimized in ruby 2.4]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-has-optimized-lstrip-and-strip-methods"><![CDATA[<p>Ruby has <code>lstrip</code> and <code>rstrip</code> methods which can be used to remove leading and
trailing whitespaces respectively from a string.</p>
<p>Ruby also has <code>strip</code> method which is a combination of lstrip and rstrip and can
be used to remove both, leading and trailing whitespaces, from a string.</p>
<pre><code class="language-ruby">
&quot;    Hello World    &quot;.lstrip    #=&gt; &quot;Hello World    &quot;
&quot;    Hello World    &quot;.rstrip    #=&gt; &quot;    Hello World&quot;
&quot;    Hello World    &quot;.strip     #=&gt; &quot;Hello World&quot;

</code></pre>
<p>Prior to Ruby 2.4, the <code>rstrip</code> method was optimized for performance, but the
<code>lstrip</code> and <code>strip</code> were somehow missed. In Ruby 2.4, <code>String#lstrip</code> and
<code>String#strip</code> methods too have been
<a href="https://bugs.ruby-lang.org/issues/12788">optimized</a> to get the performance
benefit of <code>String#rstrip</code> .</p>
<p>Let's run following snippet in Ruby 2.3 and Ruby 2.4 to benchmark and compare
the performance improvement.</p>
<pre><code class="language-ruby">
require 'benchmark/ips'

Benchmark.ips do |bench|
  str1 = &quot; &quot; * 10_000_000 + &quot;hello world&quot; + &quot; &quot; * 10_000_000
  str2 = str1.dup
  str3 = str1.dup

  bench.report('String#lstrip') do
    str1.lstrip
  end

  bench.report('String#rstrip') do
    str2.rstrip
  end

  bench.report('String#strip') do
    str3.strip
  end
end

</code></pre>
<h4>Result for Ruby 2.3</h4>
<pre><code class="language-ruby">
Warming up --------------------------------------
       String#lstrip     1.000  i/100ms
       String#rstrip     8.000  i/100ms
        String#strip     1.000  i/100ms
Calculating -------------------------------------
       String#lstrip     10.989  (± 0.0%) i/s -     55.000  in   5.010903s
       String#rstrip     92.514  (± 5.4%) i/s -    464.000  in   5.032208s
        String#strip     10.170  (± 0.0%) i/s -     51.000  in   5.022118s

</code></pre>
<h4>Result for Ruby 2.4</h4>
<pre><code class="language-ruby">
Warming up --------------------------------------
       String#lstrip    14.000  i/100ms
       String#rstrip     8.000  i/100ms
        String#strip     6.000  i/100ms
Calculating -------------------------------------
       String#lstrip    143.424  (± 4.2%) i/s -    728.000  in   5.085311s
       String#rstrip     89.150  (± 5.6%) i/s -    448.000  in   5.041301s
        String#strip     67.834  (± 4.4%) i/s -    342.000  in   5.051584s

</code></pre>
<p>From the above results, we can see that in Ruby 2.4, <code>String#lstrip</code> is around
14x faster while <code>String#strip</code> is around 6x faster. <code>String#rstrip</code> as
expected, has nearly the same performance as it was already optimized in
previous versions.</p>
<h3>Performance remains same for multi-byte strings</h3>
<p>Strings can have single byte or multi-byte characters.</p>
<p>For example <code>Lé Hello World</code> is a multi-byte string because of the presence of
<code>é</code> which is a multi-byte character.</p>
<pre><code class="language-ruby">'e'.bytesize        #=&gt; 1
'é'.bytesize        #=&gt; 2
</code></pre>
<p>Let's do performance benchmarking with string <code>Lé hello world</code> instead of
<code>hello world</code>.</p>
<h4>Result for Ruby 2.3</h4>
<pre><code class="language-ruby">
Warming up --------------------------------------
       String#lstrip     1.000  i/100ms
       String#rstrip     1.000  i/100ms
        String#strip     1.000  i/100ms
Calculating -------------------------------------
       String#lstrip     11.147  (± 9.0%) i/s -     56.000  in   5.034363s
       String#rstrip      8.693  (± 0.0%) i/s -     44.000  in   5.075011s
        String#strip      5.020  (± 0.0%) i/s -     26.000  in   5.183517s

</code></pre>
<h4>Result for Ruby 2.4</h4>
<pre><code class="language-ruby">
Warming up --------------------------------------
       String#lstrip     1.000  i/100ms
       String#rstrip     1.000  i/100ms
        String#strip     1.000  i/100ms
Calculating -------------------------------------
       String#lstrip     10.691  (± 0.0%) i/s -     54.000  in   5.055101s
       String#rstrip      9.524  (± 0.0%) i/s -     48.000  in   5.052678s
        String#strip      4.860  (± 0.0%) i/s -     25.000  in   5.152804s

</code></pre>
<p>As we can see, the performance for multi-byte strings is almost the same across
Ruby 2.3 and Ruby 2.4.</p>
<h4>Explanation</h4>
<p>The optimization introduced is related to how the strings are parsed to detect
for whitespaces. Checking for whitespaces in multi-byte string requires an
additional overhead. So the <a href="https://bugs.ruby-lang.org/issues/12788">patch</a>
adds an initial condition to check if the string is a single byte string, and if
so, processes it separately.</p>
<p>In most of the cases, the strings are single byte so the performance improvement
would be visible and helpful.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[IO#readlines now accepts chomp flag as an argument]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/io-readlines-now-accepts-chomp-flag-as-an-argument"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/io-readlines-now-accepts-chomp-flag-as-an-argument.png"/>
      <id>https://www.bigbinary.com/blog/io-readlines-now-accepts-chomp-flag-as-an-argument</id>
      <published>2017-03-07T00:00:00.000Z</published>
      <updated>2017-03-07T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/io-readlines-now-accepts-chomp-flag-as-an-argument.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[IO methods now have an optional chomp flag to remove newline return characters]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/io-readlines-now-accepts-chomp-flag-as-an-argument"><![CDATA[<p>Consider the following file which needs to be read in Ruby. We can use the
<code>IO#readlines</code> method to get the lines in an array.</p>
<pre><code class="language-plaintext">
# lotr.txt

Three Rings for the Elven-kings under the sky,
Seven for the Dwarf-lords in their halls of stone,
Nine for Mortal Men doomed to die,
One for the Dark Lord on his dark throne
In the Land of Mordor where the Shadows lie.

</code></pre>
<h3>Ruby 2.3</h3>
<pre><code class="language-ruby">
IO.readlines('lotr.txt')
#=&gt; [&quot;Three Rings for the Elven-kings under the sky,\n&quot;, &quot;Seven for the Dwarf-lords in their halls of stone,\n&quot;, &quot;Nine for Mortal Men doomed to die,\n&quot;, &quot;One for the Dark Lord on his dark throne\n&quot;, &quot;In the Land of Mordor where the Shadows lie.&quot;]

</code></pre>
<p>As we can see, the lines in the array have a <code>\n</code>, newline character, which is
not skipped while reading the lines. The newline character needs to be chopped
in most of the cases. Prior to Ruby 2.4, it could be done in the following way.</p>
<pre><code class="language-ruby">
IO.readlines('lotr.txt').map(&amp;:chomp)
#=&gt; [&quot;Three Rings for the Elven-kings under the sky,&quot;, &quot;Seven for the Dwarf-lords in their halls of stone,&quot;, &quot;Nine for Mortal Men doomed to die,&quot;, &quot;One for the Dark Lord on his dark throne&quot;, &quot;In the Land of Mordor where the Shadows lie.&quot;]

</code></pre>
<h3>Ruby 2.4</h3>
<p>Since it was a common requirement, Ruby team decided to
<a href="https://bugs.ruby-lang.org/issues/12553">add</a> an optional parameter to the
<code>readlines</code> method. So the same can now be achieved in Ruby 2.4 in the following
way.</p>
<pre><code class="language-ruby">
IO.readlines('lotr.txt', chomp: true)
#=&gt; [&quot;Three Rings for the Elven-kings under the sky,&quot;, &quot;Seven for the Dwarf-lords in their halls of stone,&quot;, &quot;Nine for Mortal Men doomed to die,&quot;, &quot;One for the Dark Lord on his dark throne&quot;, &quot;In the Land of Mordor where the Shadows lie.&quot;]

</code></pre>
<p>Additionally, <code>IO#gets</code>, <code>IO#readline</code>, <code>IO#each_line</code>, <code>IO#foreach</code> methods
also have been modified to accept an optional chomp flag.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[open-uri in Ruby 2.4 allows http to https redirection]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/open-uri-in-ruby-2-4-allows-http-to-https-redirection"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/open-uri-in-ruby-2-4-allows-http-to-https-redirection.png"/>
      <id>https://www.bigbinary.com/blog/open-uri-in-ruby-2-4-allows-http-to-https-redirection</id>
      <published>2017-03-02T00:00:00.000Z</published>
      <updated>2017-03-02T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/open-uri-in-ruby-2-4-allows-http-to-https-redirection.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[open-uri now allows http to https redirection in Ruby 2.4]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/open-uri-in-ruby-2-4-allows-http-to-https-redirection"><![CDATA[<p>In Ruby 2.3, if the argument to <code>open-uri</code> is http and the host redirects to
https , then <code>open-uri</code> would throw an error.</p>
<pre><code class="language-ruby">
&gt; require 'open-uri'
&gt; open('http://www.google.com/gmail')

RuntimeError: redirection forbidden: http://www.google.com/gmail -&gt; https://www.google.com/gmail/

</code></pre>
<p>To get around this issue, we could use
<a href="https://github.com/open-uri-redirections/open_uri_redirections">open_uri_redirections</a>
gem.</p>
<pre><code class="language-ruby">
&gt; require 'open-uri'
&gt; require 'open_uri_redirections'
&gt; open('http://www.google.com/gmail/', :allow_redirections =&gt; :safe)

=&gt; #&lt;Tempfile:/var/folders/jv/fxkfk9_10nb_964rvrszs2540000gn/T/open-uri20170228-41042-2fffoa&gt;

</code></pre>
<h3>Ruby 2.4</h3>
<p>In Ruby 2.4, this issue is <a href="https://bugs.ruby-lang.org/issues/859">fixed</a>. So
now http to https redirection is possible using open-uri.</p>
<pre><code class="language-ruby">
&gt; require 'open-uri'
&gt; open('http://www.google.com/gmail')
=&gt; #&lt;Tempfile:/var/folders/jv/fxkfk9_10nb_964rvrszs2540000gn/T/open-uri20170228-41077-1bkm1dv&gt;

</code></pre>
<p>Note that redirection from https to http will raise an error, like it did in
previous versions, since that has possible security concerns.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 now has Dir.empty? and File.empty? methods]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/dir-emtpy-included-in-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/dir-emtpy-included-in-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/dir-emtpy-included-in-ruby-2-4</id>
      <published>2017-02-28T00:00:00.000Z</published>
      <updated>2017-02-28T00:00:00.000Z</updated>
      <author>
        <name>Ratnadeep Deshmane</name>
        <uri>https://www.bigbinary.com/blog/authors/rtdp</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/dir-emtpy-included-in-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[No more platform specific code to check empty directories]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/dir-emtpy-included-in-ruby-2-4"><![CDATA[<p>In Ruby, to check if a given directory is empty or not, we check it as</p>
<pre><code class="language-ruby">
Dir.entries(&quot;/usr/lib&quot;).size == 2       #=&gt; false
Dir.entries(&quot;/home&quot;).size == 2          #=&gt; true

</code></pre>
<p>Every directory in Unix filesystem contains at least two entries. These are
<code>.</code>(current directory) and <code>..</code>(parent directory).</p>
<p>Hence, the code above checks if there are only two entries and if so, consider a
directory empty.</p>
<p>Again, this code only works for UNIX filesystems and fails on Windows machines,
as Windows directories don't have <code>.</code> or <code>..</code>.</p>
<h2>Dir.empty?</h2>
<p>Considering all this, Ruby has finally
<a href="https://bugs.ruby-lang.org/issues/10121">included</a> a new method <code>Dir.empty?</code>
that takes directory path as argument and returns boolean as an answer.</p>
<p>Here is an example.</p>
<pre><code class="language-ruby">
Dir.empty?('/Users/rtdp/Documents/posts')   #=&gt; true

</code></pre>
<p>Most importantly this method works correctly in all platforms.</p>
<h2>File.empty?</h2>
<p>To check if a file is empty, Ruby has <code>File.zero?</code> method. This checks if the
file exists and has zero size.</p>
<pre><code class="language-ruby">
File.zero?('/Users/rtdp/Documents/todo.txt')    #=&gt; true

</code></pre>
<p>After introducing <code>Dir.empty?</code> it makes sense to
<a href="https://bugs.ruby-lang.org/issues/9969">add</a> <code>File.empty?</code> as an alias to
<code>File.zero?</code></p>
<pre><code class="language-ruby">
File.empty?('/Users/rtdp/Documents/todo.txt')    #=&gt; true

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 Integer#digits extract digits in place-value]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-implements-integer-digits-for-extracting-digits-in-place-value-notation"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-implements-integer-digits-for-extracting-digits-in-place-value-notation.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-implements-integer-digits-for-extracting-digits-in-place-value-notation</id>
      <published>2017-02-23T00:00:00.000Z</published>
      <updated>2017-02-23T00:00:00.000Z</updated>
      <author>
        <name>Rohit Kumar</name>
        <uri>https://www.bigbinary.com/blog/authors/rkr090</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-implements-integer-digits-for-extracting-digits-in-place-value-notation.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 implements Integer#digits for extracting digits in place-value notation which is useful in calculating checksum digits.]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-implements-integer-digits-for-extracting-digits-in-place-value-notation"><![CDATA[<p>If we want to extract all the digits of an integer
<a href="https://en.wikipedia.org/wiki/Positional_notation">from right to left</a>, the
newly added <a href="https://bugs.ruby-lang.org/issues/12447">Integer#digits</a> method
will come in handy.</p>
<pre><code class="language-ruby">
567321.digits
#=&gt; [1, 2, 3, 7, 6, 5]

567321.digits[3]
#=&gt; 7

</code></pre>
<p>We can also supply a different base as an argument.</p>
<pre><code class="language-ruby">
0123.digits(8)
#=&gt; [3, 2, 1]

0xabcdef.digits(16)
#=&gt; [15, 14, 13, 12, 11, 10]

</code></pre>
<h4>Use case of digits</h4>
<p>We can use <code>Integer#digits</code> to sum all the digits in an integer.</p>
<pre><code class="language-ruby">
123.to_s.chars.map(&amp;:to_i).sum
#=&gt; 6

123.digits.sum
#=&gt; 6

</code></pre>
<p>Also while calculating checksums like
<a href="https://en.wikipedia.org/wiki/Luhn_algorithm">Luhn</a> and
<a href="https://en.wikipedia.org/wiki/Verhoeff_algorithm">Verhoeff</a>, <code>Integer#digits</code>
will help in reducing string allocation.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 adds compare by identity functionality]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-adds-compare-by-identity-functionality-for-sets"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-compare-by-identity-functionality-for-sets.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-adds-compare-by-identity-functionality-for-sets</id>
      <published>2016-12-29T00:00:00.000Z</published>
      <updated>2016-12-29T00:00:00.000Z</updated>
      <author>
        <name>Chirag Shah</name>
        <uri>https://www.bigbinary.com/blog/authors/chiraggshah</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-compare-by-identity-functionality-for-sets.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 adds compare_by_identity and compare_by_identity? methods for Set class so that now we can compare the set elements by their identitiy rather than value]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-adds-compare-by-identity-functionality-for-sets"><![CDATA[<p>In Ruby, <code>Object#equal?</code> method is used to compare two objects by their
identity, that is, the two objects are exactly the same or not. Ruby also has
<code>Object#eql?</code> method which returns true if two objects have the same value.</p>
<p>For example:</p>
<pre><code class="language-ruby">
str1 = &quot;Sample string&quot;
str2 = str1.dup

str1.eql?(str2) #=&gt; true

str1.equal?(str2) #=&gt; false

</code></pre>
<p>We can see that object ids of the objects are not same.</p>
<pre><code class="language-ruby">
str1.object_id #=&gt; 70334175057920

str2.object_id #=&gt; 70334195702480

</code></pre>
<p>In ruby, <a href="http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html">Set</a> does
not allow duplicate items in its collection. To determine if two items are equal
or not in a <code>Set</code> ruby uses <code>Object#eql?</code> and not <code>Object#equal?</code>.</p>
<p>So if we want to add two different objects with the same values in a set, that
would not have been possible prior to Ruby 2.4 .</p>
<h3>Ruby 2.3</h3>
<pre><code class="language-ruby">
require 'set'

set = Set.new #=&gt; #&lt;Set: {}&gt;

str1 = &quot;Sample string&quot; #=&gt; &quot;Sample string&quot;
str2 = str1.dup #=&gt; &quot;Sample string&quot;

set.add(str1) #=&gt; #&lt;Set: {&quot;Sample string&quot;}&gt;
set.add(str2) #=&gt; #&lt;Set: {&quot;Sample string&quot;}&gt;

</code></pre>
<p>But with the new
<a href="http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html#method-i-compare_by_identity">Set#compare_by_identity method introduced in Ruby 2.4</a>,
sets can now compare its values using <code>Object#equal?</code> and check for the exact
same objects.</p>
<h3>Ruby 2.4</h3>
<pre><code class="language-ruby">
require 'set'

set = Set.new.compare_by_identity #=&gt; #&lt;Set: {}&gt;

str1 = &quot;Sample string&quot; #=&gt; &quot;Sample string&quot;
str2 = str1.dup #=&gt; &quot;Sample string&quot;

set.add(str1) #=&gt; #&lt;Set: {&quot;Sample string&quot;}&gt;
set.add(str2) #=&gt; #&lt;Set: {&quot;Sample string&quot;, &quot;Sample string&quot;}&gt;

</code></pre>
<h2>Set#compare_by_identity?</h2>
<p>Ruby 2.4 also provides the
<a href="http://ruby-doc.org/stdlib-2.4.0/libdoc/set/rdoc/Set.html#method-i-compare_by_identity-3F">compare_by_identity? method</a>
to know if the set will compare its elements by their identity.</p>
<pre><code class="language-ruby">
require 'set'

set1= Set.new #=&gt; #&lt;Set: {}&gt;
set2= Set.new.compare_by_identity #=&gt; #&lt;Set: {}&gt;

set1.compare_by_identity? #=&gt; false

set2.compare_by_identity? #=&gt; true

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 MatchData#values_at]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2.4-adds-matchdata-values-at-for-extracting-named-and-positional-capture-groups"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2.4-adds-matchdata-values-at-for-extracting-named-and-positional-capture-groups.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2.4-adds-matchdata-values-at-for-extracting-named-and-positional-capture-groups</id>
      <published>2016-12-21T00:00:00.000Z</published>
      <updated>2016-12-21T00:00:00.000Z</updated>
      <author>
        <name>Rohit Kumar</name>
        <uri>https://www.bigbinary.com/blog/authors/rkr090</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2.4-adds-matchdata-values-at-for-extracting-named-and-positional-capture-groups.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 adds ability to extract named capture groups through values_at]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2.4-adds-matchdata-values-at-for-extracting-named-and-positional-capture-groups"><![CDATA[<h3>Ruby 2.3</h3>
<p>We can use <code>MatchData#[]</code> to extract named capture and positional capture
groups.</p>
<pre><code class="language-ruby">
pattern=/(?&lt;number&gt;\d+) (?&lt;word&gt;\w+)/
pattern.match('100 thousand')[:number]
#=&gt; &quot;100&quot;

pattern=/(\d+) (\w+)/
pattern.match('100 thousand')[2]
#=&gt; &quot;thousand&quot;

</code></pre>
<p>Positional capture groups could also be extracted using <code>MatchData#values_at</code>.</p>
<pre><code class="language-ruby">
pattern=/(\d+) (\w+)/
pattern.match('100 thousand').values_at(2)
#=&gt; [&quot;thousand&quot;]

</code></pre>
<h3>Changes in Ruby 2.4</h3>
<p>In Ruby 2.4, we can pass string or symbol to extract named capture groups to
method <code>#values_at</code>.</p>
<pre><code class="language-ruby">
pattern=/(?&lt;number&gt;\d+) (?&lt;word&gt;\w+)/
pattern.match('100 thousand').values_at(:number)
#=&gt; [&quot;100&quot;]

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 adds infinite? and finite? methods to Numeric]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-adds-infinite-method-to-numeric"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-infinite-method-to-numeric.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-adds-infinite-method-to-numeric</id>
      <published>2016-12-19T00:00:00.000Z</published>
      <updated>2016-12-19T00:00:00.000Z</updated>
      <author>
        <name>Abhishek Jain</name>
        <uri>https://www.bigbinary.com/blog/authors/abhishek</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-infinite-method-to-numeric.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Fixnum#infinite?/Bignum#infinite? and Numeric#finite?/Bignum#finite? methods are now consistent with Float#infinite?/BigDecimal#infinite?]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-adds-infinite-method-to-numeric"><![CDATA[<h3>Prior to Ruby 2.4</h3>
<p>Prior to Ruby 2.4, Float and BigDecimal responded to methods <code>infinite?</code> and
<code>finite?</code>, whereas Fixnum and Bignum did not.</p>
<h4>Ruby 2.3</h4>
<pre><code class="language-ruby">#infinite?

5.0.infinite?
=&gt; nil

Float::INFINITY.infinite?
=&gt; 1

5.infinite?
NoMethodError: undefined method `infinite?' for 5:Fixnum

</code></pre>
<pre><code class="language-ruby">#finite?

5.0.finite?
=&gt; true

5.finite?
NoMethodError: undefined method `finite?' for 5:Fixnum

</code></pre>
<h4>Ruby 2.4</h4>
<p>To make behavior for all the numeric values to be consistent,
<a href="https://bugs.ruby-lang.org/issues/12039">infinite? and finite? were added to Fixnum and Bignum</a>
even though they would always return nil.</p>
<p>This gives us ability to call these methods irrespective of whether they are
simple numbers or floating numbers.</p>
<pre><code class="language-ruby">#infinite?

5.0.infinite?
=&gt; nil

Float::INFINITY.infinite?
=&gt; 1

5.infinite?
=&gt; nil

</code></pre>
<pre><code class="language-ruby">#finite?

5.0.finite?
=&gt; true

5.finite?
=&gt; true

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 adds Comparable#clamp method]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-adds-comparable-clamp-method"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-comparable-clamp-method.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-adds-comparable-clamp-method</id>
      <published>2016-12-13T00:00:00.000Z</published>
      <updated>2016-12-13T00:00:00.000Z</updated>
      <author>
        <name>Abhishek Jain</name>
        <uri>https://www.bigbinary.com/blog/authors/abhishek</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-comparable-clamp-method.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Comparable#clamp method is added to Ruby 2.4 to limit the object to a specific range of values]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-adds-comparable-clamp-method"><![CDATA[<p>In Ruby 2.4,
<a href="https://bugs.ruby-lang.org/issues/10594">clamp method is added to the Comparable module</a>.
This method can be used to clamp an object within a specific range of values.</p>
<p><code>clamp</code> method takes min and max as two arguments to define the range of values
in which the given argument should be clamped.</p>
<h4>Clamping numbers</h4>
<p><code>clamp</code> can be used to keep a number within the range of min, max.</p>
<pre><code class="language-ruby">
10.clamp(5, 20)
=&gt; 10

10.clamp(15, 20)
=&gt; 15

10.clamp(0, 5)
=&gt; 5

</code></pre>
<h4>Clamping strings</h4>
<p>Similarly, strings can also be clamped within a range.</p>
<pre><code class="language-ruby">
&quot;e&quot;.clamp(&quot;a&quot;, &quot;s&quot;)
=&gt; &quot;e&quot;

&quot;e&quot;.clamp(&quot;f&quot;, &quot;s&quot;)
=&gt; &quot;f&quot;

&quot;e&quot;.clamp(&quot;a&quot;, &quot;c&quot;)
=&gt; &quot;c&quot;

&quot;this&quot;.clamp(&quot;thief&quot;, &quot;thin&quot;)
=&gt; &quot;thin&quot;

</code></pre>
<p>Internally, this method relies on applying the
<a href="https://en.wikipedia.org/wiki/Three-way_comparison">spaceship &lt;=&gt; operator</a>
between the object and the min &amp; max arguments.</p>
<pre><code class="language-ruby">if x &lt;=&gt; min &lt; 0, x = min;
if x &lt;=&gt; max &gt; 0 , x = max
else x
</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[New liberal_parsing option for parsing bad CSV data]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-introduces-liberal_parsing-option-for-parsing-bad-csv-data"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-introduces-liberal_parsing-option-for-parsing-bad-csv-data.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-introduces-liberal_parsing-option-for-parsing-bad-csv-data</id>
      <published>2016-11-22T00:00:00.000Z</published>
      <updated>2016-11-22T00:00:00.000Z</updated>
      <author>
        <name>Ershad Kunnakkadan</name>
        <uri>https://www.bigbinary.com/blog/authors/ershad</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-introduces-liberal_parsing-option-for-parsing-bad-csv-data.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[CSV input with unescaped double quotes can now be parsed in Ruby 2.4 using liberal_parsing option]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-introduces-liberal_parsing-option-for-parsing-bad-csv-data"><![CDATA[<p>Comma-Separated Values (CSV) is a widely used data format and almost every
language has a module to parse it. In Ruby, we have
<a href="http://ruby-doc.org/stdlib-2.3.2/libdoc/csv/rdoc/CSV.html">CSV class</a> to do
that.</p>
<p>According to <a href="https://tools.ietf.org/html/rfc4180#page-4">RFC 4180</a>, we cannot
have unescaped double quotes in CSV input since such data can't be parsed.</p>
<p>We get <code>MalformedCSVError</code> error when the CSV data does not conform to RFC 4180.</p>
<p>Ruby 2.4 has added a
<a href="https://bugs.ruby-lang.org/issues/11839">liberal parsing option</a> to parse such
bad data. When it is set to <code>true</code>, Ruby will try to parse the data even when
the data does not conform to RFC 4180.</p>
<pre><code class="language-ruby">
# Before Ruby 2.4

&gt; CSV.parse_line('one,two&quot;,three,four')

CSV::MalformedCSVError: Illegal quoting in line 1.


# With Ruby 2.4

&gt; CSV.parse_line('one,two&quot;,three,four', liberal_parsing: true)

=&gt; [&quot;one&quot;, &quot;two\&quot;&quot;, &quot;three&quot;, &quot;four&quot;]

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Enumerable#chunk not mandatory in Ruby 2.4]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/passing-block-with-enumerable-chunk-is-not-mandatory-in-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/passing-block-with-enumerable-chunk-is-not-mandatory-in-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/passing-block-with-enumerable-chunk-is-not-mandatory-in-ruby-2-4</id>
      <published>2016-11-21T00:00:00.000Z</published>
      <updated>2016-11-21T00:00:00.000Z</updated>
      <author>
        <name>Abhishek Jain</name>
        <uri>https://www.bigbinary.com/blog/authors/abhishek</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/passing-block-with-enumerable-chunk-is-not-mandatory-in-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Enumerable#chunk does not require a block to be passed along with it in Ruby 2.4]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/passing-block-with-enumerable-chunk-is-not-mandatory-in-ruby-2-4"><![CDATA[<p><a href="https://ruby-doc.org/core-2.3.2/Enumerable.html#method-i-chunk">Enumerable#chunk</a>
method can be used on enumerator object to group consecutive items based on the
value returned from the block passed to it.</p>
<pre><code class="language-ruby">
[1, 4, 7, 10, 2, 6, 15].chunk { |item| item &gt; 5 }.each { |values| p values }

=&gt; [false, [1, 4]]
[true, [7, 10]]
[false, [2]]
[true, [6, 15]]

</code></pre>
<p>Prior to Ruby 2.4, passing a block to <code>chunk</code> method was must.</p>
<pre><code class="language-ruby">
array = [1,2,3,4,5,6]
array.chunk

=&gt; ArgumentError: no block given

</code></pre>
<h3>Enumerable#chunk without block in Ruby 2.4</h3>
<p>In Ruby 2.4, we will be able to use
<a href="https://bugs.ruby-lang.org/issues/2172">chunk without passing block</a>. It just
returns the enumerator object which we can use to chain further operations.</p>
<pre><code class="language-ruby">
array = [1,2,3,4,5,6]
array.chunk

=&gt; &lt;Enumerator: [1, 2, 3, 4, 5, 6]:chunk&gt;

</code></pre>
<h3>Reasons for this change</h3>
<p>Let's take the
<a href="http://stackoverflow.com/questions/8621733/how-do-i-summarize-array-of-integers-as-an-array-of-ranges">case of listing</a>
consecutive integers in an array of ranges.</p>
<pre><code class="language-ruby">
# Before Ruby 2.4

integers = [1,2,4,5,6,7,9,13]

integers.enum_for(:chunk).with_index { |x, idx| x - idx }.map do |diff, group|
  [group.first, group.last]
end

=&gt; [[1,2],[4,7],[9,9],[13,13]]

</code></pre>
<p>We had to use
<a href="http://ruby-doc.org/core-2.3.2/Object.html#method-i-enum_for">enum_for</a> here as
<code>chunk</code> can't be called without block.</p>
<p><code>enum_for</code> creates a new enumerator object which will enumerate by calling the
method passed to it. In this case the method passed was <code>chunk</code>.</p>
<p>With Ruby 2.4, we can use <code>chunk</code> method directly without using <code>enum_for</code> as it
does not require a block to be passed.</p>
<pre><code class="language-ruby">
# Ruby 2.4

integers = [1,2,4,5,6,7,9,13]

integers.chunk.with_index { |x, idx| x - idx }.map do |diff, group|
  [group.first, group.last]
end

=&gt; [[1,2],[4,7],[9,9],[13,13]]

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 unifies Fixnum and Bignum into Integer]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-unifies-fixnum-and-bignum-into-integer"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-unifies-fixnum-and-bignum-into-integer.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-unifies-fixnum-and-bignum-into-integer</id>
      <published>2016-11-18T00:00:00.000Z</published>
      <updated>2016-11-18T00:00:00.000Z</updated>
      <author>
        <name>Prathamesh Sonpatki</name>
        <uri>https://www.bigbinary.com/blog/authors/prathamesh</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-unifies-fixnum-and-bignum-into-integer.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 has unified Fixnum and Bignum into Integer class. It has also deprecated usage of Fixnum and Bignum]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-unifies-fixnum-and-bignum-into-integer"><![CDATA[<p>Ruby uses <code>Fixnum</code> class for representing small numbers and <code>Bignum</code> class for
big numbers.</p>
<pre><code class="language-ruby"># Before Ruby 2.4

1.class         #=&gt; Fixnum
(2 ** 62).class #=&gt; Bignum
</code></pre>
<p>In general routine work we don't have to worry about whether the number we are
dealing with is <code>Bignum</code> or <code>Fixnum</code>. It's just an implementation detail.</p>
<p>Interestingly, Ruby also has <code>Integer</code> class which is superclass for <code>Fixnum</code>
and <code>Bignum</code>.</p>
<p>Starting with Ruby 2.4, Fixnum and Bignum
<a href="https://bugs.ruby-lang.org/issues/12005">are unified into Integer</a>.</p>
<pre><code class="language-ruby"># Ruby 2.4

1.class         #=&gt; Integer
(2 ** 62).class #=&gt; Integer
</code></pre>
<p>Starting with Ruby 2.4 usage of Fixnum and Bignum constants
<a href="https://bugs.ruby-lang.org/issues/12739">is deprecated</a>.</p>
<pre><code class="language-ruby"># Ruby 2.4

&gt;&gt; Fixnum
(irb):6: warning: constant ::Fixnum is deprecated
=&gt; Integer

&gt;&gt; Bignum
(irb):7: warning: constant ::Bignum is deprecated
=&gt; Integer
</code></pre>
<h2>How to know if a number is Fixnum, Bignum or Integer?</h2>
<p>We don't have to worry about this change most of the times in our application
code. But libraries like Rails use the class of numbers for taking certain
decisions. These libraries need to support both Ruby 2.4 and previous versions
of Ruby.</p>
<p>Easiest way to know whether the Ruby version is using integer unification or not
is to check class of 1.</p>
<pre><code class="language-ruby"># Ruby 2.4

1.class #=&gt; Integer

# Before Ruby 2.4
1.class #=&gt; Fixnum
</code></pre>
<p>Look at <a href="https://github.com/rails/rails/pull/25056">PR #25056</a> to see how Rails
is handling this case.</p>
<p>Similarly Arel is
<a href="https://github.com/rails/arel/commit/dc85a6e9c74942945ad696f5da4d82490a85b865">also supporting</a>
both Ruby 2.4 and previous versions of Ruby.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 implements Array#min and Array#max]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-implements-array-min-and-max"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-implements-array-min-and-max.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-implements-array-min-and-max</id>
      <published>2016-11-17T00:00:00.000Z</published>
      <updated>2016-11-17T00:00:00.000Z</updated>
      <author>
        <name>Rohit Kumar</name>
        <uri>https://www.bigbinary.com/blog/authors/rkr090</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-implements-array-min-and-max.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 implements Array#min and Array#max to find the minimum and maximum value of the array]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-implements-array-min-and-max"><![CDATA[<p>Ruby has <code>Enumerable#min</code> and <code>Enumerable#max</code> which can be used to find the
minimum and the maximum value in an Array.</p>
<pre><code class="language-ruby">
(1..10).to_a.max
#=&gt; 10
(1..10).to_a.method(:max)
#=&gt; #&lt;Method: Array(Enumerable)#max&gt;

</code></pre>
<p>Ruby 2.4 adds <a href="https://bugs.ruby-lang.org/issues/12172">Array#min and Array#max</a>
which are much faster than <code>Enumerable#max</code> and <code>Enuermable#min</code>.</p>
<p>Following benchmark is based on
<a href="https://blog.blockscore.com/new-features-in-ruby-2-4">https://blog.blockscore.com/new-features-in-ruby-2-4</a>
.</p>
<pre><code class="language-ruby">Benchmark.ips do |bench|
  NUM1 = 1_000_000.times.map { rand }
  NUM2 = NUM1.dup

  ENUM_MAX = Enumerable.instance_method(:max).bind(NUM1)
  ARRAY_MAX = Array.instance_method(:max).bind(NUM2)

  bench.report('Enumerable#max') do
    ENUM_MAX.call
  end

  bench.report('Array#max') do
    ARRAY_MAX.call
  end

  bench.compare!
end

Warming up --------------------------------------
      Enumerable#max     1.000  i/100ms
           Array#max     2.000  i/100ms
Calculating -------------------------------------
      Enumerable#max     17.569  (± 5.7%) i/s -     88.000  in   5.026996s
           Array#max     26.703  (± 3.7%) i/s -    134.000  in   5.032562s

Comparison:
           Array#max:       26.7 i/s
      Enumerable#max:       17.6 i/s - 1.52x  slower

Benchmark.ips do |bench|
  NUM1 = 1_000_000.times.map { rand }
  NUM2 = NUM1.dup

  ENUM_MIN = Enumerable.instance_method(:min).bind(NUM1)
  ARRAY_MIN = Array.instance_method(:min).bind(NUM2)

  bench.report('Enumerable#min') do
    ENUM_MIN.call
  end

  bench.report('Array#min') do
    ARRAY_MIN.call
  end

  bench.compare!
end

Warming up --------------------------------------
      Enumerable#min     1.000  i/100ms
           Array#min     2.000  i/100ms
Calculating -------------------------------------
      Enumerable#min     18.621  (± 5.4%) i/s -     93.000  in   5.007244s
           Array#min     26.902  (± 3.7%) i/s -    136.000  in   5.064815s

Comparison:
           Array#min:       26.9 i/s
      Enumerable#min:       18.6 i/s - 1.44x  slower

</code></pre>
<p>This benchmark shows that the new methods <code>Array#max</code> and <code>Array#min</code> are about
1.5 times faster than <code>Enumerable#max</code> and <code>Enumerable#min</code>.</p>
<p>Similar to <code>Enumerable#max</code> and <code>Enumerable#min</code>, <code>Array#max</code> and <code>Array#min</code>
also assumes that the objects use
<a href="https://ruby-doc.org/core-2.3.2/Comparable.html">Comparable</a> mixin to define
<code>spaceship &lt;=&gt;</code> operator for comparing the elements.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 Extracting captured data from Regexp results]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-adds-better-support-for-extracting-captured-data-from-regexp-match-results"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-better-support-for-extracting-captured-data-from-regexp-match-results.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-adds-better-support-for-extracting-captured-data-from-regexp-match-results</id>
      <published>2016-11-10T00:00:00.000Z</published>
      <updated>2016-11-10T00:00:00.000Z</updated>
      <author>
        <name>Rohit Kumar</name>
        <uri>https://www.bigbinary.com/blog/authors/rkr090</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-adds-better-support-for-extracting-captured-data-from-regexp-match-results.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 adds support for extracting named captures and positional capture groups from Regexp match results]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-adds-better-support-for-extracting-captured-data-from-regexp-match-results"><![CDATA[<p>Ruby has <a href="https://ruby-doc.org/core-2.2.0/MatchData.html">MatchData</a> type which
is returned by <code>Regexp#match</code> and <code>Regexp.last_match</code>.</p>
<p>It has methods <code>#names</code> and <code>#captures</code> to return the names used for capturing
and the actual captured data respectively.</p>
<pre><code class="language-ruby">
pattern = /(?&lt;number&gt;\d+) (?&lt;word&gt;\w+)/
match_data = pattern.match('100 thousand')
#=&gt; #&lt;MatchData &quot;100 thousand&quot; number:&quot;100&quot; word:&quot;thousand&quot;&gt;

&gt;&gt; match_data.names
=&gt; [&quot;number&quot;, &quot;word&quot;]
&gt;&gt; match_data.captures
=&gt; [&quot;100&quot;, &quot;thousand&quot;]

</code></pre>
<p>If we want all named captures in a key value pair, we have to combine the result
of names and captures.</p>
<pre><code class="language-ruby">
match_data.names.zip(match_data.captures).to_h
#=&gt; {&quot;number&quot;=&gt;&quot;100&quot;, &quot;word&quot;=&gt;&quot;thousand&quot;}

</code></pre>
<p>Ruby 2.4 adds <a href="https://bugs.ruby-lang.org/issues/11999"><code>#named_captures</code></a> which
returns both the name and data of the capture groups.</p>
<pre><code class="language-ruby">
pattern=/(?&lt;number&gt;\d+) (?&lt;word&gt;\w+)/
match_data = pattern.match('100 thousand')

match_data.named_captures
#=&gt; {&quot;number&quot;=&gt;&quot;100&quot;, &quot;word&quot;=&gt;&quot;thousand&quot;}

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 Regexp#match? not polluting global variables]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-implements-regexp-match-without-polluting-global-variables"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-implements-regexp-match-without-polluting-global-variables.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-implements-regexp-match-without-polluting-global-variables</id>
      <published>2016-11-04T00:00:00.000Z</published>
      <updated>2016-11-04T00:00:00.000Z</updated>
      <author>
        <name>Rohit Kumar</name>
        <uri>https://www.bigbinary.com/blog/authors/rkr090</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-implements-regexp-match-without-polluting-global-variables.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 now allows matching a regex without updating global variables using Regexp#match?. This is a faster option to match regexes when we don't care about the match data]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-implements-regexp-match-without-polluting-global-variables"><![CDATA[<p>Ruby has many ways to match with a regular expression.</p>
<h4>Regexp#===</h4>
<p>It returns true/false and sets the $~ global variable.</p>
<pre><code class="language-ruby">
/stat/ === &quot;case statements&quot;
#=&gt; true
$~
#=&gt; #&lt;MatchData &quot;stat&quot;&gt;

</code></pre>
<h3>Regexp#=~</h3>
<p>It returns integer position it matched or nil if no match. It also sets the $~
global variable.</p>
<pre><code class="language-ruby">
/stat/ =~ &quot;case statements&quot;
#=&gt; 5
$~
#=&gt; #&lt;MatchData &quot;stat&quot;&gt;

</code></pre>
<h3>Regexp#match</h3>
<p>It returns match data and also sets the $~ global variable.</p>
<pre><code class="language-ruby">
/stat/.match(&quot;case statements&quot;)
#=&gt; #&lt;MatchData &quot;stat&quot;&gt;
$~
#=&gt; #&lt;MatchData &quot;stat&quot;&gt;

</code></pre>
<h3>Ruby 2.4 adds Regexp#match?</h3>
<p><a href="https://bugs.ruby-lang.org/issues/8110">This new method</a> just returns
true/false and does not set any global variables.</p>
<pre><code class="language-ruby">
/case/.match?(&quot;case statements&quot;)
#=&gt; true
</code></pre>
<p>So <code>Regexp#match?</code> is good option when we are only concerned with the fact that
regex matches or not.</p>
<p><code>Regexp#match?</code> is also faster than its counterparts as it reduces object
allocation by not creating a back reference and changing <code>$~</code>.</p>
<pre><code class="language-ruby">
require 'benchmark/ips'

Benchmark.ips do |bench|

  EMAIL_ADDR = 'disposable.style.email.with+symbol@example.com'
  EMAIL_REGEXP_DEVISE = /\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/

  bench.report('Regexp#===') do
    EMAIL_REGEXP_DEVISE === EMAIL_ADDR
  end

  bench.report('Regexp#=~') do
    EMAIL_REGEXP_DEVISE =~ EMAIL_ADDR
  end

  bench.report('Regexp#match') do
    EMAIL_REGEXP_DEVISE.match(EMAIL_ADDR)
  end

  bench.report('Regexp#match?') do
    EMAIL_REGEXP_DEVISE.match?(EMAIL_ADDR)
  end

  bench.compare!
end

#=&gt; Warming up --------------------------------------
#=&gt;          Regexp#===   103.876k i/100ms
#=&gt;           Regexp#=~   105.843k i/100ms
#=&gt;        Regexp#match    58.980k i/100ms
#=&gt;       Regexp#match?   107.287k i/100ms
#=&gt; Calculating -------------------------------------
#=&gt;          Regexp#===      1.335M (± 9.5%) i/s -      6.648M in   5.038568s
#=&gt;           Regexp#=~      1.369M (± 6.7%) i/s -      6.880M in   5.049481s
#=&gt;        Regexp#match    709.152k (± 5.4%) i/s -      3.539M in   5.005514s
#=&gt;       Regexp#match?      1.543M (± 4.6%) i/s -      7.725M in   5.018696s
#=&gt;
#=&gt; Comparison:
#=&gt;       Regexp#match?:  1542589.9 i/s
#=&gt;           Regexp#=~:  1369421.3 i/s - 1.13x  slower
#=&gt;          Regexp#===:  1335450.3 i/s - 1.16x  slower
#=&gt;        Regexp#match:   709151.7 i/s - 2.18x  slower

</code></pre>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.4 implements Enumerable#sum]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-4-introduces-enumerable-sum"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-introduces-enumerable-sum.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-4-introduces-enumerable-sum</id>
      <published>2016-11-02T00:00:00.000Z</published>
      <updated>2016-11-02T00:00:00.000Z</updated>
      <author>
        <name>Mohit Natoo</name>
        <uri>https://www.bigbinary.com/blog/authors/mohit</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-4-introduces-enumerable-sum.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[In Ruby 2.4, every object belonging to the `Enumerable` family can now call `sum` method on it]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-4-introduces-enumerable-sum"><![CDATA[<p>It is a common use case to calculate sum of the elements of an array or values
from a hash.</p>
<pre><code class="language-ruby">
[1, 2, 3, 4] =&gt; 10

{a: 1, b: 6, c: -3} =&gt; 4

</code></pre>
<p>Active Support already implements
<a href="https://github.com/rails/rails/blob/3d716b9e66e334c113c98fb3fc4bcf8a945b93a1/activesupport/lib/active_support/core_ext/enumerable.rb#L2-L27">Enumerable#sum</a></p>
<pre><code class="language-ruby">
&gt; [1, 2, 3, 4].sum
 #=&gt; 10

&gt; {a: 1, b: 6, c: -3}.sum{ |k, v| v**2 }
 #=&gt; 46

&gt; ['foo', 'bar'].sum # concatenation of strings
 #=&gt; &quot;foobar&quot;

&gt; [[1], ['abc'], [6, 'qwe']].sum # concatenation of arrays
 #=&gt; [1, &quot;abc&quot;, 6, &quot;qwe&quot;]

</code></pre>
<p>Until Ruby 2.3, we had to use Active Support to use <code>Enumerable#sum</code> method or
we could use <code>#inject</code> which is
<a href="https://github.com/rails/rails/blob/3d716b9e66e334c113c98fb3fc4bcf8a945b93a1/activesupport/lib/active_support/core_ext/enumerable.rb#L2-L27">used by Active Support under the hood</a>.</p>
<p>Ruby 2.4.0 implements
<a href="https://github.com/ruby/ruby/commit/41ef7ec381338a97d15a6b4b18acd8b426a9ce79">Enumerable#sum</a>
as <a href="https://bugs.ruby-lang.org/issues/12217">part of the language</a> itself.</p>
<p>Let's take a look at how <code>sum</code> method fares on some of the enumerable objects in
Ruby 2.4.</p>
<pre><code class="language-ruby">
&gt; [1, 2, 3, 4].sum
 #=&gt; 10

&gt; {a: 1, b: 6, c: -3}.sum { |k, v| v**2 }
 #=&gt; 46

&gt; ['foo', 'bar'].sum
 #=&gt; TypeError: String can't be coerced into Integer

&gt; [[1], ['abc'], [6, 'qwe']].sum
 #=&gt; TypeError: Array can't be coerced into Integer

</code></pre>
<p>As we can see, the behavior of <code>Enumerable#sum</code> from Ruby 2.4 is same as that of
Active Support in case of numbers but not the same in case of string or array
concatenation. Let's see what is the difference and how we can make it work in
Ruby 2.4 as well.</p>
<h3>Understanding addition/concatenation identity</h3>
<p>The <code>Enumerable#sum</code> method takes an optional argument which acts as an
accumulator. Both Active Support and Ruby 2.4 accept this argument.</p>
<p>When identity argument is not passed, <code>0</code> is used as default accumulator in Ruby
2.4 whereas Active Support uses <code>nil</code> as default accumulator.</p>
<p>Hence in the cases of string and array concatenation, the error occurred in Ruby
because the code attempts to add a string and array respectively to <code>0</code>.</p>
<p>To overcome this, we need to pass proper addition/concatenation identity as an
argument to the <code>sum</code> method.</p>
<p>The addition/concatenation identity of an object can be defined as the value
with which calling <code>+</code> operation on an object returns the same object.</p>
<pre><code class="language-ruby">
&gt; ['foo', 'bar'].sum('')
 #=&gt; &quot;foobar&quot;

&gt; [[1], ['abc'], [6, 'qwe']].sum([])
 #=&gt; [1, &quot;abc&quot;, 6, &quot;qwe&quot;]

</code></pre>
<h3>What about Rails ?</h3>
<p>As we have seen earlier, Ruby 2.4 implements <code>Enumerable#sum</code> favouring numeric
operations whereas also supporting non-numeric callers with the identity
element. This behavior is not entirely same as that of Active Support. But still
Active Support can make use of the native sum method whenever possible. There is
already a <a href="https://github.com/rails/rails/pull/25202">pull request</a> open which
uses <code>Enumerable#sum</code> from Ruby whenever possible. This will help gain some
performance boost as the Ruby's method is implemented natively in C whereas that
in Active Support is implemented in Ruby.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[String#concat, Array#concat & String#prepend Ruby 2.4]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/string-array-concat-and-string-prepend-take-multiple-arguments-in-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/string-array-concat-and-string-prepend-take-multiple-arguments-in-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/string-array-concat-and-string-prepend-take-multiple-arguments-in-ruby-2-4</id>
      <published>2016-10-28T00:00:00.000Z</published>
      <updated>2016-10-28T00:00:00.000Z</updated>
      <author>
        <name>Abhishek Jain</name>
        <uri>https://www.bigbinary.com/blog/authors/abhishek</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/string-array-concat-and-string-prepend-take-multiple-arguments-in-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 now allows concat and prepend methods to take multiple arguments]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/string-array-concat-and-string-prepend-take-multiple-arguments-in-ruby-2-4"><![CDATA[<p>In Ruby, we use <code>#concat</code> to append a string to another string or an element to
the array. We can also use <code>#prepend</code> to add a string at the beginning of a
string.</p>
<h3>Ruby 2.3</h3>
<h4>String#concat and Array#concat</h4>
<pre><code class="language-ruby">
string = &quot;Good&quot;
string.concat(&quot; morning&quot;)
#=&gt; &quot;Good morning&quot;

array = ['a', 'b', 'c']
array.concat(['d'])
#=&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;]

</code></pre>
<h4>String#prepend</h4>
<pre><code class="language-ruby">
string = &quot;Morning&quot;
string.prepend(&quot;Good &quot;)
#=&gt; &quot;Good morning&quot;

</code></pre>
<p>Before Ruby 2.4, we could pass only one argument to these methods. So we could
not add multiple items in one shot.</p>
<pre><code class="language-ruby">
string = &quot;Good&quot;
string.concat(&quot; morning&quot;, &quot; to&quot;, &quot; you&quot;)
#=&gt; ArgumentError: wrong number of arguments (given 3, expected 1)

</code></pre>
<h3>Changes with Ruby 2.4</h3>
<p>In Ruby 2.4, we can pass multiple arguments and Ruby processes each argument one
by one.</p>
<h4>String#concat and Array#concat</h4>
<pre><code class="language-ruby">
string = &quot;Good&quot;
string.concat(&quot; morning&quot;, &quot; to&quot;, &quot; you&quot;)
#=&gt; &quot;Good morning to you&quot;

array = ['a', 'b']
array.concat(['c'], ['d'])
#=&gt; [&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;]

</code></pre>
<h4>String#prepend</h4>
<pre><code class="language-ruby">
string = &quot;you&quot;
string.prepend(&quot;Good &quot;, &quot;morning &quot;, &quot;to &quot;)
#=&gt; &quot;Good morning to you&quot;

</code></pre>
<p>These methods work even when no argument is passed unlike in previous versions
of Ruby.</p>
<pre><code class="language-ruby">
&quot;Good&quot;.concat
#=&gt; &quot;Good&quot;

</code></pre>
<h4>Difference between <code>concat</code> and shovel <code>&lt;&lt;</code> operator</h4>
<p>Though shovel <code>&lt;&lt;</code> operator can be used interchangeably with <code>concat</code> when we
are calling it once, there is a difference in the behavior when calling it
multiple times.</p>
<pre><code class="language-ruby">
str = &quot;Ruby&quot;
str &lt;&lt; str
str
#=&gt; &quot;RubyRuby&quot;

str = &quot;Ruby&quot;
str.concat str
str
#=&gt; &quot;RubyRuby&quot;

str = &quot;Ruby&quot;
str &lt;&lt; str &lt;&lt; str
#=&gt; &quot;RubyRubyRubyRuby&quot;

str = &quot;Ruby&quot;
str.concat str, str
str
#=&gt; &quot;RubyRubyRuby&quot;

</code></pre>
<p>So <code>concat</code> behaves as appending <code>present</code> content to the caller twice. Whereas
calling <code>&lt;&lt;</code> twice is just sequence of binary operations. So the argument for
the second call is output of the first <code>&lt;&lt;</code> operation.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Hash#compact and Hash#compact! now part of Ruby 2.4]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/hash-compact-and-hash-compact-now-part-of-ruby-2-4"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/hash-compact-and-hash-compact-now-part-of-ruby-2-4.png"/>
      <id>https://www.bigbinary.com/blog/hash-compact-and-hash-compact-now-part-of-ruby-2-4</id>
      <published>2016-10-24T00:00:00.000Z</published>
      <updated>2016-10-24T00:00:00.000Z</updated>
      <author>
        <name>Prathamesh Sonpatki</name>
        <uri>https://www.bigbinary.com/blog/authors/prathamesh</uri>
      </author>
      <category term="Ruby 2.4"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/hash-compact-and-hash-compact-now-part-of-ruby-2-4.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.4 has added Hash#compact and Hash#compact! methods into core]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/hash-compact-and-hash-compact-now-part-of-ruby-2-4"><![CDATA[<p>It is a common use case to remove the <code>nil</code> values from a hash in Ruby.</p>
<pre><code class="language-ruby">{ &quot;name&quot; =&gt; &quot;prathamesh&quot;, &quot;email&quot; =&gt; nil} =&gt; { &quot;name&quot; =&gt; &quot;prathamesh&quot; }
</code></pre>
<p>Active Support already has a solution for this in the form of
<a href="http://api.rubyonrails.org/classes/Hash.html#method-i-compact">Hash#compact</a>
and
<a href="http://api.rubyonrails.org/classes/Hash.html#method-i-compact-21">Hash#compact!</a>.</p>
<pre><code class="language-ruby">hash = { &quot;name&quot; =&gt; &quot;prathamesh&quot;, &quot;email&quot; =&gt; nil}
hash.compact #=&gt; { &quot;name&quot; =&gt; &quot;prathamesh&quot; }
hash #=&gt; { &quot;name&quot; =&gt; &quot;prathamesh&quot;, &quot;email&quot; =&gt; nil}

hash.compact! #=&gt; { &quot;name&quot; =&gt; &quot;prathamesh&quot; }
hash #=&gt; { &quot;name&quot; =&gt; &quot;prathamesh&quot; }
</code></pre>
<p>Now, Ruby 2.4 will have these 2 methods in the
<a href="https://bugs.ruby-lang.org/issues/11818">language</a>
<a href="https://bugs.ruby-lang.org/issues/12863">itself</a>, so even those not using Rails
or Active Support will be able to use them. Additionally it will also give
performance boost over the Active Support versions because now these methods are
implemented in C natively whereas the Active Support versions are in Ruby.</p>
<p>There is already a
<a href="https://github.com/rails/rails/pull/26868">pull request open</a> in Rails to use
the native versions of these methods from Ruby 2.4 whenever available so that we
will be able to use the performance boost.</p>
]]></content>
    </entry>
</feed>