<?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.6</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-6/feed.xml"/>
  <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/categories/ruby-2-6"/>
  <id>https://www.bigbinary.com/blog/categories/ruby-2-6</id>
  <updated>2019-03-05T00: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 2019 Big Binary LLC</rights>
  <generator uri="https://nextjs.org">Next.js</generator>
  <entry>
      <title type="text"><![CDATA[MJIT Support in Ruby 2.6]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/mjit-support-in-ruby-2-6"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/mjit-support-in-ruby-2-6.png"/>
      <id>https://www.bigbinary.com/blog/mjit-support-in-ruby-2-6</id>
      <published>2019-03-05T00:00:00.000Z</published>
      <updated>2019-03-05T00:00:00.000Z</updated>
      <author>
        <name>Sudeep Tarlekar</name>
        <uri>https://www.bigbinary.com/blog/authors/sudeeptarlekar</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/mjit-support-in-ruby-2-6.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[What is JIT? JIT stands for Just-In-Time compiler. JIT converts repetitive code into bytecode which can then be sent to the processor directly, hence, saving time by not compiling the same piece of...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/mjit-support-in-ruby-2-6"><![CDATA[<h3>What is JIT?</h3>
<p>JIT stands for Just-In-Time compiler. JIT converts repetitive code into bytecode
which can then be sent to the processor directly, hence, saving time by not
compiling the same piece of code over and over.</p>
<h3>Ruby 2.6</h3>
<p>MJIT is introduced in Ruby 2.6. It is most commonly known as MRI JIT or Method
Based JIT.</p>
<p>It is a part of the Ruby 3x3 project started by Matz. The name &quot;Ruby 3x3&quot;
signifies Ruby 3.0 will be 3 times faster than Ruby 2.0 and it will focus mainly
on performance. In addition to performance, it also aims for the following
things:</p>
<ol>
<li>Portability</li>
<li>Stability</li>
<li>Security</li>
</ol>
<p>MJIT is still in development, therefore, MJIT is optional in Ruby 2.6. If you
are running Ruby 2.6, then you can execute the following command.</p>
<pre><code class="language-shell">ruby --help
</code></pre>
<p>You will see following options.</p>
<pre><code class="language-shell">--Jit-wait # Wait program execution until code compiles.
--jit-verbose=num # Level information MJIT compiler prints for Ruby program.
--jit-min-calls=num # Minimum count in loops for which MJIT should work.
--jit-max-cache
--jit-save-temps # Save compiled library to the file.
</code></pre>
<p>Vladimir Makarov proposed improving performance by replacing VM instructions
with RTL(Register Transfer Language) and introducing the Method based JIT
compiler.</p>
<p>Vladimir explained MJIT architecture in his
<a href="https://youtu.be/qpZDw-p9yag?t=1655">RubyKaigi 2017 conference keynote</a>.</p>
<p>Ruby's compiler converts the code to YARV(Yet Another Ruby VM) instructions and
then these instructions are run by the Ruby Virtual Machine. Code that is
executed too often is converted to RTL instructions, which runs faster.</p>
<p>Let's take a look at how MJIT works.</p>
<pre><code class="language-ruby">
# mjit.rb

require 'benchmark'

puts Benchmark.measure {
def test_while
start_time = Time.now
i = 0

    while i &lt; 4
      i += 1
    end

    i
    puts Time.now - start_time

end

4.times { test_while }
}
</code></pre>
<p>Let's run this code with MJIT options and check what we got.</p>
<pre><code class="language-shell">ruby --jit --jit-verbose=1 --jit-wait --disable-gems mjit.rb
</code></pre>
<pre><code class="language-shell">Time taken is 4.0e-06
Time taken is 0.0
Time taken is 0.0
Time taken is 0.0
0.000082 0.000032 0.000114 ( 0.000105)
Successful MJIT finish
</code></pre>
<p>Nothing interesting right? And why is that? because we are iterating the loop
for 4 times and default value for MJIT to work is 5. We can always decide after
how many calls MJIT should work by providing <code>--jit-min-calls=#number</code> option.</p>
<p>Let's tweak the program a bit so MJIT gets to work.</p>
<pre><code class="language-ruby">require 'benchmark'

puts Benchmark.measure {
def test_while
start_time = Time.now
i = 0

    while i &lt; 4_00_00_000
      i += 1
    end

    puts &quot;Time taken is #{Time.now - start_time}&quot;

end

10.times { test_while }
}
</code></pre>
<p>After running the above code we can see some work done by MJIT.</p>
<pre><code class="language-shell">Time taken is 0.457916
Time taken is 0.455921
Time taken is 0.454672
Time taken is 0.452823
JIT success (72.5ms): block (2 levels) in &lt;main&gt;@mjit.rb:15 -&gt; /var/folders/v6/\_6sh53vn5gl3lct18w533gr80000gn/T//\_ruby_mjit_p66220u0.c
JIT success (140.9ms): test_while@mjit.rb:4 -&gt; /var/folders/v6/\_6sh53vn5gl3lct18w533gr80000gn/T//\_ruby_mjit_p66220u1.c
JIT compaction (23.0ms): Compacted 2 methods -&gt; /var/folders/v6/\_6sh53vn5gl3lct18w533gr80000gn/T//\_ruby_mjit_p66220u2.bundle
Time taken is 0.463703
Time taken is 0.102852
Time taken is 0.103335
Time taken is 0.103299
Time taken is 0.103252
Time taken is 0.103261
2.797843 0.005357 3.141944 ( 2.801391)
Successful MJIT finish
</code></pre>
<p>Here's what's happening. Method ran 4 times and on the 5th call it found it is
running same code again. So MJIT started a separate thread to convert the code
into RTL instructions, which created a shared object library. Next, threads took
that shared code and executed directly. As we passed option <code>--jit-verbose=1</code> we
can see what MJIT did.</p>
<p>What we are seeing in output is the following:</p>
<ol>
<li>Time taken to compile.</li>
<li>What block of code is compiled by JIT.</li>
<li>Location of compiled code.</li>
</ol>
<p>We can open the file and see how MJIT converted the piece of code to binary
instructions but for that we need to pass another option which is
<code>--jit-save-temps</code> and then just inspect those files.</p>
<p>After compiling the code to RTL instructions, take a look at the execution time.
It dropped down to 0.10 ms from 0.46 ms. That's a neat speed bump.</p>
<p>Here is a comparison across some of the Ruby versions for some basic operations.</p>
<p>![Ruby time comparison in different versions](/blog/images/images_used_in_blog/image
ruby_mjit_execution_comparison.png)</p>
<h2>Rails comparison on Ruby 2.5, Ruby 2.6 and Ruby 2.6 with JIT</h2>
<p>Create a rails application with different Ruby versions and start a server. We
can start the rails server with the JIT option, as shown below.</p>
<pre><code class="language-shell">RUBYOPT=&quot;--jit&quot; bundle exec rails s
</code></pre>
<p>Now, we can start testing the performance on servers. We found that Ruby 2.6 is
faster than Ruby 2.5, but enabling JIT in Ruby 2.6 does not add more value to
the Rails application.</p>
<h2>MJIT status and future directions</h2>
<ul>
<li>It is in an early development stage.</li>
<li>Does not work on windows.</li>
<li>Needs more time to mature.</li>
<li>Needs more optimisations.</li>
<li>MJIT can use GCC or LLVM in the future C Compilers.</li>
</ul>
<h2>Further reading</h2>
<ol>
<li><a href="https://developers.redhat.com/blog/2018/03/22/ruby-3x3-performance-goal">Ruby 3x3 Performance Goal</a></li>
<li><a href="https://medium.com/@k0kubun/the-method-jit-compiler-for-ruby-2-6-388ee0989c13">The method JIT compiler for Ruby2.6</a></li>
<li><a href="https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch">Vladimir Makarov's Ruby Edition</a></li>
</ol>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 Range#cover? accepts Range object as argument]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-range-cover-now-accepts-range-object"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-range-cover-now-accepts-range-object.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-range-cover-now-accepts-range-object</id>
      <published>2018-10-24T00:00:00.000Z</published>
      <updated>2018-10-24T00:00:00.000Z</updated>
      <author>
        <name>Abhay Nikam</name>
        <uri>https://www.bigbinary.com/blog/authors/abhay</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-range-cover-now-accepts-range-object.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.6 Range#cover? now accepts Range object as an argument]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-range-cover-now-accepts-range-object"><![CDATA[<p><code>Range#cover?</code> returns true if the object passed as argument is in the range.</p>
<pre><code class="language-ruby">(1..10).cover?(5)
=&gt; true
</code></pre>
<p><code>Range#cover?</code> returns false if the object passed as an argument is
non-comparable or is not in the range.</p>
<p>Before Ruby 2.6, <code>Range#cover?</code> used to return false if a Range object is passed
as an argument.</p>
<pre><code class="language-ruby">&gt;&gt; (1..10).cover?(2..5)
=&gt; false
</code></pre>
<h4>Ruby 2.6</h4>
<p>In Ruby 2.6 <code>Range#cover?</code> can accept a Range object as an argument. It returns
true if the argument Range is equal to or a subset of the Range.</p>
<pre><code class="language-ruby">(1..100).cover?(10..20)
=&gt; true

(1..10).cover?(2..5)
=&gt; true

(5..).cover?(4..)
=&gt; false

(&quot;a&quot;..&quot;d&quot;).cover?(&quot;x&quot;..&quot;z&quot;)
=&gt; false
</code></pre>
<p>Here is relevant
<a href="https://github.com/ruby/ruby/commit/9ca738927293df1c7a2a1ed7e2d6cf89527b5438">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/14473">discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds RubyVM::AST module]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-rubyvm-ast-module"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-rubyvm-ast-module.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-rubyvm-ast-module</id>
      <published>2018-10-02T00:00:00.000Z</published>
      <updated>2018-10-02T00:00:00.000Z</updated>
      <author>
        <name>Amit Choudhary</name>
        <uri>https://www.bigbinary.com/blog/authors/amit</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-rubyvm-ast-module.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.6 added RubyVM::AST to generate the Abstract Syntax Tree of code. Please note, this feature is experimental and under active development. As of now, RubyVM::AST supports two methods: parse and...]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-rubyvm-ast-module"><![CDATA[<p>Ruby 2.6 added <code>RubyVM::AST</code> to generate the
<a href="https://en.wikipedia.org/wiki/Abstract_syntax_tree">Abstract Syntax Tree</a> of
code. Please note, this feature is experimental and under active development.</p>
<p>As of now, <code>RubyVM::AST</code> supports two methods: <code>parse</code> and <code>parse_file</code>.</p>
<p><code>parse</code> method takes a string as a parameter and returns the root node of the
tree in the form of the object, RubyVM::AST::Node (Link is not available).</p>
<p><code>parse_file</code> method takes the file name as a parameter and returns the root node
of the tree in the form of the object,
<a href="https://ruby-doc.org/core-2.6.0.preview2/RubyVM/AST/Node.html">RubyVM::AST::Node</a>.</p>
<h4>Ruby 2.6.0-preview2</h4>
<pre><code class="language-ruby">irb&gt; RubyVM::AST.parse(&quot;(1..100).select { |num| num % 5 == 0 }&quot;)
=&gt; #&lt;RubyVM::AST::Node(NODE_SCOPE(0) 1:0, 1:38): &gt;

irb&gt; RubyVM::AST.parse_file(&quot;/Users/amit/app.rb&quot;)
=&gt; #&lt;RubyVM::AST::Node(NODE_SCOPE(0) 1:0, 1:38): &gt;
</code></pre>
<p><a href="https://ruby-doc.org/core-2.6.0.preview2/RubyVM/AST/Node.html">RubyVM::AST::Node</a>
has seven public instance methods - <code>children</code>, <code>first_column</code>, <code>first_lineno</code>,
<code>inspect</code>, <code>last_column</code>, <code>last_lineno</code> and <code>type</code>.</p>
<h4>Ruby 2.6.0-preview2</h4>
<pre><code class="language-ruby">irb&gt; ast_node = RubyVM::AST.parse(&quot;(1..100).select { |num| num % 5 == 0 }&quot;)
=&gt; #&lt;RubyVM::AST::Node(NODE_SCOPE(0) 1:0, 1:38): &gt;

irb&gt; ast_node.children
=&gt; [nil, #&lt;RubyVM::AST::Node(NODE_ITER(9) 1:0, 1:38): &gt;]

irb&gt; ast_node.first_column
=&gt; 0

irb&gt; ast_node.first_lineno
=&gt; 1

irb&gt; ast_node.inspect
=&gt; &quot;#&lt;RubyVM::AST::Node(NODE_SCOPE(0) 1:0, 1:38): &gt;&quot;

irb&gt; ast_node.last_column
=&gt; 38

irb&gt; ast_node.last_lineno
=&gt; 1

irb&gt; ast_node.type
=&gt; &quot;NODE_SCOPE&quot;
</code></pre>
<p>This module will majorly help in building a static code analyzer and formatter.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds Enumerable#filter as alias for #select]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-enumerable-filter-as-an-alias-of-enumerable-select"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-enumerable-filter-as-an-alias-of-enumerable-select.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-enumerable-filter-as-an-alias-of-enumerable-select</id>
      <published>2018-08-28T00:00:00.000Z</published>
      <updated>2018-08-28T00:00:00.000Z</updated>
      <author>
        <name>Amit Choudhary</name>
        <uri>https://www.bigbinary.com/blog/authors/amit</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-enumerable-filter-as-an-alias-of-enumerable-select.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.6 adds Enumerable#filter as an alias of Enumerable#select]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-enumerable-filter-as-an-alias-of-enumerable-select"><![CDATA[<p>Ruby 2.6 has added <code>Enumerable#filter</code> as an alias of <code>Enumerable#select</code>. The
reason for adding <code>Enumerable#filter</code> as an alias is to make it easier for
people coming from other languages to use Ruby. A lot of other languages,
including Java, R, PHP etc., have a filter method to filter/select records based
on a condition.</p>
<p>Let's take an example in which we have to select/filter all numbers which are
divisible by 5 from a range.</p>
<h4>Ruby 2.5</h4>
<pre><code class="language-ruby">irb&gt; (1..100).select { |num| num % 5 == 0 }
=&gt; [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]

irb&gt; (1..100).filter { |num| num % 5 == 0 }
=&gt; Traceback (most recent call last):
2: from /Users/amit/.rvm/rubies/ruby-2.5.1/bin/irb:11:in `&lt;main&gt;' 1: from (irb):2 NoMethodError (undefined method`filter' for 1..100:Range)
</code></pre>
<h4>Ruby 2.6.0-preview2</h4>
<pre><code class="language-ruby">irb&gt; (1..100).select { |num| num % 5 == 0 }
=&gt; [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]

irb&gt; (1..100).filter { |num| num % 5 == 0 }
=&gt; [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
</code></pre>
<p>Also note, along with <code>Enumerable#filter</code>, <code>Enumerable#filter!</code>,
<code>Enumerable#select!</code> was also added as an alias.</p>
<p>Here is the relevant <a href="https://github.com/ruby/ruby/commit/b1a8c64483">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/13784">discussion</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds support for non-ASCII capital letter]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2.6-adds-support-for-non-ascii-capital-case-constant"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2.6-adds-support-for-non-ascii-capital-case-constant.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2.6-adds-support-for-non-ascii-capital-case-constant</id>
      <published>2018-08-22T00:00:00.000Z</published>
      <updated>2018-08-22T00:00:00.000Z</updated>
      <author>
        <name>Rohan Pujari</name>
        <uri>https://www.bigbinary.com/blog/authors/rohanpujaris</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2.6-adds-support-for-non-ascii-capital-case-constant.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.6 adds support for non-ASCII capital letter as a first character in constant name]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2.6-adds-support-for-non-ascii-capital-case-constant"><![CDATA[<p>Before Ruby 2.6, constant must have a capital ASCII letter as the first
character. It means class and module name cannot start with non-ASCII capital
character.</p>
<p>Below code will raise <code>class/module name must be CONSTANT</code> exception.</p>
<pre><code class="language-ruby">  class Большойдвоичный
  end
</code></pre>
<p>We can use above non-ASCII character as a method name or variable name though.</p>
<p>Below code will run without any exception</p>
<pre><code class="language-ruby">  class NonAsciiMethodAndVariable
    def Большойдвоичный
      Имя = &quot;BigBinary&quot;
    end
  end
</code></pre>
<p>&quot;Имя&quot; is treated as a variable name in above example, even though first
letter(И) is a capital non-ASCII character.</p>
<h4>Ruby 2.6</h4>
<p>Ruby 2.6 relaxes above mentioned limitation. We can now define constants in
languages other than English. Languages having capital letters like Russian and
Greek can be used to define constant name.</p>
<p>Below code will run without exception in any Ruby 2.6.</p>
<pre><code class="language-ruby">  class Большойдвоичный
  end
</code></pre>
<p>As capital non-Ascii characters are now treated as constant, below code will
raise a warning in Ruby 2.6.</p>
<pre><code class="language-ruby">  irb(main):001:0&gt; Имя = &quot;BigBinary&quot;
  =&gt; &quot;BigBinary&quot;
  irb(main):002:0&gt; Имя = &quot;BigBinary&quot;
  (irb):2: warning: already initialized constant Имя
  (irb):1: warning: previous definition of Имя was here
</code></pre>
<p>Above code will run without any warnings on Ruby versions prior to 2.6</p>
<p>Here is relevant <a href="https://github.com/ruby/ruby/commit/f852af">commit</a> and
<a href="https://bugs.ruby-lang.org/issues/13770">discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds write_timeout to Net::HTTP]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-write-timeout-to-net-http"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-write-timeout-to-net-http.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-write-timeout-to-net-http</id>
      <published>2018-08-14T00:00:00.000Z</published>
      <updated>2018-08-14T00:00:00.000Z</updated>
      <author>
        <name>Taha Husain</name>
        <uri>https://www.bigbinary.com/blog/authors/taha</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-write-timeout-to-net-http.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[write_timeout is added to Net::HTTP and Net::BufferedIO in Ruby 2.6]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-write-timeout-to-net-http"><![CDATA[<p>Before Ruby 2.6, if we created a large request with <code>Net::HTTP</code>, it would hang
forever until request is interrupted. To fix this issue,
<a href="https://docs.ruby-lang.org/en/trunk/Net/HTTP.html#attribute-i-write_timeout">write_timeout</a>
attribute and
<a href="https://docs.ruby-lang.org/en/trunk/Net/HTTP.html#method-i-write_timeout-3D">write_timeout=</a>
method is added to <a href="https://docs.ruby-lang.org/en/2.6.0/">Net::HTTP</a> in Ruby
2.6. Default value for <code>write_timeout</code> is 60 seconds and can be set to an
integer or a float value.</p>
<p>Similarly, <code>write_timeout</code> attribute and <code>write_timeout=</code> method is added to
<code>Net::BufferedIO</code> class.</p>
<p>If any chunk of response is not written within number of seconds provided to
<code>write_timeout</code>, <a href="https://docs.ruby-lang.org/en/2.6.0/">Net::WriteTimeout</a>
exception is raised. <code>Net::WriteTimeout</code> exception is not raised on Windows
systems.</p>
<h6>Example</h6>
<pre><code class="language-ruby">
# server.rb

require 'socket'

server = TCPServer.new('localhost', 2345)
loop do
socket = server.accept
end

</code></pre>
<h5>Ruby 2.5.1</h5>
<pre><code class="language-ruby">
# client.rb

require 'net/http'

connection = Net::HTTP.new('localhost', 2345)
connection.open_timeout = 1
connection.read_timeout = 3
connection.start

post = Net::HTTP::Post.new('/')
body = (('a' _ 1023) + &quot;\n&quot;) _ 5_000
post.body = body

puts &quot;Sending #{body.bytesize} bytes&quot;
connection.request(post)

</code></pre>
<h6>Output</h6>
<pre><code class="language-ruby">\$ RBENV_VERSION=2.5.1 ruby client.rb

Sending 5120000 bytes
</code></pre>
<p>Ruby 2.5.1 processes request endlessly unless above program is interrupted.</p>
<h5>Ruby 2.6.0-dev</h5>
<p>Add <code>write_timeout</code> attribute to <code>Net::HTTP</code> instance in client.rb program.</p>
<pre><code class="language-ruby">
# client.rb

require 'net/http'

connection = Net::HTTP.new('localhost', 2345)
connection.open_timeout = 1
connection.read_timeout = 3

# set write_timeout to 10 seconds

connection.write_timeout = 10

connection.start

post = Net::HTTP::Post.new('/')
body = (('a' _ 1023) + &quot;\n&quot;) _ 5_000
post.body = body

puts &quot;Sending #{body.bytesize} bytes&quot;
connection.request(post)

</code></pre>
<h6>Output</h6>
<pre><code class="language-ruby">\$ RBENV_VERSION=2.6.0-dev ruby client.rb

Sending 5120000 bytes
Traceback (most recent call last):
13: `from client.rb:17:in `&lt;main&gt;`` 12: `from /net/http.rb:1479:in `request``
11: `from /net/http.rb:1506:in `transport_request`` 10: `from /net/http.rb:1506:in `catch``
9: `from /net/http.rb:1507:in `block in transport_request`` 8: `from /net/http/generic_request.rb:123:in `exec``
7: `from /net/http/generic_request.rb:189:in `send_request_with_body`` 6: `from /net/protocol.rb:221:in `write``
5: `from /net/protocol.rb:239:in `writing`` 4: `from /net/protocol.rb:222:in `block in write``
3: `from /net/protocol.rb:249:in `write0`` 2: `from /net/protocol.rb:249:in `each_with_index``
1: `from /net/protocol.rb:249:in `each`` `/net/protocol.rb:270:in `block in write0`: Net::WriteTimeout (Net::WriteTimeout)`

</code></pre>
<p>In Ruby 2.6.0, above program is terminated raising <code>Net::WriteTimeout</code> exception
after 10 seconds (value set to <code>write_timeout</code> attribute).</p>
<p>Here is relevant <a href="https://github.com/ruby/ruby/commit/bd7c46">commit</a> and
<a href="https://bugs.ruby-lang.org/issues/13396">discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds Dir#each_child & Dir#children instance]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-introduces-dir-each_child-and-dir-children-instance-methods"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-introduces-dir-each_child-and-dir-children-instance-methods.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-introduces-dir-each_child-and-dir-children-instance-methods</id>
      <published>2018-08-07T00:00:00.000Z</published>
      <updated>2018-08-07T00:00:00.000Z</updated>
      <author>
        <name>Tejaswini Chile</name>
        <uri>https://www.bigbinary.com/blog/authors/tejaswini</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-introduces-dir-each_child-and-dir-children-instance-methods.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.6 introduces each_child and children as instance methods to have file names in a directory without `.` and `..`]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-introduces-dir-each_child-and-dir-children-instance-methods"><![CDATA[<p>Ruby 2.5 had introduced class level methods
<a href="https://ruby-doc.org/core-2.5.1/Dir.html#method-c-each_child">Dir::each_child</a>
and <a href="https://ruby-doc.org/core-2.5.1/Dir.html#method-c-children">Dir::children</a>.
We wrote a
<a href="https://blog.bigbinary.com/2017/11/21/ruby-2_5-introduces-dir-children-and-dir-each_child.html">detailed blog</a>
about it.</p>
<p>In Ruby 2.6, same methods are added as instance methods on <code>Dir</code> class.
Dir#children (Link is not available) returns array of all the filenames except
<code>.</code> and <code>..</code> in the directory. Dir#each_child (Link is not available) yields all
the filenames and operates on it.</p>
<p>Let's have a look at examples to understand it better.</p>
<h5>Dir#children</h5>
<pre><code class="language-ruby">directory = Dir.new('/Users/tejaswinichile/workspace')

directory.children
=&gt; [&quot;panda.png&quot;, &quot;apple.png&quot;, &quot;banana.png&quot;, &quot;camera.jpg&quot;]

</code></pre>
<p><code>Dir#each_child</code> iterates and calls block for each file entry in the given
directory. It uses filename as a parameter to the block.</p>
<h5>Dir#each_child</h5>
<pre><code class="language-ruby">directory = Dir.new('/Users/tejaswinichile/workspace')

directory.each_child { |filename| puts &quot;Currently reading: #{filename}&quot;}

Currently reading: panda.png
Currently reading: apple.png
Currently reading: banana.png
Currently reading: camera.jpg
=&gt; #&lt;Dir:/Users/tejaswinichile/Desktop&gt;

</code></pre>
<p>If we don't pass any block to <code>each_child</code>, it returns enumerator instead.</p>
<pre><code class="language-ruby">directory = Dir.new('/Users/tejaswinichile/workspace')

directory.each_child

=&gt; #&lt;Enumerator: #&lt;Dir:/Users/tejaswinichile/Desktop&gt;:each_child&gt;

</code></pre>
<p>Here is relevant
<a href="https://github.com/ruby/ruby/commit/6a3a7e9114c3ede47d15f0d2a73f392cfcdd1ea7">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/13969">discussion</a> for this change.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds exception parameter to Integer and Float]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-option-to-not-raise-exception-for-integer-float-methods"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-option-to-not-raise-exception-for-integer-float-methods.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-option-to-not-raise-exception-for-integer-float-methods</id>
      <published>2018-07-31T00:00:00.000Z</published>
      <updated>2018-07-31T00:00:00.000Z</updated>
      <author>
        <name>Prathamesh Sonpatki</name>
        <uri>https://www.bigbinary.com/blog/authors/prathamesh</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-option-to-not-raise-exception-for-integer-float-methods.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Instead of raising exception, we can pass a keyword argument and the type conversion methods will return nil]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-option-to-not-raise-exception-for-integer-float-methods"><![CDATA[<p>We can use <code>Integer</code> and <code>Float</code> methods to convert values to integers and
floats respectively. Ruby also has <code>to_i</code> and <code>to_f</code> methods for same purpose.
Let's see how it differs from the <code>Integer</code> method.</p>
<pre><code class="language-ruby">
&gt; &gt; &quot;1one&quot;.to_i
&gt; &gt; =&gt; 1

&gt; &gt; Integer(&quot;1one&quot;)
&gt; &gt; ArgumentError: invalid value for Integer(): &quot;1one&quot;

    from (irb):2:in `Integer'
    from (irb):2
    from /Users/prathamesh/.rbenv/versions/2.4.0/bin/irb:11:in `&lt;main&gt;'

&gt; &gt;
</code></pre>
<p>The <code>to_i</code> method tries to convert the given input to integer as much as
possible whereas the <code>Integer</code> method throws an <code>ArgumentError</code> if it can't
covert the input to integer. The <code>Integer</code> and <code>Float</code> methods parse more
strictly compared to <code>to_i</code> and <code>to_f</code> respectively.</p>
<p>Some times, we might need the strictness of <code>Integer</code> and <code>Float</code> but ability to
not raise an exception every time the input can't be parsed.</p>
<p>Before Ruby 2.6 it was possible to achieve it in following way.</p>
<pre><code class="language-ruby">
&gt; &gt; Integer(&quot;msg&quot;) rescue nil
&gt; &gt;
</code></pre>
<p>In Ruby 2.6, the
<a href="https://bugs.ruby-lang.org/issues/12732">Integer and Float methods accept a keyword argument exception</a>
which can be either <code>true</code> or <code>false</code>. If it is <code>false</code> then no exception is
raised if the input can't be parsed and <code>nil</code> is returned.</p>
<pre><code class="language-ruby">
&gt; &gt; Float(&quot;foo&quot;, exception: false)
&gt; &gt; =&gt; nil
&gt; &gt; Integer(&quot;foo&quot;, exception: false)
&gt; &gt; =&gt; nil
&gt; &gt;
</code></pre>
<p>This is also faster than rescuing the exception and returning <code>nil</code>.</p>
<pre><code class="language-ruby">
&gt; &gt; Benchmark.ips do |x|
&gt; &gt; ?&gt; x.report(&quot;rescue&quot;) {
&gt; &gt; ?&gt; Integer('foo') rescue nil
&gt; &gt; }
&gt; &gt; x.report(&quot;kwarg&quot;) {
&gt; &gt; ?&gt; Integer('foo', exception: false)
&gt; &gt; }
&gt; &gt; x.compare!
&gt; &gt; end
&gt; &gt; Warming up --------------------------------------

              rescue    41.896k i/100ms
               kwarg    81.459k i/100ms

Calculating -------------------------------------
rescue 488.006k (± 4.5%) i/s - 2.472M in 5.076848s
kwarg 1.024M (±11.8%) i/s - 5.050M in 5.024937s

Comparison:
kwarg: 1023555.3 i/s
rescue: 488006.0 i/s - 2.10x slower


</code></pre>
<p>As we can see, rescuing the exception is twice slower than using the new keyword
argument. We can still use the older technique if we want to return a different
value from <code>nil</code>.</p>
<pre><code class="language-ruby">
&gt; &gt; Integer('foo') rescue 42
&gt; &gt; =&gt; 42
&gt; &gt;
</code></pre>
<p>By default, the keyword argument <code>exception</code> is set to <code>true</code> for backward
compatibility.</p>
<p>The Chinese version of this blog is available
<a href="http://madao.me/yi-ruby-2-6-zeng-jia-liao-integer-he-float-fang-fa-de-yi-chang-can-shu/">here</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds Binding#source_location]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-binding-source-location"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-binding-source-location.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-binding-source-location</id>
      <published>2018-07-24T00:00:00.000Z</published>
      <updated>2018-07-24T00:00:00.000Z</updated>
      <author>
        <name>Taha Husain</name>
        <uri>https://www.bigbinary.com/blog/authors/taha</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-binding-source-location.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Binding#source_location is added in Ruby 2.6 which makes fetching filename and line number more readable]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-binding-source-location"><![CDATA[<p>Before Ruby 2.6, if we want to know file name with location and line number of
source code, we would need to use Binding#eval (Link is not available) .</p>
<pre><code class="language-ruby">binding.eval('[__FILE__, __LINE__]')
=&gt; [&quot;/Users/taha/blog/app/controllers/application_controller&quot;, 2]
</code></pre>
<p>Ruby 2.6 adds more readable method Binding#source_location (Link is not
available) to achieve similar result.</p>
<pre><code class="language-ruby">binding.source_location
=&gt; [&quot;/Users/taha/blog/app/controllers/application_controller&quot;, 2]
</code></pre>
<p>Here is relevant <a href="https://github.com/ruby/ruby/commit/571e48">commit</a> and
<a href="https://bugs.ruby-lang.org/issues/14230">discussion</a> for this change.</p>
<p>The Chinese version of this blog is available
<a href="http://madao.me/yi-ruby-2-6-binding-dui-xiang-zeng-jia-source_location-fang-fa/">here</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds String#split with block]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-split-with-block"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-split-with-block.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-split-with-block</id>
      <published>2018-07-17T00:00:00.000Z</published>
      <updated>2018-07-17T00:00:00.000Z</updated>
      <author>
        <name>Taha Husain</name>
        <uri>https://www.bigbinary.com/blog/authors/taha</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-split-with-block.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[String#split with block is added in Ruby 2.6. split yields each split substrings if the block is given, instead of returing the array.]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-split-with-block"><![CDATA[<p>Before Ruby 2.6,
<a href="http://ruby-doc.org/core-2.5.1/String.html#method-i-split">String#split</a>
returned array of split strings.</p>
<p>In Ruby 2.6, a block can be passed to String#split (Link is not available) which
yields each split string and operates on it. This avoids creating an array and
thus is memory efficient.</p>
<p>We will add method <code>is_fruit?</code> to understand how to use <code>split</code> with a block.</p>
<pre><code class="language-ruby">def is_fruit?(value)
%w(apple mango banana watermelon grapes guava lychee).include?(value)
end
</code></pre>
<p>Input is a comma separated string with vegetables and fruits names. Goal is to
fetch names of fruits from input string and store it in an array.</p>
<h5>String#split</h5>
<pre><code class="language-ruby">input_str = &quot;apple, mango, potato, banana, cabbage, watermelon, grapes&quot;

splitted_values = input_str.split(&quot;, &quot;)
=&gt; [&quot;apple&quot;, &quot;mango&quot;, &quot;potato&quot;, &quot;banana&quot;, &quot;cabbage&quot;, &quot;watermelon&quot;, &quot;grapes&quot;]

fruits = splitted_values.select { |value| is_fruit?(value) }
=&gt; [&quot;apple&quot;, &quot;mango&quot;, &quot;banana&quot;, &quot;watermelon&quot;, &quot;grapes&quot;]
</code></pre>
<p>Using <code>split</code> an intermediate array is created which contains both fruits and
vegetables names.</p>
<h5>String#split with a block</h5>
<pre><code class="language-ruby">fruits = []

input_str = &quot;apple, mango, potato, banana, cabbage, watermelon, grapes&quot;

input_str.split(&quot;, &quot;) { |value| fruits &lt;&lt; value if is_fruit?(value) }
=&gt; &quot;apple, mango, potato, banana, cabbage, watermelon, grapes&quot;

fruits
=&gt; [&quot;apple&quot;, &quot;mango&quot;, &quot;banana&quot;, &quot;watermelon&quot;, &quot;grapes&quot;]
</code></pre>
<p>When a block is passed to <code>split</code>, it returns the string on which split was
called and does not create an array. <code>String#split</code> yields block on each split
string, which in our case was to push fruit names in a separate array.</p>
<h4>Update</h4>
<h5>Benchmark</h5>
<p>We created a large random string to benchmark performance of <code>split</code> and
<code>split with block</code></p>
<pre><code class="language-ruby">require 'securerandom'

test_string = ''

100_000.times.each do
test_string += SecureRandom.alphanumeric(10)
test_string += ' '
end
</code></pre>
<pre><code class="language-ruby">require 'benchmark'

Benchmark.bmbm do |bench|

bench.report('split') do
arr = test_string.split(' ')
str_starts_with_a = arr.select { |str| str.start_with?('a') }
end

bench.report('split with block') do
str_starts_with_a = []
test_string.split(' ') { |str| str_starts_with_a &lt;&lt; str if str.start_with?('a') }
end

end
</code></pre>
<p>Results</p>
<pre><code class="language-plaintext">Rehearsal ----------------------------------------------------
split              0.023764   0.000911   0.024675 (  0.024686)
split with block   0.012892   0.000553   0.013445 (  0.013486)
------------------------------------------- total: 0.038120sec

                       user     system      total        real
split              0.024107   0.000487   0.024594 (  0.024622)
split with block   0.010613   0.000334   0.010947 (  0.010991)
</code></pre>
<p>We did another iteration of benchmarking using
<a href="https://github.com/evanphx/benchmark-ips">benchmark/ips</a>.</p>
<pre><code class="language-ruby">require 'benchmark/ips'
Benchmark.ips do |bench|

bench.report('split') do
splitted_arr = test_string.split(' ')
str_starts_with_a = splitted_arr.select { |str| str.start_with?('a') }
end

bench.report('split with block') do
str_starts_with_a = []
test_string.split(' ') { |str| str_starts_with_a &lt;&lt; str if str.start_with?('a') }
end

bench.compare!
end
</code></pre>
<p>Results</p>
<pre><code class="language-plaintext">Warming up --------------------------------------
               split     4.000  i/100ms
    split with block    10.000  i/100ms
Calculating -------------------------------------
               split     46.906  (± 2.1%) i/s -    236.000  in   5.033343s
    split with block    107.301  (± 1.9%) i/s -    540.000  in   5.033614s

Comparison:
    split with block:      107.3 i/s
               split:       46.9 i/s - 2.29x  slower
</code></pre>
<p>This benchmark shows that <code>split with block</code> is about 2 times faster than
<code>split</code>.</p>
<p>Here is relevant
<a href="https://github.com/ruby/ruby/commit/2258a97fe2b21da9ec294ccedd00b3bbbc85cb07">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/4780">discussion</a> for this change.</p>
<p>The Chinese version of this blog is available
<a href="http://madao.me/yi-ruby-2-6-stringde-split-fang-fa-zhi-chi-dai-ma-kuai-zhi-xing/">here</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 raises exception for else without rescue]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2.6-raise-exception-for-else-without-rescue"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2.6-raise-exception-for-else-without-rescue.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2.6-raise-exception-for-else-without-rescue</id>
      <published>2018-07-10T00:00:00.000Z</published>
      <updated>2018-07-10T00:00:00.000Z</updated>
      <author>
        <name>Rohan Pujari</name>
        <uri>https://www.bigbinary.com/blog/authors/rohanpujaris</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2.6-raise-exception-for-else-without-rescue.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Ruby 2.6 raises exception when 'else' is used inside 'begin..end' block without 'rescue']]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2.6-raise-exception-for-else-without-rescue"><![CDATA[<h4>Ruby 2.5</h4>
<p>If we use <code>else</code> without <code>rescue</code> inside <code>begin..end</code> block in Ruby 2.5, it
gives a warning.</p>
<pre><code class="language-ruby">irb(main):001:0&gt; begin
irb(main):002:1&gt; puts &quot;Inside begin block&quot;
irb(main):003:1&gt; else
irb(main):004:1&gt; puts &quot;Inside else block&quot;
irb(main):005:1&gt; end
(irb):5: warning: else without rescue is useless
</code></pre>
<p>This warning is present as code inside <code>else</code> block will never get executed</p>
<h4>Ruby 2.6</h4>
<p>In Ruby 2.6 it will raise an exception if we use <code>else</code> without <code>rescue</code> in
<code>begin..end</code> block. This
<a href="https://github.com/ruby/ruby/commit/140512d2225e6fd046ba1bdbcd1a27450f55c233#diff-ff4e2dc4962dc25a1512353299992c8d">commit</a>
changed warning into exception in Ruby 2.6. Changes made in the commit are
experimental.</p>
<pre><code class="language-ruby">irb(main):001:0&gt; begin
irb(main):002:1&gt; puts &quot;Inside begin block&quot;
irb(main):003:1&gt; else
irb(main):004:1&gt; puts &quot;Inside else block&quot;
irb(main):005:1&gt; end
Traceback (most recent call last):
1: from /usr/local/bin/irb:11:in `&lt;main&gt;'
SyntaxError ((irb):3: else without rescue is useless)
</code></pre>
<p>The Chinese version of this blog is available
<a href="http://madao.me/yi-ruby-2-6-hui-zai-begin-end-dai-ma-kuai-zhong-yin-wei-bu-xie-rescue-zhi-xie-else-er-pao-chu-yi-chang-shi-yan-xing-feature">here</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 adds endless range]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-adds-endless-range"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-endless-range.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-adds-endless-range</id>
      <published>2018-07-04T00:00:00.000Z</published>
      <updated>2018-07-04T00:00:00.000Z</updated>
      <author>
        <name>Taha Husain</name>
        <uri>https://www.bigbinary.com/blog/authors/taha</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-adds-endless-range.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[Shorter syntax for endless range with index is added in Ruby 2.6]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-adds-endless-range"><![CDATA[<p>Before Ruby 2.6, if we want endless loop with index, we would need to use
<a href="http://ruby-doc.org/core-2.5.1/Float.html#INFINITY">Float::INFINITY</a> with
<a href="http://ruby-doc.org/core-2.5.1/Integer.html#method-i-upto">up to</a> or
<a href="http://ruby-doc.org/core-2.5.1/Range.html">Range</a>, or use
<a href="http://ruby-doc.org/core-2.5.1/Numeric.html#method-i-step">Numeric#step</a>.</p>
<h5>Ruby 2.5.0</h5>
<pre><code class="language-ruby">irb&gt; (1..Float::INFINITY).each do |n|
irb\* # logic goes here
irb&gt; end
</code></pre>
<p>OR</p>
<pre><code class="language-ruby">irb&gt; 1.step.each do |n|
irb\* # logic goes here
irb&gt; end
</code></pre>
<h4>Ruby 2.6.0</h4>
<p>Ruby 2.6 makes infinite loop more readable by changing mandatory second argument
in range to optional. Internally, Ruby changes second argument to <code>nil</code> if
second argument is not provided. So, both <code>(0..)</code> and <code>(0..nil)</code> are same in
Ruby 2.6.</p>
<h6>Using endless loop in Ruby 2.6</h6>
<pre><code class="language-ruby">irb&gt; (0..).each do |n|
irb\* # logic goes here
irb&gt; end
</code></pre>
<pre><code class="language-ruby">irb&gt; (0..nil).size
=&gt; Infinity
irb&gt; (0..).size
=&gt; Infinity
</code></pre>
<p>In Ruby 2.5, <code>nil</code> is not an acceptable argument and <code>(0..nil)</code> would throw
<code>ArgumentError</code>.</p>
<pre><code class="language-ruby">irb&gt; (0..nil)
ArgumentError (bad value for range)
</code></pre>
<p>Here is the relevant
<a href="https://github.com/ruby/ruby/commit/7f95eed19e22cb9a4867819355fe4ab99f85fd16">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/12912">discussion</a> for this change.</p>
<p>The Chinese version of this blog is available
<a href="http://madao.me/yi-ruby-2-6-zeng-jia-wu-qiong-fan-wei/">here</a>.</p>
]]></content>
    </entry>
  <entry>
      <title type="text"><![CDATA[Ruby 2.6 added option to raise exception in Kernel#system]]></title>
      <link rel="alternate" type="text/html" href="https://www.bigbinary.com/blog/ruby-2-6-added-option-to-raise-exception-in-kernel-system"/>
      <link rel="enclosure" type="image/png" href="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-added-option-to-raise-exception-in-kernel-system.png"/>
      <id>https://www.bigbinary.com/blog/ruby-2-6-added-option-to-raise-exception-in-kernel-system</id>
      <published>2018-04-25T00:00:00.000Z</published>
      <updated>2018-04-25T00:00:00.000Z</updated>
      <author>
        <name>Amit Choudhary</name>
        <uri>https://www.bigbinary.com/blog/authors/amit</uri>
      </author>
      <category term="Ruby 2.6"/>
      <category term="Ruby"/>
      <media:thumbnail url="https://www.bigbinary.com/blog/images/social_preview_images/generated/ruby-2-6-added-option-to-raise-exception-in-kernel-system.png" width="1200" height="630"/>
      <summary type="text"><![CDATA[The BigBinary team's lesson on Ruby 2.6 adding an option to raise exception in Kernel#system]]></summary>
      <content type="html" xml:base="https://www.bigbinary.com/blog/ruby-2-6-added-option-to-raise-exception-in-kernel-system"><![CDATA[<p>We write scripts to automate setup and deployment of Rails applications. In
those scripts, in many places, we need to run system commands like
<code>bundle install</code>, <code>rake db:create</code>, <code>rake db:migrate</code> and many more.</p>
<p>Let's suppose we need to run migrations using <code>rake db:migrate</code> in a Rails
project setup script. We can use the <code>Kernel#system</code> method.</p>
<pre><code class="language-ruby">irb&gt; system('rake db:migrate')
</code></pre>
<h4>Ruby 2.5.0</h4>
<p>Executing <code>system</code> returns <code>true</code> or <code>false</code>. Another feature of <code>system</code> is
that it eats up the exceptions.</p>
<p>Let's suppose our migrations can run successfully. In this case the <code>system</code>
command for running migrations will return true.</p>
<pre><code class="language-ruby">irb&gt; system('rake db:migrate')
 =&gt; true
</code></pre>
<p>Let's suppose we have a migration that is trying to add a column to a table
which does not exist. In this case, the <code>system</code> command for running migrations
will return false.</p>
<pre><code class="language-ruby">irb&gt; system('rake db:migrate')
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation &quot;admins&quot; does not exist
: ALTER TABLE &quot;admins&quot; ADD &quot;first_name&quot; character varying
.
.
.
Tasks: TOP =&gt; db:migrate
(See full trace by running task with --trace)
 =&gt; false
</code></pre>
<p>As we can see, even when there is a failure in executing system commands, the
return value is false. Ruby does not raise an exception in those cases.</p>
<p>However, we can use <code>raise</code> explicitly to raise an exception and halt the setup
script execution.</p>
<pre><code class="language-ruby">irb&gt; system('rake db:migrate') || raise('Failed to run migrations')
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation &quot;admins&quot; does not exist
: ALTER TABLE &quot;admins&quot; ADD &quot;first_name&quot; character varying
.
.
.
Tasks: TOP =&gt; db:migrate
(See full trace by running task with --trace)
Traceback (most recent call last):
        2: from /Users/amit/.rvm/rubies/ruby-2.5.0/bin/irb:11:in `&lt;main&gt;'
        1: from (irb):4
RuntimeError (Failed to run migrations)
</code></pre>
<h4>Ruby 2.6.0-preview1</h4>
<p>Ruby 2.6 make our lives easier by providing an option <code>exception: true</code> so that
we do not need to use <code>raise</code> explicitly to halt script execution.</p>
<pre><code class="language-ruby">irb&gt; system('rake db:migrate', exception: true)
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation &quot;admins&quot; does not exist
: ALTER TABLE &quot;admins&quot; ADD &quot;first_name&quot; character varying
.
.
.
Tasks: TOP =&gt; db:migrate
(See full trace by running task with --trace)
Traceback (most recent call last):
        3: from /Users/amit/.rvm/rubies/ruby-2.6.0-preview1/bin/irb:11:in `&lt;main&gt;'
        2: from (irb):2
        1: from (irb):2:in `system'
RuntimeError (Command failed with exit 1: rake)
</code></pre>
<p>Ruby 2.6 works the same way as previous Ruby versions when used without the
<code>exception</code> option or used with <code>exception</code> set as false.</p>
<pre><code class="language-ruby">irb&gt; system('rake db:migrate', exception: false)
== 20180311211836 AddFirstNameToAdmins: migrating =============================
-- add_column(:admins, :first_name, :string)
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedTable: ERROR:  relation &quot;admins&quot; does not exist
: ALTER TABLE &quot;admins&quot; ADD &quot;first_name&quot; character varying
.
.
.
Tasks: TOP =&gt; db:migrate
(See full trace by running task with --trace)
 =&gt; false
</code></pre>
<p>Here is the relevant <a href="https://github.com/ruby/ruby/commit/fb29cffab0">commit</a>
and <a href="https://bugs.ruby-lang.org/issues/14386">discussion</a> for this change.</p>
<p><code>system</code> is not the only way to execute scripts like these. We wrote
<a href="https://blog.bigbinary.com/2012/10/18/backtick-system-exec-in-ruby.html">a blog</a>
6 years ago which discusses the differences between running commands using
<code>backtick</code>, <code>exec</code>, <code>sh</code>, <code>popen3</code>, <code>popen2e</code> and <code>Process.spawn</code>.</p>
<p>The Chinese version of this blog is available
<a href="http://madao.me/yi-ruby-2-6-kernel-de-system-fang-fa-zeng-jia-shi-fou-pao-chu-yi-chang-can-shu/">here</a>.</p>
]]></content>
    </entry>
</feed>