Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112023-12-09T06:21:22ZRuby Issue Tracking System
Redmine Ruby master - Feature #20054 (Rejected): Replace the use of `def` in endless method definitions w...https://bugs.ruby-lang.org/issues/200542023-12-09T06:21:22Zsawa (Tsuyoshi Sawada)
<p>I propose to remove the use of keyword <code>def</code> from the syntax of endless method definition, and introduce a new sigil instead of it. There are several possibilities for what character to use as the sigil, but the most seemingly promising one to me at this point is the colon. So, instead of:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="k">def</span> <span class="nf">foo</span> <span class="o">=</span> <span class="n">method_body</span>
</code></pre>
<p>I propose to write</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="ss">:foo</span> <span class="o">=</span> <span class="n">method_body</span>
</code></pre>
<p>There a few reasons to dispense with <code>def</code> in endless method definition.</p>
<p>First, the current syntax for endless method definition looks too similar to conventional method definition. Without endless method definition, we could already define a method in a single line:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="n">method_body</span> <span class="k">end</span>
</code></pre>
<p>and compared to this, what the endless method definition does is that, it only saves you from typing the <code>end</code> keyword just by replacing the semicolon with an equal sign. This actually had not made much sense to me. Just saving you from typing the keyword <code>end</code> looks too small of a change for introducing new syntax. In order for endless method definition syntax to be justified (as a shorthand for conventional method definition), it needs to save more typing.</p>
<p>Second, in <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Endless method and parsing priorities (Closed)" href="https://bugs.ruby-lang.org/issues/19392">#19392</a>, some people are claiming to change the precedence involving endless method definition. I agree with Matz and other developers who support the current precedence in which:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="k">def</span> <span class="nf">foo</span> <span class="o">=</span> <span class="n">bar</span> <span class="ow">and</span> <span class="n">baz</span>
</code></pre>
<p>is interpreted as:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="p">(</span><span class="k">def</span> <span class="nf">foo</span> <span class="o">=</span> <span class="n">bar</span><span class="p">)</span> <span class="ow">and</span> <span class="n">baz</span>
</code></pre>
<p>and I understand that the controversy is due to the look and feel of the keyword <code>def</code>. <code>def</code> has lower precedence than <code>and</code> in conventional method definition, although <code>=</code> has higher precedence than <code>and</code> in variable/constant assignment. Mixing the low-precedence <code>def</code> and the high-precedence <code>=</code> into a single syntax was the cause of the trouble, according to my opinion.</p>
<p>Thence, we should get rid of <code>def</code>. Once we do so, we need to distinguish endless method definition from variable/constant assignment in a new way. What came to my mind was to use a single character: a sigil.</p>
<p>Especially, using the colon seems to make sense to me for several reasons:</p>
<p>Most importantly, assignment to a symbol is impossible, and it currently raises a syntax error, so it would not conflict with variable/constant assignment syntax.</p>
<p>Within Ruby syntax, symbol is naturally used to represent a method name. For example, in <code>foo(&:bar)</code> constructions, users are used to passing a method name as a symbol. Also, a method definition returns a symbol representing the method name. So, making the endless method definition syntax look superficially like an "assignment to a symbol" would make sense.</p> Ruby master - Feature #19889 (Feedback): Let `Kernel.#require` search for files relative to the c...https://bugs.ruby-lang.org/issues/198892023-09-18T13:10:36Zsawa (Tsuyoshi Sawada)
<p>My understanding is that <code>./</code> and <code>../</code> in the given path argument are interpreted relative to:</p>
<p>(1)</p>
<ul>
<li>The current working directory (for <code>load</code> or <code>require</code>)</li>
<li>The requiring file's path (for <code>require_relative</code>)</li>
</ul>
<p>which shows a division of labor between the methods, and seems reasonable. However, when it comes to other relative paths (e.g., <code>foo/bar.rb</code>), they are interpreted relative to:</p>
<p>(2)</p>
<ul>
<li>Paths in <code>$LOAD_PATH</code> (for <code>require</code>)</li>
<li>Paths in <code>$LOAD_PATH</code> or <strong>the current working directory</strong> (for <code>load</code> or <code>require_relative</code>)</li>
</ul>
<p>For example, given:</p>
<ul>
<li>File <code>some_path/foo/a.rb</code>
</li>
<li>File <code>some_path/b.rb</code> with content <code>require "foo/a"</code>
</li>
<li>Current directory at <code>some_path</code>,</li>
</ul>
<p>running <code>ruby b.rb</code> raises a <code>LoadError</code>, but given:</p>
<ul>
<li>File <code>some_path/foo/a.rb</code>
</li>
<li>File <code>some_path/b.rb</code> with content <code> require_relative "foo/a"</code>
</li>
<li>Current directory at <code>some_path</code>,</li>
</ul>
<p>running <code>ruby b.rb</code> does not raise an error.</p>
<p>The search path in (2) for <code>require</code> is a proper subset of that of <code>load</code> and <code>require_relative</code>. There is no division of labor here; there is only inconvenience for <code>require</code>.</p>
<p>Furthermore, in (1), <code>require</code> (as well as <code>load</code>) is concerned with the current working directory while <code>require_relative</code> is not, but in (2), the relation is reversed: <code>require_relative</code> (as well as <code>load</code>) is concerned with the current working directory while <code>require</code> is not.</p>
<p>This situation is making the specification of <code>require</code> versus <code>require_relative</code> difficult to understand, as well as causing inconvenience.</p>
<p><strong>Proposal</strong>: For non-<code>./</code>-or-<code>../</code> relative paths, I propose to let <code>Kernel.#require</code> search relative to the current working directory if the file is not found relative to the paths in <code>$LOAD_PATH</code>, so that the methods <code>load</code>, <code>require</code>, and <code>require_relative</code> all work the same in this respect.</p> Ruby master - Feature #19832 (Rejected): Method#destructive?, UnboundMethod#destructive?https://bugs.ruby-lang.org/issues/198322023-08-06T04:39:36Zsawa (Tsuyoshi Sawada)
<p>I propose to add <code>destructive?</code> property to <code>Method</code> and <code>UnboundMethod</code> instances, which shall behave like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">String</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:<<</span><span class="p">).</span><span class="nf">destructive?</span> <span class="c1"># => true</span>
<span class="no">String</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(:</span><span class="o">+</span><span class="p">).</span><span class="nf">destructive?</span> <span class="c1"># => false</span>
</code></pre>
<p>One main purpose of using these classes is to inspect and make sure how a certain method behaves. Besides arity and owner, whether a method is destructive or not is one important piece of information, but currently, you cannot achieve that from <code>Method</code> or <code>UnboundMethod</code> instances.</p>
<p>The problem is how to implement this. It is best if this information (whether or not a method is destructive) can be extracted automatically from the method definition.</p>
<p>Unlike owner and arity, it may or may not be straightforward by statically analyzing the code. I think that, if a method definition defined at the ruby level does not call a destructive method anywhere within its own definition, and no dynamic method calls (<code>send</code>, <code>eval</code>, etc.) are made, then we can say that the method is non-destructive. If it does call, then the method is most likely a destructive method (it would not be destructive if the internally-called destructive method is applied to a different object. Or, we could rather call that a destructive method in the sense that it has a destructive side effect).</p>
<p>If doing that turns out to be difficult for some or all cases, then a practical approach for the difficult cases is to label the methods as destructive or not, manually. We can perhaps have methods <code>Module#destructive</code> and <code>Module#non_destructive</code> which take (a) symbol/string argument(s) and return the method name(s) in symbol so that they can be used like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="n">destructive</span> <span class="kp">private</span> <span class="k">def</span> <span class="nf">some_destructive_private_method</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>or</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">baz</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
<span class="n">non_destructive</span> <span class="ss">:foo</span><span class="p">,</span> <span class="ss">:baz</span>
<span class="n">destructive</span> <span class="ss">:bar</span>
<span class="k">end</span>
</code></pre>
<p>or</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="n">non_destructive</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">baz</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
<span class="n">destructive</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>When the method is not (yet) specified whether destructive or not, the return value can be <code>"unknown"</code> (or <code>:unknown</code> or <code>nil</code>) by default.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">String</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:<<</span><span class="p">).</span><span class="nf">destructive?</span> <span class="c1"># => "unknown"</span>
</code></pre> Ruby master - Feature #19734 (Rejected): Let `Dir` methods be available to `File`https://bugs.ruby-lang.org/issues/197342023-06-17T14:53:51Zsawa (Tsuyoshi Sawada)
<p>I propose to let <code>Dir</code> singleton methods be available to <code>File</code> in some way. Motivations are as follows.</p>
<p>When we want to do something with a file (for example <code>File.read</code> or <code>File.write</code>), we quite often want to achieve the home directory. If we are in the mode of thinking in the ream of <code>File</code>, we would likely come up with <code>File.expand_path("~")</code>. However, this is cumbersome, and actually, <code>Dir.home</code> is simpler. But my experience is that switching the mind to <code>Dir</code> when thinking about <code>File</code> require extra cognitive load.</p>
<p>Also, many methods defined in <code>File</code> work for both a file or a directory. When we are doing something with a directory, we have to stop and think whether the method we want to use is defined in <code>File</code> or in <code>Dir</code>. It is possible to do that, but that also requires extra cognitive load.</p>
<p>I thought things would become simpler if we do not need to switch between these two classes in mind, and keep using <code>File</code>. There are a few singleton methods that are defined on both <code>File</code> and <code>Dir</code>:</p>
<pre><code>delete/unlink, empty?, exist?, new/open
</code></pre>
<p>For them, perhaps some modification can be made.</p> Ruby master - Bug #19733 (Feedback): Kernel#Rational does not accept prefix 0https://bugs.ruby-lang.org/issues/197332023-06-15T00:44:52Zsawa (Tsuyoshi Sawada)
<p><code>Integer</code> and <code>Rational</code> literals accept prefix <code>0</code>. There is no difference in this respect.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mb">0b10</span> <span class="c1"># => 2</span>
<span class="mb">0b10</span><span class="n">r</span> <span class="c1"># => (2/1)</span>
</code></pre>
<p>However, when it comes to <code>Kernel#Integer</code> and <code>Kernel#Rational</code>, the former accepts prefix <code>0</code> while the latter does not. This is confusing. And as I do not see any reason they should behave differently, I think it is a bug.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Integer</span><span class="p">(</span><span class="s2">"0b10"</span><span class="p">)</span> <span class="c1"># => 2</span>
<span class="no">Rational</span><span class="p">(</span><span class="s2">"0b10"</span><span class="p">)</span> <span class="c1"># !> ArgumentError</span>
</code></pre> Ruby master - Feature #19600 (Closed): Method `clamp?`https://bugs.ruby-lang.org/issues/196002023-04-14T12:47:47Zsawa (Tsuyoshi Sawada)
<p>Currently, we have pairs of non-predicate and predicate methods like <code>String#match</code> and <code>String#match?</code>. Along this line, I propose the following. They are brain-friendly, and make programmers happier by saving them from terminology hell.</p>
<ol>
<li>Since by <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Allow Comparable#clamp(min, max) to accept nil as a specification (Closed)" href="https://bugs.ruby-lang.org/issues/19588">#19588</a>, <code>Comparable#clamp</code>'s behavior is made the same as <code>Range#cover?</code> for range arguments, alias <code>Range#cover?</code> as <code>Range#clamp?</code>.</li>
<li>Synchronize the specification of <code>Comparable#between?</code> with <code>Comparable#clamp</code>, i.e.,<br>
a. Allow <code>Comparable#between?</code> to take a range argument, and<br>
b. Allow <code>Comparable#between?</code> to take <code>nil</code> as either or both of its arguments, or as either or both ends of its range argument.</li>
<li>Alias <code>Comparable#between?</code> as <code>Comparable#clamped?</code>
</li>
</ol> Ruby master - Feature #19559 (Rejected): Introduce `Symbol#+@` and `Symbol#-@`, and eventually re...https://bugs.ruby-lang.org/issues/195592023-03-30T05:23:38Zsawa (Tsuyoshi Sawada)
<p>I propose to define <code>Symbol#+@</code> and <code>Symbol#-@</code>, so that we can add positive or negative polarity to symbols. A possible implementation can be equivalent to what can be achieved by this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Symbol</span>
<span class="k">def</span> <span class="nf">-@</span><span class="p">;</span> <span class="s2">"-</span><span class="si">#{</span><span class="nb">self</span><span class="si">}</span><span class="s2">"</span><span class="p">.</span><span class="nf">to_sym</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">+@</span><span class="p">;</span> <span class="nb">self</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>The intention behind this is to, eventually, replace boolean positional or keyword arguments with symbols so that, instead of this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"foo"</span><span class="p">.</span><span class="nf">methods</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span>
<span class="nb">gets</span><span class="p">(</span><span class="ss">chomp: </span><span class="kp">true</span><span class="p">)</span>
<span class="no">Integer</span><span class="p">(</span><span class="s2">"2.3"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">false</span><span class="p">)</span>
</code></pre>
<p>we can write like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"foo"</span><span class="p">.</span><span class="nf">methods</span><span class="p">(</span><span class="o">-</span><span class="ss">:inherit</span><span class="p">)</span>
<span class="nb">gets</span><span class="p">(</span><span class="o">+</span><span class="ss">:chomp</span><span class="p">)</span>
<span class="no">Integer</span><span class="p">(</span><span class="s2">"2.3"</span><span class="p">,</span> <span class="o">-</span><span class="ss">:exception</span><span class="p">)</span>
</code></pre> Ruby master - Feature #19069 (Rejected): Default value assignment with `Hash.new` in block formhttps://bugs.ruby-lang.org/issues/190692022-10-18T11:58:14Zsawa (Tsuyoshi Sawada)
<p>This is a spin-out from <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Hash.new with non-value objects should be less confusing (Rejected)" href="https://bugs.ruby-lang.org/issues/19063">#19063</a>, and is a recapture of my comment <a href="https://bugs.ruby-lang.org/issues/19063#note-15" class="external">https://bugs.ruby-lang.org/issues/19063#note-15</a>.</p>
<p>I propose to change the behavior of <code>Hash.new</code> when it takes a block with its parameter signature absent. In such case, the evaluated value of the block should be assigned to the hash with the missing key in question (<code>h3</code> below). When the block does take parameters, then the behavior should remain as is now (<code>h1</code>, <code>h2</code> below).</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="n">h1</span> <span class="o">=</span> <span class="no">Hash</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="o">|</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="o">|</span> <span class="n">h</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"foo"</span><span class="p">}</span>
<span class="n">h2</span> <span class="o">=</span> <span class="no">Hash</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="o">|</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="o">|</span> <span class="s2">"foo"</span><span class="p">}</span>
<span class="n">h3</span> <span class="o">=</span> <span class="no">Hash</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="s2">"foo"</span><span class="p">}</span>
<span class="n">h1</span><span class="p">[</span><span class="ss">:a</span><span class="p">]</span> <span class="c1"># => "foo"</span>
<span class="n">h2</span><span class="p">[</span><span class="ss">:a</span><span class="p">]</span> <span class="c1"># => "foo"</span>
<span class="n">h3</span><span class="p">[</span><span class="ss">:a</span><span class="p">]</span> <span class="c1"># => "foo"</span>
<span class="n">h1</span> <span class="c1"># => {:a=>"foo"}</span>
<span class="n">h2</span> <span class="c1"># => {}</span>
<span class="n">h3</span> <span class="c1"># => {:a=>"foo"}</span>
</code></pre>
<p>This will solve a few problems. First, as discussed in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Hash.new with non-value objects should be less confusing (Rejected)" href="https://bugs.ruby-lang.org/issues/19063">#19063</a>, many users make the mistake of writing <code>Hash.new([])</code> when they actually mean <code>Hash.new{|h, k| h[k] = []}</code>, and I suspect this is partially due to the fact that the block <code>{|h, k| h[k] = []}</code> is too long, and the users are tempted to avoid writing so. With the proposed feature introduced, the users will be encouraged to naturally write the correct form <code>Hash.new{[]}</code>.</p>
<p>Second, some of the more advanced users than those mentioned above still make the mistake of writing <code>Hash.new{foo}</code> when they actually mean <code>Hash.new{|h, k| h[k] = foo}</code>, and the current proposal is to let them actually be equivalent.</p>
<p>Third, this will resemble a similar construct <code>Array.new(5){[]}</code> and they will make a good parallel.</p>
<p>Indeed, there are situations where the intended behavior is to just run a routine without assigning a new key-value pair to the hash. Examples of current code may be as follows:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="n">h4</span> <span class="o">=</span> <span class="no">Hash</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="n">some_routine_to_take_care_of_the_missing_key_situation</span><span class="p">}</span>
<span class="n">h5</span> <span class="o">=</span> <span class="no">Hash</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="k">raise</span> <span class="no">WrongKeyBlahBlahError</span><span class="p">}</span>
</code></pre>
<p>Such blocks would need to be prepended by a parameter signature <code>|h, k|</code> in order to avoid unwanted results. I do not think such transition would be a huge pain.</p> Ruby master - Bug #18765 (Closed): Wrong description introduced by https://github.com/ruby/ruby/p...https://bugs.ruby-lang.org/issues/187652022-05-09T07:44:14Zsawa (Tsuyoshi Sawada)
<p>Commit <a href="https://github.com/ruby/ruby/pull/4938/files" class="external">https://github.com/ruby/ruby/pull/4938/files</a> introduced problems and made the description wrong.</p>
<ol>
<li>
<p>For methods <code>slice_after</code> and <code>slice_when</code>, it introduces expressions like "partition elements into arrays ('slices')", and for method <code>chunk_while</code>, "partition elements into arrays ('chunks')". It suggests to call the resulting elements using different words depending on the name of the method. But that does not make sense. They are all simply arrays, and there is no need to distinguish a "slice array" from a "chunk array". (They can all be called an "array", "slice", or "chunk", or whatever.)</p>
<p>Perhaps, it is attempting to explain where the method names came from, under the assumption that the words "slice" and "chunk" in these method names are nouns. If so, that is wrong. The succeeding parts "when (block)" and "while (block)" are (to correspond to English) adverbial clauses, not adjectival (relative) clauses; hence, these "slice" and "chunk" must be interpreted as verbs, not nouns. In fact, "a slice when y is not a successor of x" or "a chunk while y is a successor of x" does not make sense, whereas "slice it when y is not a successor of x" and "chunk them while y is a successor of x" do make sense.</p>
<p>The difference between the "slice" and "chunk" methods lies in the process, not the return value. If you want to use these words, it can be something like "slice the receiver into arrays when the block returns a truthy value" and "chunk the elements together while the block returns a truthy value".</p>
</li>
<li>
<p>In the description of <code>slice_when</code> and <code>chunk_while</code>, it says "it calls the block with each element and its successor", but that is not true. If you are going to phrase it that way, then it only calls each element except for the last one.</p>
</li>
<li>
<p>In the description of <code>slice_when</code>, it says "begins a new slice if and only if the block returns a truthy value", but that is not true. Regardless of the value of the block, the first element always begins a new "slice".</p>
</li>
<li>
<p>Most crucially, in the description of <code>chunk_while</code>, the expression "begins a new chunk if and only if the block returns a truthy value" is entirely wrong.</p>
</li>
</ol> Ruby master - Feature #18749 (Rejected): Strangeness of endless inclusive rangeshttps://bugs.ruby-lang.org/issues/187492022-04-22T05:55:59Zsawa (Tsuyoshi Sawada)
<p>I came to think about this while looking at the pull request linked in <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Range#cover? returns true for beginless range of different type (Closed)" href="https://bugs.ruby-lang.org/issues/18748">#18748</a>.</p>
<p>Currently, an endless inclusive range covers the corresponding endless exclusive range, but not vice versa:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="s2">"a"</span><span class="o">..</span><span class="kp">nil</span><span class="p">).</span><span class="nf">cover?</span><span class="p">(</span><span class="s2">"a"</span><span class="o">...</span><span class="kp">nil</span><span class="p">)</span> <span class="c1">#=> true</span>
<span class="p">(</span><span class="s2">"a"</span><span class="o">...</span><span class="kp">nil</span><span class="p">).</span><span class="nf">cover?</span><span class="p">(</span><span class="s2">"a"</span><span class="o">..</span><span class="kp">nil</span><span class="p">)</span> <span class="c1">#=> false</span>
<span class="p">(</span><span class="kp">nil</span><span class="o">..</span><span class="kp">nil</span><span class="p">).</span><span class="nf">cover?</span><span class="p">(</span><span class="kp">nil</span><span class="o">...</span><span class="kp">nil</span><span class="p">)</span> <span class="c1">#=> true</span>
<span class="p">(</span><span class="kp">nil</span><span class="o">...</span><span class="kp">nil</span><span class="p">).</span><span class="nf">cover?</span><span class="p">(</span><span class="kp">nil</span><span class="o">..</span><span class="kp">nil</span><span class="p">)</span> <span class="c1">#=> false</span>
</code></pre>
<p>This looks strange to me. There is not a single element covered by an endless inclusive range that is not covered by the corresponding endless exclusive range. This should mean that there is no difference in coverage between an endless inclusive range and the corresponding endless exclusive range.</p>
<p>However, actually, an interval in mathematics (which I think is the counterpart to Ruby's range) ending in ∞ (which I think is the counterpart to an endless range) is always an open interval (which I think is the counterpart to an exclusive range), and never a closed interval (which I think is the counterpart to an inclusive range).</p>
<p>[a, ∞) is correct.<br>
[a, ∞] is wrong.</p>
<p>From analogy, ideally, endless inclusive ranges should be prohibited in the first place. But that would cause new issues: There is no inclusive-exclusive distinction on the begin side of a range, and that is actually always assumed to be inclusive. Since we have beginless (inclusive) ranges, prohibiting endless inclusive ranges would cause asymmetry.</p>
<p>So what I can think of are the following possibilities (ordered from conservative to radical):</p>
<p>A. Endless inclusive ranges are allowed as is. An endless inclusive range and the corresponding endless exclusive range cover each other.<br>
B. Endless inclusive ranges are disallowed. Beginless (inclusive) ranges are allowed as is.<br>
C. New syntax is introduced in order to describe ranges that are exclusive on the begin side. Inclusive-exclusive distinction can be described on both begin and end sides independently. Endless inclusive ranges and beginless inclusive ranges are disallowed.</p> Ruby master - Feature #18690 (Open): Allow `Kernel#then` to take argumentshttps://bugs.ruby-lang.org/issues/186902022-04-12T09:20:21Zsawa (Tsuyoshi Sawada)
<p><code>Kernel#then</code> passes the receiver to the block as its first positional block parameter.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mf">1.5</span><span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="no">Math</span><span class="p">.</span><span class="nf">atan</span><span class="p">(</span><span class="n">x</span><span class="p">)}</span>
</code></pre>
<p>I would like to propose to let <code>then</code> take arguments, which would be passed to the block as the other block parameters.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">3</span><span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="mi">4</span><span class="p">){</span><span class="o">|</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="o">|</span> <span class="no">Math</span><span class="p">.</span><span class="nf">hypot</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)}</span>
</code></pre>
<p>There are two uses. First, to separate bulky or repeated parameters from the routine. Instead of writing:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">honyarara</span><span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span>
<span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">bar</span><span class="p">(</span><span class="n">fugafugafuga</span><span class="p">)</span>
<span class="n">baz</span><span class="p">(</span><span class="n">hogehogehoge</span><span class="p">)</span>
<span class="n">qux</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">fugafugafuga</span><span class="p">,</span> <span class="n">hogehogehoge</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
<p>we can then write:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">honyarara</span><span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="n">fugafugafuga</span><span class="p">,</span> <span class="n">hogehogehoge</span><span class="p">){</span><span class="o">|</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="o">|</span>
<span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">bar</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="n">baz</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">qux</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
<span class="p">}</span>
</code></pre>
<p>Second, to use a proc with multiple parameters when, for some reason, you do not want to define a method to do it:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">p</span> <span class="o">=</span> <span class="o">-></span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">){</span>
<span class="n">foo</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">bar</span><span class="p">(</span><span class="n">y</span><span class="p">)</span>
<span class="n">baz</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="n">qux</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span>
<span class="p">}</span>
<span class="n">honyarara</span><span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="n">fugafugafuga</span><span class="p">,</span> <span class="n">hogehogehoge</span><span class="p">,</span> <span class="o">&</span><span class="nb">p</span><span class="p">)</span>
</code></pre> Ruby master - Feature #18366 (Rejected): Enumerator#return_evalhttps://bugs.ruby-lang.org/issues/183662021-11-29T04:04:05Zsawa (Tsuyoshi Sawada)
<p>Some <code>Enumerable</code> methods return one or more of the receiver's elements according to the return value of a block it takes. Often, we want such evaluated value rather than the original element.</p>
<p>For example, suppose we want to know the character width sufficient to fit all the strings in an array:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Hello"</span><span class="p">,</span> <span class="s2">"my"</span><span class="p">,</span> <span class="s2">"name"</span><span class="p">,</span> <span class="s2">"is"</span><span class="p">,</span> <span class="s2">"Ruby"</span><span class="p">]</span>
</code></pre>
<p>We either have to repeat the evaluation of the block:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">max_by</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">).</span><span class="nf">length</span> <span class="c1"># => 5</span>
</code></pre>
<p>or create a temporal array:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">).</span><span class="nf">max</span> <span class="c1"># => 5</span>
</code></pre>
<p>both of which seem not to be optimal.</p>
<p>I propose to have a method <code>Enumerator#return_eval</code> that returns the evaluated value(s) of the block:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">max_by</span><span class="p">.</span><span class="nf">return_eval</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">)</span> <span class="c1"># => 5</span>
<span class="n">a</span><span class="p">.</span><span class="nf">min_by</span><span class="p">.</span><span class="nf">return_eval</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">)</span> <span class="c1"># => 2</span>
<span class="n">a</span><span class="p">.</span><span class="nf">minmax_by</span><span class="p">.</span><span class="nf">return_eval</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">)</span> <span class="c1"># => [2, 5]</span>
<span class="p">[</span><span class="s2">"Ava Davidson"</span><span class="p">,</span> <span class="s2">"Benjamin Anderson"</span><span class="p">,</span> <span class="s2">"Charlie Baker"</span><span class="p">]</span>
<span class="p">.</span><span class="nf">sort_by</span><span class="p">.</span><span class="nf">return_eval</span><span class="p">{</span><span class="n">_1</span><span class="p">.</span><span class="nf">split</span><span class="p">.</span><span class="nf">reverse</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)}</span> <span class="c1"># => ["Anderson, Benjamin", "Baker, Charlie", "Davidson, Ava"]</span>
</code></pre> Ruby master - Feature #18331 (Open): Kernel.#Timehttps://bugs.ruby-lang.org/issues/183312021-11-13T12:27:30Zsawa (Tsuyoshi Sawada)
<p>I remember that, once, Matz suggested a new literal notation for date/time, but he later withdrew it. It seems like introducing new syntax at this point is less realistic. But I believe that many people have wanted a simple way to create a date/time object.</p>
<p>I propose <code>Kernel.Time</code> or <code>Kernel#Time</code>, in much of the same way as <code>Kernel.#Integer</code>, <code>Kernel.#Float</code>, <code>Kernel.#Complex</code> and others. It should take a string as the first required argument and some optional keyword arguments.</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="no">Time</span><span class="p">(</span><span class="s2">"2021-11-13T21:21:18.027294 +0900"</span><span class="p">)</span> <span class="c1"># => 2021-11-13 21:21:18.027294 +0900</span>
<span class="no">Time</span><span class="p">(</span><span class="s2">"2021-11-13 21:21:18.027294 +0900"</span><span class="p">)</span> <span class="c1"># => 2021-11-13 21:21:18.027294 +0900</span>
<span class="no">Time</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => nil</span>
</code></pre>
<p>I leave out the specifics. There should be room for debate.</p>
<p>I wish the features nobu implemented in <a href="https://bugs.ruby-lang.org/issues/18033" class="external">https://bugs.ruby-lang.org/issues/18033</a> for <code>Time.new</code> can be carried over to <code>Kernel.#Time</code>.</p> Ruby master - Feature #17773 (Open): Alias `Numeric#zero?` and `Float#zero?` as `Numeric#empty?` ...https://bugs.ruby-lang.org/issues/177732021-04-02T03:49:45Zsawa (Tsuyoshi Sawada)
<p>When dealing with user input fields as in web applications, there are typical values that we want to consider as the default and/or absence of user input. For string/text inputs, list items, and attributes, we have <code>String#empty?</code>, <code>Array#empty?</code>, and <code>Hash#empty?</code> respectively, which seem to correspond to those cases. As for numerics, there are <code>Numeric#zero?</code> and <code>Float#zero?</code>.</p>
<p>However, there is no single term that covers all these cases. In a routine to check through the fields whether there is user input, we have to selectively use <code>empty?</code> or <code>zero?</code> depending on the type of the input field.</p>
<p>Many programming languages other than Ruby typically consider these values as falsy with respect to logical calculation. Ruby handles only <code>nil</code> and <code>false</code> as falsy, and that has clear advantages in many aspects, but with the cost of losing a simple way to handle these default values.</p>
<p>I propose to alias <code>Numeric#zero?</code> as <code>Numeric#empty?</code> and <code>Float#zero?</code> as <code>Float#empty?</code> so that we can simply use <code>empty?</code>. At first, calling zero as empty might sound strange, but at least for non-negative integers, set theoretic definitions usually define zero as the empty set, so it is not that strange after all.</p>
<p>Ruby on Rails' <code>blank?</code> is conceptually similar to this, but <code>0.blank?</code> returns <code>false</code>, so it is a different concept.</p> Ruby master - Feature #17608 (Rejected): Compact and sum in one stephttps://bugs.ruby-lang.org/issues/176082021-02-04T06:18:38Zsawa (Tsuyoshi Sawada)
<p>Many use cases of <code>Array#sum</code> are preceded with the <code>compact</code> method or are followed by a block to ensure the value is addable.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="kp">nil</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">sum</span> <span class="c1"># !> TypeError</span>
<span class="n">a</span><span class="p">.</span><span class="nf">compact</span><span class="p">.</span><span class="nf">sum</span> <span class="c1"># => 6</span>
<span class="n">a</span><span class="p">.</span><span class="nf">sum</span><span class="p">{</span><span class="n">_1</span> <span class="o">||</span> <span class="mi">0</span><span class="p">}</span> <span class="c1"># => 6</span>
</code></pre>
<p>I propose there should be a way to do that in one step. I request either of the following:</p>
<p>A. Change the current behaviour to skip <code>nil</code>s.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">sum</span> <span class="c1"># => 6</span>
</code></pre>
<p>B. <code>Array#filter_sum</code> method</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">filter_sum</span> <span class="c1"># => 6</span>
</code></pre>
<p>C. An option for <code>Array#sum</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">sum</span><span class="p">(</span><span class="ss">compact: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => 6</span>
</code></pre> Ruby master - Feature #17316 (Open): On memoizationhttps://bugs.ruby-lang.org/issues/173162020-11-11T10:22:03Zsawa (Tsuyoshi Sawada)
<p>I have seen so many attempts to memoize a value in the form:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="vi">@foo</span> <span class="o">||=</span> <span class="n">some_heavy_calculation</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
</code></pre>
<p>improperly, i.e., even when the value can potentially be falsy. This practice is wide spread, and since in most cases memoization is about efficiency and it would not be critical if it does not work correctly, people do not seem to care so much about correcting the wrong usage.</p>
<p>In such case, the correct form would be:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">unless</span> <span class="n">instance_variable_defined?</span><span class="p">(</span><span class="ss">:@foo</span><span class="p">)</span>
<span class="vi">@foo</span> <span class="o">=</span> <span class="n">some_heavy_calculation</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
<p>but this looks too long, and perhaps that is keeping people away from using it.</p>
<p>What about allowing <code>Kernel#instance_variable_set</code> to take a block instead of the second argument, in which case the assignment should be done only when the instance variable is not defined?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">instance_variable_set</span><span class="p">(</span><span class="ss">:@foo</span><span class="p">){</span><span class="n">some_heavy_calculation</span><span class="p">(</span><span class="o">...</span><span class="p">)}</span>
</code></pre>
<p>Or, if that does not look right or seems to depart from the original usage of <code>instance_variable_set</code>, then what about having a new method?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">memoize</span><span class="p">(</span><span class="ss">:foo</span><span class="p">){</span><span class="n">some_heavy_calculation</span><span class="p">(</span><span class="o">...</span><span class="p">)}</span>
</code></pre> Ruby master - Feature #17290 (Closed): Syntax sugar for boolean keyword argumenthttps://bugs.ruby-lang.org/issues/172902020-10-29T02:54:40Zsawa (Tsuyoshi Sawada)
<p>We frequently use keyword arguments just to pass <code>true</code> value out of the truthy/falsy options given. And in many such cases, the falsy option is set as the default, and only the truthy value is ever passed explicitly. I propose to have a syntax sugar to omit the value of a keyword argument. When omitted, it should be interpreted with value <code>true</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">gets</span><span class="p">(</span><span class="nb">chomp</span><span class="p">:)</span>
<span class="no">CSV</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="s2">" foo var "</span><span class="p">,</span> <span class="n">strip</span><span class="p">:)</span>
</code></pre>
<p>should be equivalent to</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">gets</span><span class="p">(</span><span class="ss">chomp: </span><span class="kp">true</span><span class="p">)</span>
<span class="no">CSV</span><span class="p">.</span><span class="nf">parse</span><span class="p">(</span><span class="s2">" foo var "</span><span class="p">,</span> <span class="ss">strip: </span><span class="kp">true</span><span class="p">)</span>
</code></pre>
<p>Additionally, we may also extend this to pragmas.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># frozen_string_literal:</span>
</code></pre>
<p>to be equivalent to:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># frozen_string_literal: true</span>
</code></pre> Ruby master - Feature #17177 (Rejected): Include the current file name and the line number in the...https://bugs.ruby-lang.org/issues/171772020-09-18T12:17:57Zsawa (Tsuyoshi Sawada)
<p>In many debugging situations, we want to inspect some objects in more than one source location throughout the code. To be identified where it is called from, it is very common that the method <code>p</code> is used together with a <code>puts</code> method that outputs some marker that distinguishes the location:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">...</span> <span class="c1"># some buggy area or conditional branch</span>
<span class="nb">puts</span> <span class="s2">"== A =="</span>
<span class="nb">p</span> <span class="n">foo</span>
<span class="o">...</span> <span class="c1"># another buggy area or conditional branch</span>
<span class="nb">puts</span> <span class="s2">"== B =="</span>
<span class="nb">p</span> <span class="n">foo</span>
<span class="o">...</span> <span class="c1"># another buggy area or conditional branch</span>
<span class="nb">puts</span> <span class="s2">"bar is:"</span>
<span class="nb">p</span> <span class="n">bar</span>
<span class="o">...</span>
</code></pre>
<p>But this is cumbersome.</p>
<p>Also, after debugging, when we want to remove the <code>p</code> calls from the code, it is sometimes not so trivial to identify where those method calls are written.</p>
<p>I propose that the method <code>p</code> should display not only the objects passed as arguments, but also its source location. Supposing we have a file <code>bar.rb</code> like this,</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="n">foo</span> <span class="o">=</span> <span class="s2">"a"</span>
<span class="nb">p</span> <span class="n">foo</span>
</code></pre>
<p>running <code>ruby bar.rb</code> should perhaps have an output like this:</p>
<pre><code>At bar.rb:2
"a"
</code></pre>
<p>Then, in a debugging situation like the above, we would only need to write:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">...</span> <span class="c1"># some buggy area or conditional branch</span>
<span class="nb">p</span> <span class="n">foo</span>
<span class="o">...</span> <span class="c1"># another buggy area or conditional branch</span>
<span class="nb">p</span> <span class="n">foo</span>
<span class="o">...</span> <span class="c1"># another buggy area or conditional branch</span>
<span class="nb">p</span> <span class="n">bar</span>
<span class="o">...</span>
</code></pre> Ruby master - Bug #17167 (Closed): Nested numbered parameters are not allowedhttps://bugs.ruby-lang.org/issues/171672020-09-12T15:20:28Zsawa (Tsuyoshi Sawada)
<p>Numbered parameter is allowed in an ordinary block:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]].</span><span class="nf">each</span><span class="p">{</span><span class="nb">p</span> <span class="n">_1</span><span class="p">}</span>
<span class="c1"># >> [1, 2]</span>
<span class="c1"># >> [3, 4]</span>
</code></pre>
<p>as well as in a nested block:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]].</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="n">a</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="nb">p</span> <span class="n">_1</span><span class="p">}}</span>
<span class="c1"># >> 1</span>
<span class="c1"># >> 2</span>
<span class="c1"># >> 3</span>
<span class="c1"># >> 4</span>
</code></pre>
<p>but not in both at the same time:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]].</span><span class="nf">each</span><span class="p">{</span><span class="n">_1</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="nb">p</span> <span class="n">_1</span><span class="p">}}</span>
<span class="c1"># >> SyntaxError ((irb):2: numbered parameter is already used in) outer block here</span>
<span class="c1"># >> [[1, 2], [3, 4]].each{_1.each{p _1}}</span>
<span class="o">^~</span>
</code></pre>
<p>I feel that this should be a bug.</p>
<p>Note that an error is not raised when an ordinary block parameter with the same name is used in the outer and the inner blocks:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]].</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span> <span class="n">v</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">v</span><span class="o">|</span> <span class="nb">p</span> <span class="n">v</span><span class="p">}}</span>
<span class="c1"># >> 1</span>
<span class="c1"># >> 2</span>
<span class="c1"># >> 3</span>
<span class="c1"># >> 4</span>
</code></pre>
<p>If this is not a bug, the specification of numbered parameters is too complex. How am I supposed to use numbered parameters in such use case as above?</p> Ruby master - Feature #17165 (Open): Add `filter` and `flatten` keywords to `Enumerable#map`https://bugs.ruby-lang.org/issues/171652020-09-12T14:46:54Zsawa (Tsuyoshi Sawada)
<p>I had a use case to do <code>map</code> on an enumerable, with 1-level flattening, while skipping <code>nil</code> values.</p>
<p>There are convenient <code>Enumerable#flat_map</code> and <code>Enumerable#filter_map</code> methods, but the problem is that they cannot be used at the same time. I had to chose to do either of the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">array</span>
<span class="p">.</span><span class="nf">filter_map</span> <span class="k">do</span> <span class="o">|</span><span class="n">foo</span><span class="o">|</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">baz</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="k">next</span> <span class="k">unless</span> <span class="n">bar</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">...</span><span class="p">}</span>
<span class="k">end</span>
<span class="p">.</span><span class="nf">flatten</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">array</span>
<span class="p">.</span><span class="nf">flat_map</span> <span class="k">do</span> <span class="o">|</span><span class="n">foo</span><span class="o">|</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">baz</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="k">next</span> <span class="k">unless</span> <span class="n">bar</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">...</span><span class="p">}</span>
<span class="k">end</span>
<span class="p">.</span><span class="nf">compact</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">array</span>
<span class="p">.</span><span class="nf">flat_map</span> <span class="k">do</span> <span class="o">|</span><span class="n">foo</span><span class="o">|</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">baz</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="k">next</span> <span class="p">[]</span> <span class="k">unless</span> <span class="n">bar</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">...</span><span class="p">}</span>
<span class="k">end</span>
</code></pre>
<p>The last one of the above may not look so bad, but it requires an extra consideration, and is a bit hacky. When you are in a hurry, it just might not come to your mind.</p>
<p>This led me to realize that <code>flat_map</code> and <code>filter_map</code> should not be independent operations, but are rather some different modes of the operation <code>map</code>. There is no reason for the modes to be mutually exclusive of one another, and a use case that I mentioned above may arise.</p>
<p>I propose to add <code>filter</code> and <code>flatten</code> as optional keyword arguments to <code>Enumerable#map</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">array</span>
<span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="ss">filter: </span><span class="kp">true</span><span class="p">,</span> <span class="ss">flatten: </span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">foo</span><span class="o">|</span>
<span class="n">bar</span> <span class="o">=</span> <span class="n">baz</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="k">next</span> <span class="k">unless</span> <span class="n">bar</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">...</span><span class="p">}</span>
<span class="k">end</span>
</code></pre>
<p>In fact, even when the two parameters are not used together, I believe it would be easier to the brain and I would feel much more comfortable to pass <code>filter: true</code> or <code>flatten: 1</code> to <code>map</code> when necessary rather than having to deicide whether to use <code>map</code> or <code>flat_map</code> or use <code>map</code> or <code>filter_map</code>.</p>
<p>Furthermore, this would make it possible to do flattening of an arbitrary depth (as specified by the parameter) during map.</p> Ruby master - Feature #17163 (Open): Rename `begin`https://bugs.ruby-lang.org/issues/171632020-09-09T03:04:22Zsawa (Tsuyoshi Sawada)
<p><code>Range#begin</code> is a getter method; it returns a value, and does not have a side effect, or does any calculation. Nevertheless, "begin" is a verb, so there is a mismatch. I would rather expect a noun.</p>
<p>It has a counterpart <code>Range#end</code>, and "end" is a noun as well as a verb, so that is not strange.</p>
<p>I propose to alias <code>Range#begin</code> to a noun or a nominal. "beginning" will work, but it may be too long, so what about "start", which works as a noun (as well as a verb)?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Range</span><span class="c1">#start</span>
</code></pre> Ruby master - Feature #17097 (Open): `map_min`, `map_max`https://bugs.ruby-lang.org/issues/170972020-07-31T12:33:39Zsawa (Tsuyoshi Sawada)
<p><code>min</code>, <code>min_by</code>, <code>max</code>, <code>max_by</code> return the element that leads to the minimum or the maximum value, but I think it is as, or even more, frequent that we are interested in the minimum or the maximum value itself rather than the element. For example, to get the length of the longest string in an array, we do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="sx">%w[aa b cccc dd]</span><span class="p">.</span><span class="nf">max_by</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">).</span><span class="nf">length</span> <span class="c1"># => 4</span>
<span class="sx">%w[aa b cccc dd]</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">).</span><span class="nf">max</span> <span class="c1"># => 4</span>
</code></pre>
<p>I propose to have methods that return the minimum or the maximum value. Temporarily calling them <code>map_min</code>, <code>map_max</code>, they should work like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="sx">%w[aa b cccc dd]</span><span class="p">.</span><span class="nf">map_max</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">)</span> <span class="c1"># => 4</span>
</code></pre>
<p><code>map_min</code>, <code>map_max</code> are implementation-centered names, so perhaps better names should replace them, just like <code>yield_self</code> was replaced by <code>then</code>.</p> Ruby master - Feature #17006 (Open): Let `Kernel#Hash` take a block to provide the default valuehttps://bugs.ruby-lang.org/issues/170062020-07-03T08:09:01Zsawa (Tsuyoshi Sawada)
<p>Sometimes, we need to create a hash that has explicit key-value pairs as well as a default value, but there has not been a way to do that at once. The most naive way is to do like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">}</span>
<span class="n">h</span><span class="p">.</span><span class="nf">default_proc</span> <span class="o">=</span> <span class="o">-></span><span class="p">(</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="p">){</span><span class="k">raise</span> <span class="s2">"Unknown key </span><span class="si">#{</span><span class="n">k</span><span class="si">}</span><span class="s2">"</span><span class="p">}</span>
<span class="n">h</span> <span class="c1"># => ...</span>
</code></pre>
<p>A more sophisticated way is this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Hash</span><span class="p">.</span><span class="nf">new</span><span class="p">{</span><span class="o">|</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="o">|</span> <span class="k">raise</span> <span class="s2">"Unknown key </span><span class="si">#{</span><span class="n">k</span><span class="si">}</span><span class="s2">"</span><span class="p">}.</span><span class="nf">merge</span><span class="p">({</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">})</span>
</code></pre>
<p>But that is still not short enough, and it also looks backwards, i.e., we usually want to specify the explicit key-value pairs before the default value.</p>
<p>My proposal is to allow <code>Kernel#Hash</code> to take a block that provides the default value in the same way as the block of <code>Hash.new</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Hash</span><span class="p">({</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">}){</span><span class="o">|</span><span class="n">h</span><span class="p">,</span> <span class="n">k</span><span class="o">|</span> <span class="k">raise</span> <span class="s2">"Unknown key </span><span class="si">#{</span><span class="n">k</span><span class="si">}</span><span class="s2">"</span><span class="p">}</span>
</code></pre> Ruby master - Bug #16842 (Closed): `inspect` prints the UTF-8 character U+0085 (NEXT LINE) verbat...https://bugs.ruby-lang.org/issues/168422020-05-09T14:35:11Zsawa (Tsuyoshi Sawada)
<p>The UTF-8 character U+0085 (NEXT LINE) is not printable, but <code>inspect</code> prints the character verbatim (within double quotation):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mh">0x85</span><span class="p">.</span><span class="nf">chr</span><span class="p">(</span><span class="no">Encoding</span><span class="o">::</span><span class="no">UTF_8</span><span class="p">).</span><span class="nf">match?</span><span class="p">(</span><span class="sr">/\p{print}/</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="mh">0x85</span><span class="p">.</span><span class="nf">chr</span><span class="p">(</span><span class="no">Encoding</span><span class="o">::</span><span class="no">UTF_8</span><span class="p">).</span><span class="nf">inspect</span>
<span class="c1">#=> "\"</span>
<span class="p">\</span><span class="s2">""</span>
</code></pre>
<p>My understanding is that non-printable characters are not printed verbatim with <code>inspect</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">.</span><span class="nf">match?</span><span class="p">(</span><span class="sr">/\p{print}/</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1">#=> "\"\\n\""</span>
</code></pre>
<p>while printable characters are:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"a"</span><span class="p">.</span><span class="nf">match?</span><span class="p">(</span><span class="sr">/\p{print}/</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="s2">"a"</span><span class="p">.</span><span class="nf">inspect</span> <span class="c1"># => "\"a\""</span>
</code></pre>
<p>I ran the following script, and found that U+0085 is the only character within the range U+0000 to U+FFFF that behaves like this.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">verbatim?</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
<span class="o">!</span><span class="n">char</span><span class="p">.</span><span class="nf">inspect</span><span class="p">.</span><span class="nf">start_with?</span><span class="p">(</span><span class="sr">%r{</span><span class="se">\"\\</span><span class="sr">[a-z]}</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">printable?</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
<span class="n">char</span><span class="p">.</span><span class="nf">match?</span><span class="p">(</span><span class="sr">/\p{print}/</span><span class="p">)</span>
<span class="k">end</span>
<span class="p">(</span><span class="mh">0x0000</span><span class="o">..</span><span class="mh">0xffff</span><span class="p">).</span><span class="nf">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="k">begin</span>
<span class="n">char</span> <span class="o">=</span> <span class="n">i</span><span class="p">.</span><span class="nf">chr</span><span class="p">(</span><span class="no">Encoding</span><span class="o">::</span><span class="no">UTF_8</span><span class="p">)</span>
<span class="k">rescue</span> <span class="no">RangeError</span>
<span class="k">next</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s1">'%#x'</span> <span class="o">%</span> <span class="n">i</span> <span class="k">unless</span> <span class="n">verbatim?</span><span class="p">(</span><span class="n">char</span><span class="p">)</span> <span class="o">==</span> <span class="n">printable?</span><span class="p">(</span><span class="n">char</span><span class="p">)</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #16818 (Open): Rename `Range#%` to `Range#/`https://bugs.ruby-lang.org/issues/168182020-04-26T02:15:08Zsawa (Tsuyoshi Sawada)
<p><code>Range#%</code> was introduced as an alias of <code>Range#step</code> by 14697, but it is counter-intuitive and confusing.</p>
<p>Iteration in the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">((</span><span class="mi">5</span><span class="o">..</span><span class="mi">14</span><span class="p">)</span> <span class="o">%</span> <span class="mi">3</span><span class="p">).</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">p</span> <span class="n">i</span><span class="p">}</span>
<span class="c1">#>> 5</span>
<span class="c1">#>> 8</span>
<span class="c1">#>> 11</span>
<span class="c1">#>> 14</span>
</code></pre>
<p>is not based on <code>x % y</code> in any sense. In fact, actually applying <code>% 3</code> to the selected elements returns a unique value <code>2</code>, and it is not obvious how this is related to the iteration.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">14</span><span class="p">].</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span> <span class="o">%</span> <span class="mi">3</span><span class="p">}</span>
<span class="c1"># => [2, 2, 2, 2]</span>
</code></pre>
<p>Rather, the concept seems to be based on <code>/</code>. Applying <code>/ 3</code> to the relevant elements returns a sequence <code>1, 2, 3, 4</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">14</span><span class="p">].</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span> <span class="o">/</span> <span class="mi">3</span><span class="p">}</span>
<span class="c1"># => [1, 2, 3, 4]</span>
</code></pre>
<p>Hence, <code>(5..14).step(3)</code> can be interpreted like this: Iterate over the <a href="https://en.wikipedia.org/wiki/Equivalence_class" class="external">equivalence class</a> (quotient set) of range <code>5..14</code> yielded by <code>/ 3</code>.</p>
<p>Notice that the number of elements in <code>[5, 8, 11, 14]</code> is 4, which is <code>(14 - 5 + 1) / 3.0).ceil</code>, but is not related to <code>%</code>.</p>
<p>So I propose that the alias of <code>Range#step</code> should be <code>Range#/</code>, and <code>Range#%</code> should be deprecated as soon as possible before its use accumulates:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">((</span><span class="mi">5</span><span class="o">..</span><span class="mi">14</span><span class="p">)</span> <span class="o">/</span> <span class="mi">3</span><span class="p">).</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">p</span> <span class="n">i</span><span class="p">}</span>
<span class="c1">#>> 5</span>
<span class="c1">#>> 8</span>
<span class="c1">#>> 11</span>
<span class="c1">#>> 14</span>
</code></pre>
<hr>
<p>P.S.</p>
<p>And if <code>Range#%</code> were to be introduced at all, I would rather expect it to behave like the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">((</span><span class="mi">5</span><span class="o">..</span><span class="mi">14</span><span class="p">)</span> <span class="o">%</span> <span class="mi">3</span><span class="p">).</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">p</span> <span class="n">i</span><span class="p">}</span>
<span class="c1">#>> 5</span>
<span class="c1">#>> 6</span>
<span class="c1">#>> 7</span>
</code></pre>
<p>which is why I claimed above that the current <code>Range#%</code> is confusing.</p> Ruby master - Feature #16703 (Open): Namespace parameter for `Module#name`https://bugs.ruby-lang.org/issues/167032020-03-23T10:57:03Zsawa (Tsuyoshi Sawada)
<p>I often see code that intends to remove a portion of the namespace from a module/class name like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span><span class="p">;</span> <span class="k">class</span> <span class="nc">B</span> <span class="k">class</span> <span class="nc">C</span><span class="p">;</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">.</span><span class="nf">delete_prefix</span><span class="p">(</span><span class="s2">"A::"</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">.</span><span class="nf">delete_prefix</span><span class="p">(</span><span class="s2">"A::B::"</span><span class="p">)</span> <span class="c1"># => "C"</span>
</code></pre>
<p>I think a large portion of the use cases of the method <code>String#delete_prefix</code> belongs to such use cases.</p>
<p>I propose to let <code>Module#name</code> take an optional parameter that expresses the name space. The parameter should be either a module, string, or a symbol.</p>
<p>I am not sure whether a positional argument or a keyword argument is better.</p>
<p>Positional argument:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="s2">"A"</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">:A</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="no">A</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="s2">"A::B"</span><span class="p">)</span> <span class="c1"># => "C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">:"A::B"</span><span class="p">)</span> <span class="c1"># => "C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">)</span> <span class="c1"># => "C"</span>
</code></pre>
<p>Keyword argument:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">namespace: </span><span class="s2">"A"</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">namespace: :A</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">namespace: </span><span class="no">A</span><span class="p">)</span> <span class="c1"># => "B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">namespace: </span><span class="s2">"A::B"</span><span class="p">)</span> <span class="c1"># => "C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">namespace: :"A::B"</span><span class="p">)</span> <span class="c1"># => "C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="ss">namespace: </span><span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">)</span> <span class="c1"># => "C"</span>
</code></pre>
<p>If the module/class does not belong to the namespace given as the parameter, then perhaps it would be a good idea to prepend the name with <code>::</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span><span class="p">;</span> <span class="k">class</span> <span class="nc">B</span><span class="p">;</span> <span class="k">class</span> <span class="nc">D</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span>
<span class="k">class</span> <span class="nc">E</span> <span class="k">end</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span> <span class="c1"># => "A::B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">D</span><span class="p">)</span> <span class="c1"># => "::A::B::C"</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">C</span><span class="p">.</span><span class="nf">name</span><span class="p">(</span><span class="no">E</span><span class="p">)</span> <span class="c1"># => "::A::B::C"</span>
</code></pre> Ruby master - Bug #16685 (Closed): IRB auto indent does not work for single-line method definitionshttps://bugs.ruby-lang.org/issues/166852020-03-10T21:41:44Zsawa (Tsuyoshi Sawada)
<p>IRB auto indent does not work correctly for single line method definitions within a class. It ends up like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">001</span><span class="p">:</span><span class="mi">1</span><span class="o">*</span> <span class="k">class</span> <span class="nc">Foo</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">002</span><span class="p">:</span><span class="mi">1</span><span class="o">*</span> <span class="k">def</span> <span class="nf">a</span><span class="p">;</span> <span class="k">end</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">003</span><span class="p">:</span><span class="mi">1</span><span class="o">*</span> <span class="k">def</span> <span class="nf">b</span><span class="p">;</span> <span class="k">end</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">004</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="k">end</span>
<span class="o">=></span> <span class="ss">:b</span>
</code></pre>
<p>I believe it should end up like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">001</span><span class="p">:</span><span class="mi">1</span><span class="o">*</span> <span class="k">class</span> <span class="nc">Foo</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">002</span><span class="p">:</span><span class="mi">1</span><span class="o">*</span> <span class="k">def</span> <span class="nf">a</span><span class="p">;</span> <span class="k">end</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">003</span><span class="p">:</span><span class="mi">1</span><span class="o">*</span> <span class="k">def</span> <span class="nf">b</span><span class="p">;</span> <span class="k">end</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">004</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="k">end</span>
<span class="o">=></span> <span class="ss">:b</span>
</code></pre> Ruby master - Feature #16684 (Open): Use the word "to" instead of "from" in backtracehttps://bugs.ruby-lang.org/issues/166842020-03-10T16:00:53Zsawa (Tsuyoshi Sawada)
<p>The most-recent-call-last order of backtrace introduced by <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add option to print backtrace in reverse order (stack frames first and error last) (Closed)" href="https://bugs.ruby-lang.org/issues/8661">#8661</a>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">a</span><span class="p">;</span> <span class="k">raise</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">b</span><span class="p">;</span> <span class="n">a</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">c</span><span class="p">;</span> <span class="n">b</span> <span class="k">end</span>
<span class="n">c</span>
</code></pre>
<p><strong>Current</strong></p>
<pre><code>Traceback (most recent call last):
3: from foo.rb:4:in `<main>'
2: from foo.rb:3:in `c'
1: from foo.rb:2:in `b'
foo.rb:1:in `a': unhandled exception
</code></pre>
<p>is intuitive to me, and I hope it is retained. However, there are people complaining that it is confusing. I believe the unnaturalness is (at least partly) due to the fact that the word "from" is used, which made sense when backtrace was displayed in most-recent-call-first order,</p>
<pre><code>foo.rb:1:in `a': unhandled exception
1: from foo.rb:2:in `b'
2: from foo.rb:3:in `c'
3: from foo.rb:4:in `<main>'
</code></pre>
<p>but not any more. Here, my understanding is that "from" means that the previous line was called <strong>from</strong> that line.</p>
<p>I propose that, so long as the most-recent-call-last order is adopted, the word "to" should be used rather than "from", which would mean that the previous line leads <strong>to</strong> that line:</p>
<p><strong>Proposed 1</strong></p>
<pre><code>Traceback (most recent call last):
3: to foo.rb:4:in `<main>'
2: to foo.rb:3:in `c'
1: to foo.rb:2:in `b'
foo.rb:1:in `a': unhandled exception
</code></pre>
<p>Or, as an alternative, if it looks unnatural to have "to" in the first line, and to lack one before the message line, we may put it at the end of a line:</p>
<p><strong>Proposed 2</strong></p>
<pre><code>Traceback (most recent call last)
3: foo.rb:4:in `<main>' to:
2: foo.rb:3:in `c' to:
1: foo.rb:2:in `b' to:
foo.rb:1:in `a': unhandled exception
</code></pre>
<p>By using different words, it would become easier to understand the display order at a glance, and even by just looking at a single line.</p> Ruby master - Feature #16601 (Open): Let `nil.to_a` and `nil.to_h` return a fixed instancehttps://bugs.ruby-lang.org/issues/166012020-01-31T10:11:44Zsawa (Tsuyoshi Sawada)
<p>Now, <code>nil.to_s</code> returns a fixed instance:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">nil</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 440</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 440</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 440</span>
<span class="o">...</span>
</code></pre>
<p>This is useful when we have some variable <code>foo</code> which may be either <code>nil</code> or a string, and we want to check its emptiness in a condition:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="n">foo</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">empty?</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
</code></pre>
<p>By this feature, we do not (need to) create a new instance of an empty string each time we check <code>foo</code>, even when it happens to be <code>nil</code>.</p>
<p>There are similar situations with arrays and hashes. We may have variable <code>bar</code> which may be either <code>nil</code> or an array, or <code>baz</code> which may be either <code>nil</code> or a hash, and we want to check their emptiness in conditions as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="n">bar</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">empty?</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="n">baz</span><span class="p">.</span><span class="nf">to_h</span><span class="p">.</span><span class="nf">empty?</span><span class="p">;</span> <span class="o">...</span> <span class="k">end</span>
</code></pre>
<p>But unlike <code>nil.to_s</code>, the methods <code>nil.to_a</code> and <code>nil.to_h</code> create new instances of empty array or hash each time they are called:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">nil</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 540</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 560</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_a</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 580</span>
<span class="o">...</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_h</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 460</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_h</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 480</span>
<span class="kp">nil</span><span class="p">.</span><span class="nf">to_h</span><span class="p">.</span><span class="nf">object_id</span> <span class="c1"># => 500</span>
<span class="o">...</span>
</code></pre>
<p>The fact that this is somewhat inefficient discourages the use of <code>foo.to_a</code> or <code>foo.to_h</code> in such use cases.</p>
<p>I request <code>nil.to_a</code> to <code>nil.to_h</code> to return a fixed empty instance.</p> Ruby master - Bug #16599 (Closed): did_you_mean is not activated for NameError and KeyErrorhttps://bugs.ruby-lang.org/issues/165992020-01-28T20:26:23Zsawa (Tsuyoshi Sawada)
<p><a href="https://www.rubydoc.info/gems/did_you_mean/" class="external">This document</a> claims that the did_you_mean gem responds to NameError, NoMethodError, and KeyError, but it actually seems to only respond to NoMethodError.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">foo</span><span class="p">()</span>
<span class="c1"># >> NoMethodError: undefined method `foo' for main:Object</span>
<span class="c1"># >> Did you mean? for</span>
<span class="n">foo</span>
<span class="c1"># >> NameError: undefined local variable or method `foo' for main:Object</span>
<span class="no">Foo</span>
<span class="c1"># >> NameError: uninitialized constant Foo</span>
<span class="p">{</span><span class="ss">foo: </span><span class="mi">1</span><span class="p">}.</span><span class="nf">fetch</span><span class="p">(</span><span class="ss">:bar</span><span class="p">)</span>
<span class="c1"># >> KeyError: key not found: :bar</span>
</code></pre> Ruby master - Bug #16506 (Closed): Documentation for `Module#const_souce_location` is wronghttps://bugs.ruby-lang.org/issues/165062020-01-12T18:17:28Zsawa (Tsuyoshi Sawada)
<p><a href="https://ruby-doc.org/core-2.7.0/Module.html#method-i-const_source_location" class="external">https://ruby-doc.org/core-2.7.0/Module.html#method-i-const_source_location</a> says:</p>
<blockquote>
<p>Returns the Ruby source filename and line number containing <strong>first</strong> definition of constant specified.</p>
</blockquote>
<p>It should be:</p>
<blockquote>
<p>Returns the Ruby source filename and line number containing the <strong>last</strong> definition (the effective definition) of the constant specified.</p>
</blockquote>
<p>It also has an example line:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">p</span> <span class="no">Object</span><span class="p">.</span><span class="nf">const_source_location</span><span class="p">(</span><span class="s1">'A'</span><span class="p">)</span> <span class="c1"># => ["test.rb", 1] -- note it is first entry, not "continuation"</span>
</code></pre>
<p>but that may give the impression that the first-ness is due to the nature of this method. The reason <code>["test.rb", 1]</code> is returned instead of <code>["test.rb", 14]</code> is because the constant is created at line 1, and is only reopened/modified in line 14. Perhaps, this line can be changed to:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">p</span> <span class="no">Object</span><span class="p">.</span><span class="nf">const_source_location</span><span class="p">(</span><span class="s1">'A'</span><span class="p">)</span> <span class="c1"># => ["test.rb", 1] -- note 'A' is created in line 1, and is only reopened/modified in "continuation"</span>
</code></pre>
<p>Adding something like this may make it clear that it is the last definition that is returned:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">D</span> <span class="o">=</span> <span class="s1">'D1'</span>
<span class="no">D</span> <span class="o">=</span> <span class="s1">'D2'</span>
<span class="no">D</span> <span class="o">=</span> <span class="s1">'D3'</span>
<span class="o">...</span>
<span class="no">Object</span><span class="p">.</span><span class="nf">const_source_location</span><span class="p">(</span><span class="s1">'D'</span><span class="p">)</span> <span class="c1"># => returns the location that corresponds to 'D3'</span>
</code></pre> Ruby master - Feature #16446 (Rejected): Enumerable#take_*, Enumerable#drop_* counterparts with p...https://bugs.ruby-lang.org/issues/164462019-12-23T08:26:05Zsawa (Tsuyoshi Sawada)
<p><a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Enumerable#take_while_after (Rejected)" href="https://bugs.ruby-lang.org/issues/16441">#16441</a> led me to think about the issue more generally. When we want to split a series of iterations by the first element that satisfies (or dissatisfies) a condition, we have three factors to consider.</p>
<p>(1) Whether we want the condition to work <strong>negatively</strong> or <strong>positively</strong><br>
(2) Whether we want the first element to satisfy (or dissatisfy) the condition to be included in the <strong>left</strong> side or the <strong>right</strong> side of the split<br>
(3) Whether we want the <strong>left</strong> side or the <strong>right</strong> side in the returned output</p>
<p>This leads us to eight possible combinations to consider.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">enum</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">].</span><span class="nf">to_enum</span>
</code></pre>
<table>
<thead>
<tr>
<th></th>
<th>(1)</th>
<th>(2)</th>
<th>(3)</th>
<th>method</th>
<th>example</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>negatively</td>
<td>left</td>
<td>left</td>
<td><code>take_while</code></td>
<td><code>enum.foo1(&:nonzero?) # => [1, 1]</code></td>
</tr>
<tr>
<td>2</td>
<td>negatively</td>
<td>left</td>
<td>right</td>
<td><code>drop_while</code></td>
<td><code>enum.foo2(&:nonzero?) # => [0, 3, 3, 0, 5, 5]</code></td>
</tr>
<tr>
<td>3</td>
<td>negatively</td>
<td>right</td>
<td>left</td>
<td></td>
<td><code>enum.foo3(&:nonzero?) # => [1, 1, 0]</code></td>
</tr>
<tr>
<td>4</td>
<td>negatively</td>
<td>right</td>
<td>right</td>
<td></td>
<td><code>enum.foo4(&:nonzero?) # => [3, 3, 0, 5, 5]</code></td>
</tr>
<tr>
<td>5</td>
<td>positively</td>
<td>left</td>
<td>left</td>
<td></td>
<td><code>enum.foo5(&:zero?) # => [1, 1]</code></td>
</tr>
<tr>
<td>6</td>
<td>positively</td>
<td>left</td>
<td>right</td>
<td></td>
<td><code>enum.foo6(&:zero?) # => [0, 3, 3, 0, 5, 5]</code></td>
</tr>
<tr>
<td>7</td>
<td>positively</td>
<td>right</td>
<td>left</td>
<td></td>
<td><code>enum.foo7(&:zero?) # => [1, 1, 0]</code></td>
</tr>
<tr>
<td>8</td>
<td>positively</td>
<td>right</td>
<td>right</td>
<td></td>
<td><code>enum.foo8(&:zero?) # => [3, 3, 0, 5, 5]</code></td>
</tr>
</tbody>
</table>
<p>Proposal <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Enumerable#take_while_after (Rejected)" href="https://bugs.ruby-lang.org/issues/16441">#16441</a> asks for a method that corresponds to case 3 in the table above, but I think that would make the paradigm messy unless case 4 is also implemented. Either cases 3 and 4 should both be implemented, or both not. Actually, the current proposal is not about cases 3 and 4. I would leave that to <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Backport request: MJIT crashes on a certain flow of branches (Closed)" href="https://bugs.ruby-lang.org/issues/16641">#16641</a>.</p>
<p>In many use cases (including the first example in <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Backport request: MJIT crashes on a certain flow of branches (Closed)" href="https://bugs.ruby-lang.org/issues/16641">#16641</a>), we want to detect the "marker element" by which we split the iterations. In the cases above, that can be the element <code>0</code>. In such use cases, it is more natural to describe the condition in positive terms (i.e., <code>zero?</code>) rather than negative terms (i.e., <code>nonzero?</code>). (And in other use cases, it might be the other way around.) So I would like to propose methods that correspond to cases 5, 6, 7, 8 above.</p>
<p>Naming of the methods should be done systematically. As a candidate, I came up with the following:</p>
<table>
<thead>
<tr>
<th></th>
<th>method</th>
</tr>
</thead>
<tbody>
<tr>
<td>5</td>
<td><code>take_before</code></td>
</tr>
<tr>
<td>6</td>
<td><code>drop_before</code></td>
</tr>
<tr>
<td>7</td>
<td><code>take_upto</code></td>
</tr>
<tr>
<td>8</td>
<td><code>drop_upto</code></td>
</tr>
</tbody>
</table> Ruby master - Feature #16274 (Closed): Transform hash keys by a hashhttps://bugs.ruby-lang.org/issues/162742019-10-23T09:09:15Zsawa (Tsuyoshi Sawada)
<p>We have <code>Hash#transform_keys</code> and its bang version to change the keys of a hash, but that requires passing a block, which assumes that the mapping from the old keys to the new keys follows some rule. But in reality, we frequently want to change the keys where it is difficult to provide a rule. For example, suppose we have:</p>
<pre><code>hash = {created: 2019-10-23 17:54:46 +0900, updated: 2019-10-23 17:59:18 +0900, author: "foo"}
</code></pre>
<p>and want to achieve:</p>
<pre><code>{created_at: 2019-10-23 17:54:46 +0900, update_time: 2019-10-23 17:59:18 +0900, author: "foo"}
</code></pre>
<p>I request an option to change the keys of a hash not by giving a block, but by passing a hash. I came up with two options.</p>
<a name="1-Argument-for-Hashtransform_keys-and-its-bang-version"></a>
<h3 >1. Argument for <code>Hash#transform_keys</code> and its bang version<a href="#1-Argument-for-Hashtransform_keys-and-its-bang-version" class="wiki-anchor">¶</a></h3>
<p>Allow <code>Hash#transform_keys</code> to optionally take a hash argument instead of a block.</p>
<pre><code>hash.transform_keys({created: :created_at, updated: :update_time})
# => {created_at: 2019-10-23 17:54:46 +0900, update_time: 2019-10-23 17:59:18 +0900, author: "foo"}
</code></pre>
<a name="2-Argument-for-Hashslice-and-the-counterparts-in-other-classes"></a>
<h3 >2. Argument for <code>Hash#slice</code> and the counterparts in other classes<a href="#2-Argument-for-Hashslice-and-the-counterparts-in-other-classes" class="wiki-anchor">¶</a></h3>
<p>Since <code>Hash#slice</code> is often the first step of modifying a hash into some other hash form, it makes sense to let it take an optional hash argument.</p>
<pre><code>hash.slice(:created, :author, transform_keys: {created: :created_at})
# => {created_at: 2019-10-23 17:54:46 +0900, author: "foo"}
</code></pre>
<p>With option 1, it could make sense to even allow a hash argument and a block simultaneously:</p>
<pre><code>hash.transform_keys({created: :created_at, updated: :update_time}, &:to_s)
# => {"created_at" => 2019-10-23 17:54:46 +0900, "update_time" => 2019-10-23 17:59:18 +0900, "author" => "foo"}
</code></pre> Ruby master - Feature #16246 (Open): require with an optional block that is evaluated when requir...https://bugs.ruby-lang.org/issues/162462019-10-09T05:54:23Zsawa (Tsuyoshi Sawada)
<p>I have some code like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="nb">require</span> <span class="s2">"foo"</span>
<span class="k">rescue</span> <span class="no">LoadError</span>
<span class="nb">puts</span> <span class="s2">"You need to install foo in order to have the function A work."</span>
<span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>I request to allow <code>require</code> to take a block which is executed when requiring fails. When <code>require</code> takes a block, a <code>LoadError</code> would not be raised. The code above would then be written like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"foo"</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="s2">"You need to install foo in order to have the function A work."</span>
<span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>If there is no need to particularly do anything, then it can be like</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">){}</span>
</code></pre>
<p>which will cover the use case in <a href="https://bugs.ruby-lang.org/issues/14565" class="external">https://bugs.ruby-lang.org/issues/14565</a>.</p> Ruby master - Feature #16166 (Closed): Remove exceptional treatment of *foo when it is the sole b...https://bugs.ruby-lang.org/issues/161662019-09-13T08:17:11Zsawa (Tsuyoshi Sawada)
<p>In the parameter signature of a code block for a method that is not involved in method definition or creation of lambda objects, two types of arguments <code>["a"]</code> and <code>"a"</code> are neutralized:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|</span><span class="n">foo</span><span class="p">,</span> <span class="n">bar</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => "a"</span>
<span class="n">instance_exec</span><span class="p">(</span><span class="s2">"a"</span><span class="p">){</span><span class="o">|</span><span class="n">foo</span><span class="p">,</span> <span class="n">bar</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => "a"</span>
<span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|*</span><span class="n">foo</span><span class="p">,</span> <span class="o">**</span><span class="n">bar</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => ["a"]</span>
<span class="n">instance_exec</span><span class="p">(</span><span class="s2">"a"</span><span class="p">){</span><span class="o">|*</span><span class="n">foo</span><span class="p">,</span> <span class="o">**</span><span class="n">bar</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>This is the same behavior as with assignment constructions:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">foo</span><span class="p">,</span> <span class="n">bar</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">];</span> <span class="n">foo</span> <span class="c1"># => "a"</span>
<span class="n">foo</span><span class="p">,</span> <span class="n">bar</span> <span class="o">=</span> <span class="s2">"a"</span><span class="p">;</span> <span class="n">foo</span> <span class="c1"># => "a"</span>
<span class="o">*</span><span class="n">foo</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">];</span> <span class="n">foo</span> <span class="c1"># => ["a"]</span>
<span class="o">*</span><span class="n">foo</span> <span class="o">=</span> <span class="s2">"a"</span><span class="p">;</span> <span class="n">foo</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>And it contrasts with constructions involved in method definition or creation of lambda objects, where the distinction is preserved:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">lambda</span><span class="p">{</span><span class="o">|</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">([</span><span class="s2">"a"</span><span class="p">])</span> <span class="c1"># => ["a"]</span>
<span class="nb">lambda</span><span class="p">{</span><span class="o">|</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span> <span class="c1"># => "a"</span>
<span class="o">-></span><span class="p">(</span><span class="n">foo</span><span class="p">){</span><span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">([</span><span class="s2">"a"</span><span class="p">])</span> <span class="c1"># => ["a"]</span>
<span class="o">-></span><span class="p">(</span><span class="n">foo</span><span class="p">){</span><span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span> <span class="c1"># => "a"</span>
<span class="nb">lambda</span><span class="p">{</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">([</span><span class="s2">"a"</span><span class="p">])</span> <span class="c1"># => [["a"]]</span>
<span class="nb">lambda</span><span class="p">{</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span> <span class="c1"># => ["a"]</span>
<span class="o">-></span><span class="p">(</span><span class="o">*</span><span class="n">foo</span><span class="p">){</span><span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">([</span><span class="s2">"a"</span><span class="p">])</span> <span class="c1"># => [["a"]]</span>
<span class="o">-></span><span class="p">(</span><span class="o">*</span><span class="n">foo</span><span class="p">){</span><span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>However, when <code>*foo</code> is the sole parameter of a code block for a method that is not involved in method definition or creation of lambda objects, <code>["a"]</code> and <code>"a"</code> are not neutralized:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => [["a"]]</span>
<span class="n">instance_exec</span><span class="p">(</span><span class="s2">"a"</span><span class="p">){</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>behaving in contrast to assignment constructions, and rather on a par with constructions involved in method definition or creation of lambda objects.</p>
<p>Particularly, existence or absence of another parameter <code>**bar</code> entirely changes what <code>foo</code> refers to:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => [["a"]]</span>
<span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|*</span><span class="n">foo</span><span class="p">,</span> <span class="o">**</span><span class="n">bar</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>I find this behavior inconsistent and confusing. I would like to request to remove this exceptional treatment of splatted parameter <code>*foo</code> when it is the sole parameter in a code block. I request this behavior:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => ["a"]</span>
</code></pre> Ruby master - Feature #16102 (Open): `Symbol#call`https://bugs.ruby-lang.org/issues/161022019-08-14T06:59:46Zsawa (Tsuyoshi Sawada)
<p>Since symbols have a <code>to_proc</code> method, it is natural to expect that they would appear in a method chain like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="ss">:some_symbol</span><span class="p">.</span><span class="nf">to_proc</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
</code></pre>
<p>In fact, I have use cases like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">arrays</span> <span class="o">=</span> <span class="p">[[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">],</span> <span class="p">[</span><span class="s2">"c"</span><span class="p">],</span> <span class="p">[</span><span class="s2">"d"</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">]]</span>
<span class="n">hashes</span> <span class="o">=</span> <span class="p">[{</span><span class="s2">"a"</span> <span class="o">=></span> <span class="mi">1</span><span class="p">},</span> <span class="p">{</span><span class="s2">"b"</span> <span class="o">=></span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"c"</span> <span class="o">=></span> <span class="mi">3</span><span class="p">},</span> <span class="p">{</span><span class="s2">"d"</span> <span class="o">=></span> <span class="mi">4</span><span class="p">,</span> <span class="s2">"e"</span> <span class="o">=></span> <span class="mi">5</span><span class="p">}]</span>
<span class="ss">:product</span><span class="p">.</span><span class="nf">to_proc</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">arrays</span><span class="p">)</span> <span class="c1"># => [["a", "c", "d"], ["a", "c", "e"], ["b", "c", "d"], ["b", "c", "e"]]</span>
<span class="ss">:zip</span><span class="p">.</span><span class="nf">to_proc</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">arrays</span><span class="p">)</span> <span class="c1"># => [["a", "c", "d"], ["b", nil, "e"]]</span>
<span class="ss">:union</span><span class="p">.</span><span class="nf">to_proc</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">arrays</span><span class="p">)</span> <span class="c1"># => ["a", "b", "c", "d", "e"]</span>
<span class="ss">:merge</span><span class="p">.</span><span class="nf">to_proc</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">hashes</span><span class="p">)</span> <span class="c1"># => {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5}</span>
</code></pre>
<p>I request <code>Symbol#call</code> to be defined, which would implicitly call <code>to_proc</code> on the receiver and then the conventional <code>Proc#call</code> on the result. Then, I can do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="ss">:product</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">arrays</span><span class="p">)</span> <span class="c1"># => [["a", "c", "d"], ["a", "c", "e"], ["b", "c", "d"], ["b", "c", "e"]]</span>
<span class="ss">:zip</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">arrays</span><span class="p">)</span> <span class="c1"># => [["a", "c", "d"], ["b", nil, "e"]]</span>
<span class="ss">:union</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">arrays</span><span class="p">)</span> <span class="c1"># => ["a", "b", "c", "d", "e"]</span>
<span class="ss">:merge</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">hashes</span><span class="p">)</span> <span class="c1"># => {"a"=>1, "b"=>2, "c"=>3, "d"=>4, "e"=>5}</span>
</code></pre>
<p>This would solve what proposals <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Array::zip (Rejected)" href="https://bugs.ruby-lang.org/issues/6499">#6499</a>, <a class="issue tracker-2 status-7 priority-4 priority-default closed" title="Feature: Add Array#rest (with implementation) (Feedback)" href="https://bugs.ruby-lang.org/issues/6727">#6727</a>, <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Array#product_set (Open)" href="https://bugs.ruby-lang.org/issues/7444">#7444</a>, <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Array.zip and Array.product (Open)" href="https://bugs.ruby-lang.org/issues/8970">#8970</a>, <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Make more objects behave like "Functions" (Open)" href="https://bugs.ruby-lang.org/issues/11262">#11262</a> aim to do.</p>
<p>Notice that proposals <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Add Symbol#call to allow to_proc shorthand with arguments (Open)" href="https://bugs.ruby-lang.org/issues/12115">#12115</a> and <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Symbol#call, returning method bound with arguments (Closed)" href="https://bugs.ruby-lang.org/issues/15301">#15301</a> ask for <code>Symbol#call</code>, but they ask for different things (a method that returns a proc), and are irrelevant to the current proposal.</p> Ruby master - Bug #16050 (Rejected): :@ is not parsed correctlyhttps://bugs.ruby-lang.org/issues/160502019-08-07T10:56:02Zsawa (Tsuyoshi Sawada)
<p>Symbol literal allows <code>@</code> as the first character:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="ss">:@foo</span> <span class="c1"># => :@foo</span>
</code></pre>
<p>Nevertheless, it does not allow <code>@</code> by itself:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">:</span><span class="err">@</span> <span class="c1"># >> SyntaxError: `@' without identifiers is not allowed as an instance variable name</span>
</code></pre>
<p>This resembles <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: :~@ and :!@ are not parsed correctly (Rejected)" href="https://bugs.ruby-lang.org/issues/10463">#10463</a>, but while <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: :~@ and :!@ are not parsed correctly (Rejected)" href="https://bugs.ruby-lang.org/issues/10463">#10463</a> is related to placeholder in a method name, the issue here is related to instance variable name, so I think they are different issues.</p> Ruby master - Feature #16037 (Open): Allow multiple single/double-splatted variables in `in` patt...https://bugs.ruby-lang.org/issues/160372019-08-02T11:50:30Zsawa (Tsuyoshi Sawada)
<p>Pattern matching in <code>in</code> argument seems to prohibit multiple occurrences of single/double-splatted variables.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">];</span> <span class="k">in</span> <span class="o">*</span><span class="n">foo</span><span class="p">,</span> <span class="no">Integer</span><span class="p">,</span> <span class="n">bar</span><span class="p">;</span> <span class="k">end</span> <span class="c1"># >> (Not SyntaxError)</span>
<span class="k">case</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">];</span> <span class="k">in</span> <span class="o">*</span><span class="n">foo</span><span class="p">,</span> <span class="no">Integer</span><span class="p">,</span> <span class="o">*</span><span class="n">bar</span><span class="p">;</span> <span class="k">end</span> <span class="c1"># >> SyntaxError: unexpected *</span>
</code></pre>
<p>However, unlike conventional constant/variable assignment, it makes sense to have multiple occurrences of single/double-splatted variables in a single pattern matching provided that we have a definite rule regarding whether the splats are greedy or not.</p>
<p>I propose the following.</p>
<ol>
<li>Relax the syntax for pattern matching in <code>in</code> argument to allow multiple occurrences of single/double-splatted variables, and set up a rule regarding whether the splats are greedy or not; preferably greedy.</li>
<li>Further, introduce new syntax for non-greedy splats <code>*?foo</code>, <code>**?foo</code>. Currently, they are syntactically invalid, so I don't think they would conflict with existing code.</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">,</span> <span class="s2">"f"</span><span class="p">];</span> <span class="k">in</span> <span class="o">*</span><span class="n">foo</span><span class="p">,</span> <span class="no">Integer</span><span class="p">,</span> <span class="o">*</span><span class="n">bar</span><span class="p">;</span> <span class="n">foo</span> <span class="k">end</span> <span class="c1"># => ["a", "b", 3, "c", "d"]</span>
<span class="k">case</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">,</span> <span class="s2">"b"</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s2">"c"</span><span class="p">,</span> <span class="s2">"d"</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="s2">"e"</span><span class="p">,</span> <span class="s2">"f"</span><span class="p">];</span> <span class="k">in</span> <span class="o">*</span><span class="p">?</span><span class="n">foo</span><span class="p">,</span> <span class="no">Integer</span><span class="p">,</span> <span class="o">*</span><span class="n">bar</span><span class="p">;</span> <span class="n">foo</span> <span class="k">end</span> <span class="c1"># => ["a", "b"]</span>
</code></pre> Ruby master - Bug #16010 (Rejected): Sole single-splatted variable with an array object in an ass...https://bugs.ruby-lang.org/issues/160102019-07-18T10:44:31Zsawa (Tsuyoshi Sawada)
<p>When a single splatted variable appears as the sole argument on the left side of assignment with an array on the right side, that variable is assigned the object as is on the right side:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">*</span><span class="n">foo</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">];</span> <span class="n">foo</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>This behavior looks inconsistent to me, and I am suspecting it is a bug from the reasons below.</p>
<hr>
<p>First, all other constructions that involve assignment of objects to variables work in the same way to one another, but in a different way from the above. That is, they add another nesting level of an array:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">instance_exec</span><span class="p">([</span><span class="s2">"a"</span><span class="p">]){</span><span class="o">|*</span><span class="n">foo</span><span class="o">|</span> <span class="n">foo</span><span class="p">}</span> <span class="c1"># => [["a"]]</span>
<span class="o">->*</span><span class="n">foo</span><span class="p">{</span><span class="n">foo</span><span class="p">}.</span><span class="nf">call</span><span class="p">([</span><span class="s2">"a"</span><span class="p">])</span> <span class="c1"># => [["a"]]</span>
<span class="k">def</span> <span class="nf">baz</span><span class="p">(</span><span class="o">*</span><span class="n">foo</span><span class="p">);</span> <span class="n">foo</span> <span class="k">end</span><span class="p">;</span> <span class="n">baz</span><span class="p">([</span><span class="s2">"a"</span><span class="p">])</span> <span class="c1"># => [["a"]]</span>
</code></pre>
<p>Second, if the object on the right side of the assignment construction in question is not an array, then another level of nesting is added:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">*</span><span class="n">foo</span> <span class="o">=</span> <span class="s2">"a"</span><span class="p">;</span> <span class="n">foo</span> <span class="c1"># => ["a"]</span>
</code></pre>
<p>The splat on a variable can be understood to collect the objects into an array. However, in the first example above in which the right side object is an array, all of a sudden, the additional nesting level of array becomes absent. It is not obvious why it behaves differently when the object to be collected is already an array.</p>
<p>Third, when there is no remaining object for the splatted variable, the variable is assigned an empty array,</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">*</span><span class="n">foo</span><span class="p">,</span> <span class="n">bar</span> <span class="o">=</span> <span class="s2">"baz"</span><span class="p">;</span> <span class="n">foo</span> <span class="c1"># => []</span>
</code></pre>
<p>and when more than one objects remain for the splatted variable, the variable is assigned an array that includes those objects, even if they are arrays:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">*</span><span class="n">foo</span><span class="p">,</span> <span class="n">bar</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">],</span> <span class="p">[</span><span class="s2">"b"</span><span class="p">],</span> <span class="s2">"c"</span><span class="p">;</span> <span class="n">foo</span> <span class="c1"># => [["a"], ["b"]]</span>
</code></pre>
<p>But when there is exactly one object that corresponds to the splatted variable, that object is not included in an array, but is given as is.</p>
<hr>
<p>In short, I believe the correct behavior should be as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">*</span><span class="n">foo</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"a"</span><span class="p">];</span> <span class="n">foo</span> <span class="c1"># => [["a"]]</span>
</code></pre> Ruby master - Feature #16006 (Rejected): String count and alignment that consider multibyte chara...https://bugs.ruby-lang.org/issues/160062019-07-16T03:35:12Zsawa (Tsuyoshi Sawada)
<p>In non-proportional font, multibyte characters have twice the width of ASCII characters. Since <code>String#length</code>, <code>String#ljust</code>, <code>String#rjust</code>, and <code>String#center</code> do not take this into consideration, applying these methods do not give the desired output.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">array</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"aaあああ"</span><span class="p">,</span> <span class="s2">"bいいいいいいいい"</span><span class="p">,</span> <span class="s2">"cc"</span><span class="p">]</span>
<span class="n">col_width</span> <span class="o">=</span> <span class="n">array</span><span class="p">.</span><span class="nf">max</span><span class="p">(</span><span class="o">&</span><span class="ss">:length</span><span class="p">)</span>
<span class="n">array</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">w</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">w</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="n">col_width</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)}</span>
<span class="c1"># >> aaあああ****</span>
<span class="c1"># >> bいいいいいいいい</span>
<span class="c1"># >> cc*******</span>
</code></pre>
<p>In order to do justification of strings that have multi-byte characters, we have to do something much more complicated such as the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">col_widths</span> <span class="o">=</span>
<span class="n">array</span><span class="p">.</span><span class="nf">to_h</span><span class="p">{</span><span class="o">|</span><span class="n">w</span><span class="o">|</span> <span class="p">[</span>
<span class="n">w</span><span class="p">,</span>
<span class="n">w</span>
<span class="p">.</span><span class="nf">chars</span>
<span class="p">.</span><span class="nf">partition</span><span class="p">(</span><span class="o">&</span><span class="ss">:ascii_only?</span><span class="p">)</span>
<span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="o">|</span><span class="n">ascii</span><span class="p">,</span> <span class="n">non</span><span class="o">|</span> <span class="n">ascii</span><span class="p">.</span><span class="nf">length</span> <span class="o">+</span> <span class="p">(</span><span class="n">non</span><span class="p">.</span><span class="nf">length</span> <span class="o">*</span> <span class="mi">2</span><span class="p">)}</span>
<span class="p">]}</span>
<span class="n">col_width</span> <span class="o">=</span> <span class="n">col_widths</span><span class="p">.</span><span class="nf">values</span><span class="p">.</span><span class="nf">max</span>
<span class="n">array</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">w</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">w</span> <span class="o">+</span> <span class="s2">"*"</span> <span class="o">*</span> <span class="p">(</span><span class="n">col_width</span> <span class="o">-</span> <span class="n">col_widths</span><span class="p">[</span><span class="n">w</span><span class="p">])}</span>
<span class="c1"># Note that the following gives the desired alignment in non-proportional font, but may not appear so in this issue tracker.</span>
<span class="c1"># >> aaあああ*********</span>
<span class="c1"># >> bいいいいいいいい</span>
<span class="c1"># >> cc***************</span>
</code></pre>
<p>This issue seems to be common, as several webpages can be found that attempt to do something similar.</p>
<p>I propose to give the relevant methods an option to take multibyte characters into consideration. Perhaps something like the <code>proportional</code> keyword in the following may work:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"aaあああ"</span><span class="p">.</span><span class="nf">length</span><span class="p">(</span><span class="ss">proportional: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => 8</span>
<span class="s2">"aaあああ"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="mi">17</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">proportional: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "aaあああ*********"</span>
</code></pre>
<p>Then, the desired output would be given by this code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">col_width</span> <span class="o">=</span> <span class="n">array</span><span class="p">.</span><span class="nf">max</span><span class="p">{</span><span class="o">|</span><span class="n">w</span><span class="o">|</span> <span class="n">w</span><span class="p">.</span><span class="nf">length</span><span class="p">(</span><span class="ss">proportional: </span><span class="kp">true</span><span class="p">)}</span>
<span class="n">array</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">w</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">w</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="n">col_width</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">proportional: </span><span class="kp">true</span><span class="p">)}</span>
<span class="c1"># >> aaあああ*********</span>
<span class="c1"># >> bいいいいいいいい</span>
<span class="c1"># >> cc***************</span>
</code></pre> Ruby master - Bug #15987 (Closed): Let `exception` option in `Kernel#Complex`, `Kernel#Float`, `K...https://bugs.ruby-lang.org/issues/159872019-07-05T03:12:16Zsawa (Tsuyoshi Sawada)
<p>The <code>exception</code> option in <code>Kernel#Complex</code>, <code>Kernel#Float</code>, <code>Kernel#Integer</code>, and <code>Kernel#Rational</code> distinguishes <code>false</code> vs. other values.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Integer</span><span class="p">(</span><span class="s2">"z"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">false</span><span class="p">)</span> <span class="c1">#=> nil</span>
<span class="no">Integer</span><span class="p">(</span><span class="s2">"z"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">nil</span><span class="p">)</span> <span class="c1">#>> ArgumentError: invalid value for Integer(): "z")</span>
</code></pre>
<p>But in most other cases where a boolean notion is concerned (for example, the <code>chomp</code> option in <code>Kernel#gets</code>), the distinction is between falsy vs. truthy values.</p>
<p>I request the distinction to be falsy vs. truthy. In other words, I would like the value <code>nil</code> to work on the falsy side rather than the truthy side like this.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Integer</span><span class="p">(</span><span class="s2">"z"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">false</span><span class="p">)</span> <span class="c1">#=> nil</span>
<span class="no">Integer</span><span class="p">(</span><span class="s2">"z"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">nil</span><span class="p">)</span> <span class="c1">#=> nil</span>
</code></pre> Ruby master - Feature #15954 (Rejected): 簡単にマルチスレッドを一度に合流させるhttps://bugs.ruby-lang.org/issues/159542019-06-24T10:18:38Zsawa (Tsuyoshi Sawada)
<p>現在いるスレッド以外の全てのスレッドを現在のスレッドに合流させたいときは多いと思います。</p>
<p>その場合、一つの方法は、スレッドを生成するときにそれらを配列に蓄えておき、あとでその配列の各要素のスレッドに対して<code>join</code>をすることですが、そのためにわざわざスレッドを配列に蓄えておかなければならないのは、若干手間で無駄かなと思います。</p>
<p>それを回避する方法として、私の思いつく限りで単純な方法は次のようなものです。</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Thread</span><span class="p">.</span><span class="nf">list</span><span class="p">.</span><span class="nf">each</span><span class="p">{</span><span class="o">|</span><span class="n">t</span><span class="o">|</span> <span class="n">t</span><span class="p">.</span><span class="nf">join</span> <span class="k">unless</span> <span class="n">t</span> <span class="o">==</span> <span class="no">Thread</span><span class="p">.</span><span class="nf">current</span><span class="p">}</span>
</code></pre>
<p>しかし、ここでは現在のスレッドを合流の対象から除く条件式を入れる必要があるためにエレガントでありません。そこで、<code>Thread.list</code>から現在のスレッドを除いた配列を返すメソッドを希望します。これは<code>Dir.entries</code>だと不要なピリオドファイルが含まれる不便さから<code>Dir.children</code>が作られたのと同じ発想です。</p>
<p>あるいは、一歩進めて、<code>Thread.join_other_threads</code>のような感じで現在のスレッド以外の全てのスレッドを一気に合流させるメソッドがあってもよいと思います。</p> Ruby master - Feature #15950 (Rejected): Allow negative length in `Array#[]`, `Array#[]=`, `Array...https://bugs.ruby-lang.org/issues/159502019-06-22T03:09:43Zsawa (Tsuyoshi Sawada)
<p>To take the first n characters of a string, using <code>[]</code> is straightforward:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"abcdefgh"</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span> <span class="c1"># => "abc"</span>
</code></pre>
<p>But to take the last n characters, we need to use n in two arguments: in the index (in negative form) in addition to the length:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"abcdefgh"</span><span class="p">[</span><span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span> <span class="c1"># => "fgh"</span>
</code></pre>
<p>This is cumbersome.</p>
<p>I wish negative length to be allowed, and be interpreted as measuring leftward (while cycling the receiver if necessary).</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"abcdefgh"</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="c1"># => "fgh"</span>
<span class="s2">"abcdefgh"</span><span class="p">[</span><span class="mi">5</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="c1"># => "cde"</span>
</code></pre>
<p>If there is not enough characters or elements, it should stop at the boundary.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"abcdefgh"</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">]</span> <span class="c1"># => "a"</span>
</code></pre> Ruby master - Feature #15945 (Open): Option to truncate in `String#ljust`, `String#rjust`, and `S...https://bugs.ruby-lang.org/issues/159452019-06-20T12:00:24Zsawa (Tsuyoshi Sawada)
<p>Sometimes, I need to adjust a string to an exact length: Pad if shorter, and truncate if longer. To do that, I need to combine two methods like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"12"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span> <span class="c1"># => "12***"</span>
<span class="s2">"1234567"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span> <span class="c1"># => "12345"</span>
<span class="s2">"xyz"</span><span class="p">.</span><span class="nf">rjust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)[</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span> <span class="c1"># => "**xyz"</span>
<span class="s2">"stuvwxyz"</span><span class="p">.</span><span class="nf">rjust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)[</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span> <span class="c1"># => "vwxyz"</span>
</code></pre>
<p>But that is messy, and needs a bit of thinking. It becomes even harder with centering.</p>
<p>I request an option on <code>String#ljust</code>, <code>String#rjust</code>, <code>String#center</code> to truncate the string when it is longer than the given length.</p>
<p>One way to do so may be: take a keyword <code>:truncate</code> or <code>:trunc</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"12"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">trunc: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "12***"</span>
<span class="s2">"1234567"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">trunc: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "12345"</span>
<span class="s2">"xyz"</span><span class="p">.</span><span class="nf">rjust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">trunc: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "**xyz"</span>
<span class="s2">"stuvwxyz"</span><span class="p">.</span><span class="nf">rjust</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">trunc: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "vwxyz"</span>
<span class="s2">"abc"</span><span class="p">.</span><span class="nf">center</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">trunc: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "*abc*"</span>
<span class="s2">"abcdefg"</span><span class="p">.</span><span class="nf">center</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">,</span> <span class="ss">trunc: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => "bcdef"</span>
</code></pre>
<p>Another way is, when the length is negative, interpret it as truncating option.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"12"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)</span> <span class="c1"># => "12***"</span>
<span class="s2">"1234567"</span><span class="p">.</span><span class="nf">ljust</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)</span> <span class="c1"># => "12345"</span>
<span class="s2">"xyz"</span><span class="p">.</span><span class="nf">rjust</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)</span> <span class="c1"># => "**xyz"</span>
<span class="s2">"stuvwxyz"</span><span class="p">.</span><span class="nf">rjust</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)</span> <span class="c1"># => "vwxyz"</span>
<span class="s2">"abc"</span><span class="p">.</span><span class="nf">center</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)</span> <span class="c1"># => "*abc*"</span>
<span class="s2">"abcdefg"</span><span class="p">.</span><span class="nf">center</span><span class="p">(</span><span class="o">-</span><span class="mi">5</span><span class="p">,</span> <span class="s2">"*"</span><span class="p">)</span> <span class="c1"># => "bcdef"</span>
</code></pre>
<p>But the second way changes the current behavior.</p> Ruby master - Feature #15919 (Rejected): Offset parameter for `Integer#times`https://bugs.ruby-lang.org/issues/159192019-06-13T09:18:47Zsawa (Tsuyoshi Sawada)
<p>I request an optional argument on <code>Integer#times</code> to set the offset at start, just like <code>Enumerator#with_index</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">5</span><span class="p">.</span><span class="nf">times</span><span class="p">(</span><span class="mi">3</span><span class="p">){</span><span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">p</span> <span class="n">i</span><span class="p">}</span>
<span class="c1"># >> 3</span>
<span class="c1"># >> 4</span>
<span class="c1"># >> 5</span>
<span class="c1"># >> 6</span>
<span class="c1"># >> 7</span>
</code></pre>
<p>I think there are plenty of use cases, especially when the offset is 1.</p> Ruby master - Feature #15722 (Feedback): `Kernel#case?`https://bugs.ruby-lang.org/issues/157222019-03-22T07:12:32Zsawa (Tsuyoshi Sawada)
<p>I often want to use <code>===</code> to match a single object on the right side against multiple objects on the left, as is used in <code>case</code>-constructions, just to return a truth value, and end up writing like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">bar</span> <span class="c1"># => "bar"</span>
<span class="n">flag1</span> <span class="o">=</span> <span class="k">case</span> <span class="n">bar</span><span class="p">;</span> <span class="k">when</span> <span class="s2">"foo"</span><span class="p">,</span> <span class="s2">"bar"</span><span class="p">,</span> <span class="s2">"baz"</span><span class="p">;</span> <span class="kp">true</span><span class="p">;</span> <span class="k">end</span> <span class="c1"># => true</span>
<span class="n">flag2</span> <span class="o">=</span> <span class="k">case</span> <span class="n">bar</span><span class="p">;</span> <span class="k">when</span> <span class="no">Symbol</span><span class="p">,</span> <span class="no">String</span><span class="p">;</span> <span class="kp">true</span><span class="p">;</span> <span class="k">end</span> <span class="c1"># => true</span>
</code></pre>
<p>I propose <code>Kernel#case?</code> that should work like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">bar</span> <span class="c1"># => "bar"</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">case?</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="s2">"bar"</span><span class="p">,</span> <span class="s2">"baz"</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">case?</span><span class="p">(</span><span class="s2">"qux"</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">case?</span><span class="p">(</span><span class="no">Symbol</span><span class="p">,</span> <span class="no">String</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">case?</span><span class="p">(</span><span class="no">Array</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="n">bar</span><span class="p">.</span><span class="nf">case?</span> <span class="c1"># => false</span>
</code></pre>
<p>It is similar to Rails' <code>in?</code>, but it differs from it in that it uses <code>===</code> for comparison, not <code>==</code>.</p>
<p>Or, alternatively, allowing <code>Kernel#instance_of?</code> and <code>Kernel#kind_of?</code> to allow multiple arguments may be a compromise.</p> Ruby master - Bug #15708 (Rejected): Implicit numbered argument decomposes an arrayhttps://bugs.ruby-lang.org/issues/157082019-03-19T11:08:39Zsawa (Tsuyoshi Sawada)
<p>In the following, <code>@1</code> refers to the entire item iterated:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span><span class="p">}</span> <span class="c1"># => [1, 2, 3]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="err">@</span><span class="mi">1</span><span class="p">}</span> <span class="c1"># => [1, 2, 3]</span>
</code></pre>
<p>whereas in the following, <code>@1</code> refers to the first item achieved by decomposing the item iterated, behaving the same as <code>x</code> given by <code>|(x)|</code> rather than by <code>|x|</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[[</span><span class="mi">1</span><span class="p">],</span> <span class="p">[</span><span class="mi">2</span><span class="p">],</span> <span class="p">[</span><span class="mi">3</span><span class="p">]]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span><span class="p">}</span> <span class="c1"># => [[1], [2], [3]]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">|</span> <span class="n">x</span><span class="p">}</span> <span class="c1"># => [1, 2, 3]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="err">@</span><span class="mi">1</span><span class="p">}</span> <span class="c1"># => [1, 2, 3]</span>
</code></pre>
<p>Is this intended?</p> Ruby master - Feature #15627 (Open): Appearance of custom singleton classeshttps://bugs.ruby-lang.org/issues/156272019-02-28T11:47:27Zsawa (Tsuyoshi Sawada)
<p>When I have a singleton class <code>AClass</code> of an instance <code>a</code> of a custom class <code>A</code>,</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span><span class="p">;</span> <span class="k">end</span>
<span class="n">a</span> <span class="o">=</span> <span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="no">AClass</span> <span class="o">=</span> <span class="n">a</span><span class="p">.</span><span class="nf">singleton_class</span>
</code></pre>
<p>i) even though the singleton class of <code>nil</code>, <code>false</code>, and <code>true</code> are referred to by their assigned constant names, the singleton class <code>AClass</code> of <code>a</code> is not:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">nil</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1">#=> NilClass</span>
<span class="kp">false</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1">#=> FalseClass</span>
<span class="kp">true</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1">#=> TrueClass</span>
<span class="n">a</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1">#=> #<Class:#<A:0x00007fda832a7eb0>></span>
</code></pre>
<p>ii) even though the singleton class of <code>nil</code>, <code>false</code>, and <code>true</code> appear as their class, the singleton class <code>AClass</code> of <code>a</code> does not:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">nil</span><span class="p">.</span><span class="nf">class</span> <span class="c1">#=> NilClass</span>
<span class="kp">false</span><span class="p">.</span><span class="nf">class</span> <span class="c1">#=> FalseClass</span>
<span class="kp">true</span><span class="p">.</span><span class="nf">class</span> <span class="c1">#=> TrueClass</span>
<span class="n">a</span><span class="p">.</span><span class="nf">class</span> <span class="c1">#=> A</span>
</code></pre>
<p>This contrast between <code>nil</code>, <code>false</code>, and <code>true</code> on the one hand and <code>a</code> on the other is confusing. I am actually not sure if this is intended behaviour It may be related to</p>
<ul>
<li><a href="https://bugs.ruby-lang.org/issues/15608" class="external">https://bugs.ruby-lang.org/issues/15608</a></li>
<li><a href="https://bugs.ruby-lang.org/issues/14895" class="external">https://bugs.ruby-lang.org/issues/14895</a></li>
</ul>
<p>I expect <code>AClass</code> to behave the same as with <code>NilClass</code>, <code>FalseClass</code>, and <code>TrueClass</code>. I expect:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">singleton_class</span> <span class="c1">#=> AClass</span>
<span class="n">a</span><span class="p">.</span><span class="nf">class</span> <span class="c1">#=> AClass</span>
</code></pre>
<p>If the current behaviour is intended, I would like this to become a feature request.</p> Ruby master - Feature #15612 (Feedback): A construct to restrict the scope of local variableshttps://bugs.ruby-lang.org/issues/156122019-02-19T12:42:21Zsawa (Tsuyoshi Sawada)
<p>We sometimes have local variables that are to be used only to keep track of some temporal states/values during a short routine:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o">...</span>
<span class="n">foo</span> <span class="o">=</span> <span class="n">some_initial_value</span>
<span class="n">some_routine_that_uses_foo</span>
<span class="o">...</span>
</code></pre>
<p>Currently, the scope of local variables are either a proc, a block, <code>loop</code> body, a method definition, or a class/module definition, but such routines are sometimes just only a part of them.</p>
<p>In order to improve readability of the code by explicitly indicating the scope of such local variables, and to avoid pollution by the variable, I propose to have some construct to restrict the scope of local variables.</p>
<p>One possibility, without adding a new keyword to the current syntax, is to use the <code>begin</code>...<code>end</code> construct. The expected behavior would be:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="n">foo</span> <span class="o">=</span> <span class="s2">"foo"</span>
<span class="n">foo</span> <span class="c1"># => "foo"</span>
<span class="k">end</span>
<span class="n">foo</span> <span class="c1"># => `nil`, or "Undefined local variable or method error"</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">foo</span> <span class="o">=</span> <span class="s2">"bar"</span>
<span class="k">begin</span>
<span class="n">foo</span> <span class="o">=</span> <span class="s2">"foo"</span>
<span class="n">foo</span> <span class="c1"># => "foo"</span>
<span class="k">end</span>
<span class="n">foo</span> <span class="c1"># => "bar"</span>
</code></pre>
<p>Or, does this break the existing code too much? If so, can a new construct be added to the current syntax?</p> Ruby master - Feature #15589 (Closed): `Numeric#zero?` is much slower than `== 0`https://bugs.ruby-lang.org/issues/155892019-02-06T09:34:41Zsawa (Tsuyoshi Sawada)
<p>My understanding is that the predicate method <code>Numeric#zero?</code> is not only a shorthand for <code>== 0</code>, but is also optimized for frequent patterns. If <code>zero?</code> is not faster than <code>== 0</code>, then it loses its reason for existence.</p>
<p>However, According to benchmarks on my environment, <code>number.zero?</code> is around 1.23 times to 1.64 times slower than <code>number == 0</code> when <code>number</code> is an <code>Integer</code>, <code>Rational</code>, or <code>Complex</code>. It is faster only when <code>number</code> is a <code>Float</code>.</p>
<p>And with <code>number.nonzero?</code>, it is even worse. It is about 1.88 times to 4.35 times slower than <code>number != 0</code>.</p>
<p>I think there is something wrong with this, and it should be possible to optimize these methods, which has somehow been missed.</p> Ruby master - Feature #15562 (Open): `String#split` option to suppress the initial empty substringhttps://bugs.ruby-lang.org/issues/155622019-01-25T07:19:12Zsawa (Tsuyoshi Sawada)
<p><code>String#split</code> returns an empty substring if any at the beginning of the original string, even though it does not return an empty substring at the end of the original string:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span> <span class="c1"># => ["", "b"]</span>
</code></pre>
<p>This is probably heritage from Perl or AWK, and may have some use cases, but in some (if not most) use cases, this looks asymmetric, and the initial empty string is unnatural and often requires some additional code to remove it. I propose to give an option to <code>String#split</code> to suppress it, perhaps like this (with <code>true</code> being the default):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">initial_empty_string: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => ["b"]</span>
<span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">initial_empty_string: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => ["", "b"]</span>
<span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"ba"</span><span class="p">,</span> <span class="ss">initial_empty_string: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => ["b"]</span>
</code></pre>
<p>This does not mean to suppress empty strings in the middle. So it should work like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"aaaba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">initial_empty_string: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => ["", "", "b"]</span>
<span class="s2">"aaaba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">initial_empty_string: </span><span class="kp">true</span><span class="p">)</span> <span class="c1"># => ["", "", "", "b"]</span>
</code></pre>
<p>Or may be we can even go on further to control both the initial and the final ones like (with <code>:initial</code> being the default):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">terminal_empty_string: :none</span><span class="p">)</span> <span class="c1"># => ["b"]</span>
<span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">terminal_empty_string: :initial</span><span class="p">)</span> <span class="c1"># => ["", "b"]</span>
<span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">terminal_empty_string: :final</span><span class="p">)</span> <span class="c1"># => ["b", ""]</span>
<span class="s2">"aba"</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">,</span> <span class="ss">terminal_empty_string: :both</span><span class="p">)</span> <span class="c1"># => ["", "b", ""]</span>
</code></pre> Ruby master - Feature #15557 (Open): A new class that stores a condition and the previous receiverhttps://bugs.ruby-lang.org/issues/155572019-01-23T09:15:54Zsawa (Tsuyoshi Sawada)
<p>I often see code like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">foo</span> <span class="o">=</span> <span class="n">default_definition</span>
<span class="n">foo</span> <span class="o">=</span> <span class="n">some_method</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> <span class="k">if</span> <span class="n">some_condition</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="n">foo</span> <span class="o">=</span> <span class="n">another_method</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span> <span class="k">if</span> <span class="n">another_condition</span><span class="p">(</span><span class="n">foo</span><span class="p">)</span>
<span class="o">...</span>
</code></pre>
<p>It would be nice if we can write this as a method chain. Since we now have the method <code>then</code>, I thought it would be a nice fit to introduce a method called <code>when</code>, such that putting it right in front of <code>then</code> would execute the <code>then</code> method as ordinarily only when the condition is satisfied, and returns the previous receiver otherwise so that the code above can be rewritten as:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">foo</span> <span class="o">=</span>
<span class="n">default_definition</span>
<span class="p">.</span><span class="nf">when</span><span class="p">{</span><span class="o">|</span><span class="n">foo</span><span class="o">|</span> <span class="n">some_condition</span><span class="p">(</span><span class="n">foo</span><span class="p">)}</span>
<span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="o">|</span><span class="n">foo</span><span class="o">|</span> <span class="n">some_method</span><span class="p">(</span><span class="n">foo</span><span class="p">)}</span>
<span class="p">.</span><span class="nf">when</span><span class="p">{</span><span class="o">|</span><span class="n">foo</span><span class="o">|</span> <span class="n">another_condition</span><span class="p">(</span><span class="n">foo</span><span class="p">)}</span>
<span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="o">|</span><span class="n">foo</span><span class="o">|</span> <span class="n">another_method</span><span class="p">(</span><span class="n">foo</span><span class="p">)}</span>
</code></pre>
<p>This proposal is also a generalization of what I intended to cover by <a href="https://bugs.ruby-lang.org/issues/13807" class="external">https://bugs.ruby-lang.org/issues/13807</a>. That is,</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">some_condition</span> <span class="p">?</span> <span class="n">a</span> <span class="p">:</span> <span class="n">b</span>
</code></pre>
<p>would rewritten as:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">when</span><span class="p">(</span><span class="o">&</span><span class="ss">:some_condition</span><span class="p">).</span><span class="nf">then</span><span class="p">{</span><span class="n">b</span><span class="p">}</span>
</code></pre>
<p>The proposal can be implemented by introducing a class called <code>Condition</code>, which stores a condition and the previous receiver, and works with <code>then</code> in a particular way.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">when</span>
<span class="no">Condition</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="k">yield</span><span class="p">(</span><span class="nb">self</span><span class="p">))</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Condition</span>
<span class="k">def</span> <span class="nf">initialize</span> <span class="n">default</span><span class="p">,</span> <span class="n">condition</span>
<span class="vi">@default</span><span class="p">,</span> <span class="vi">@condition</span> <span class="o">=</span> <span class="n">default</span><span class="p">,</span> <span class="n">condition</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">then</span>
<span class="vi">@condition</span> <span class="p">?</span> <span class="k">yield</span><span class="p">(</span><span class="vi">@default</span><span class="p">)</span> <span class="p">:</span> <span class="vi">@default</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>And additionally, if we introduce a negated method <code>unless</code> (or <code>else</code>) as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">unless</span>
<span class="no">Condition</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="nb">self</span><span class="p">,</span> <span class="o">!</span><span class="k">yield</span><span class="p">(</span><span class="nb">self</span><span class="p">))</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>then we can use that for purposes such as validation of a variable as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">bar</span> <span class="o">=</span>
<span class="nb">gets</span>
<span class="p">.</span><span class="nf">unless</span><span class="p">{</span><span class="o">|</span><span class="n">bar</span><span class="o">|</span> <span class="n">some_validation</span><span class="p">(</span><span class="n">bar</span><span class="p">)}</span>
<span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="k">raise</span> <span class="s2">"The input is bad."</span><span class="p">}</span>
<span class="p">.</span><span class="nf">unless</span><span class="p">{</span><span class="o">|</span><span class="n">bar</span><span class="o">|</span> <span class="n">another_validation</span><span class="p">(</span><span class="n">bar</span><span class="p">)}</span>
<span class="p">.</span><span class="nf">then</span><span class="p">{</span><span class="k">raise</span> <span class="s2">"The input is bad in another way."</span><span class="p">}</span>
</code></pre> Ruby master - Feature #15523 (Open): Let `Range#begin` and `Range#end` be aliases of Range#first ...https://bugs.ruby-lang.org/issues/155232019-01-11T04:44:48Zsawa (Tsuyoshi Sawada)
<p>My understanding is that <code>Range#begin</code> and <code>Range#end</code>'s features are just subsets of <code>Range#first</code> and <code>Range#last</code>, respectively. And since they are slightly confusing with the keywords <code>begin</code> and <code>end</code>, I propose to either:</p>
<ul>
<li>Let <code>Range#begin</code> and <code>Range#end</code> be aliases of <code>Range#first</code> and <code>Range#last</code>, respectively, or</li>
<li>Let <code>Range#begin</code> and <code>Range#end</code> be obsolete after a migration path of waning against their use and recommending the use of <code>Range#first</code> and <code>Range#last</code> instead.</li>
</ul> Ruby master - Feature #15381 (Open): Let double splat call `to_h` implicitlyhttps://bugs.ruby-lang.org/issues/153812018-12-05T08:25:04Zsawa (Tsuyoshi Sawada)
<p>The single splat calls <code>to_a</code> implicitly on the object (if it is not an array already) so that, for example, we have the convenience of writing conditions in an array literal:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span>
<span class="o">*</span><span class="p">(</span><span class="ss">:foo</span> <span class="k">if</span> <span class="n">some_condition</span><span class="p">),</span>
<span class="o">*</span><span class="p">(</span><span class="ss">:bar</span> <span class="k">if</span> <span class="n">another_condition</span><span class="p">),</span>
<span class="p">]</span>
</code></pre>
<p>And the ampersand implicitly calls <code>to_proc</code> on the object (if it is not a proc already) so that we can substitute a block with an ampersand followed by a symbol:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">some_method</span><span class="p">(</span><span class="o">&</span><span class="ss">:some_method_name</span><span class="p">)</span>
</code></pre>
<p>Unlike the single splat and ampersand, the double splat does not seem to implicitly call a corresponding method. I propose that the double splat should call <code>to_h</code> implicitly on the object if it not already a Hash so that we can, for example, write a condition in a hash literal as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{</span>
<span class="o">**</span><span class="p">({</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}</span> <span class="k">if</span> <span class="n">some_condition</span><span class="p">),</span>
<span class="o">**</span><span class="p">({</span><span class="ss">b: </span><span class="mi">2</span><span class="p">)</span> <span class="k">if</span> <span class="n">another_condition</span><span class="p">),</span>
<span class="p">}</span>
</code></pre>
<p>There may be some other benefits of this feature that I have not noticed yet.</p> Ruby master - Feature #15143 (Closed): Extend `Enumerable#to_h`https://bugs.ruby-lang.org/issues/151432018-09-20T02:23:27Zsawa (Tsuyoshi Sawada)
<p>Often, we call <code>Array#to_h</code> to the result of <code>Enumerable#map</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">5</span><span class="p">).</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span> <span class="o">**</span> <span class="mi">2</span><span class="p">]}.</span><span class="nf">to_h</span>
<span class="c1">#=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}</span>
</code></pre>
<p>I am thinking of a feature to do this in a single method call.</p>
<p>Currently, <code>Enumerable#to_h</code> does not accept a block. I propose that, when <code>Enumerable#to_h</code> is called with a block (that has a subarray representing a key-value pair), return a hash that would be returned by applying the block to <code>map</code>, and <code>to_h</code> to the result:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">5</span><span class="p">).</span><span class="nf">to_h</span><span class="p">{</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="p">[</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span> <span class="o">**</span> <span class="mi">2</span><span class="p">]}</span>
<span class="c1">#=> {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}</span>
</code></pre>
<p>Ideally, I request this to be done internally to Ruby without creating an intermediate parent array.</p> Ruby master - Feature #14559 (Closed): ENV.slicehttps://bugs.ruby-lang.org/issues/145592018-02-28T08:39:22Zsawa (Tsuyoshi Sawada)
<p>I would like to request <code>ENV.slice</code>, which should behave analogous to <code>Hash#slice</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">ENV</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="s2">"PATH"</span><span class="p">,</span> <span class="s2">"FOO"</span><span class="p">)</span>
<span class="c1"># => {"PATH" => "/foo:/bar", "FOO" => "foo"}</span>
</code></pre> Ruby master - Feature #14443 (Closed): Omit 'pattern' parameter in '(g)sub(!)' when 'hash' is givenhttps://bugs.ruby-lang.org/issues/144432018-02-05T05:58:45Zsawa (Tsuyoshi Sawada)
<p>When <code>(g)sub(!)</code> takes a hash as the second argument, in almost all use cases, the first argument expresses the union of keys of the hash. In the following, <code>/[abc]/</code> is the union of the keys <code>"a"</code>, <code>"b"</code>, <code>"c"</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"blahblah"</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="sr">/[abc]/</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a"</span> <span class="o">=></span> <span class="s2">"A"</span><span class="p">,</span> <span class="s2">"b"</span> <span class="o">=></span> <span class="s2">"B"</span><span class="p">,</span> <span class="s2">"c"</span> <span class="o">=></span> <span class="s2">"C"</span><span class="p">})</span>
</code></pre>
<p>I feel this redundant and not efficient. Hence I propose to let the current first argument be optional when a hash is given. The following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"blahblah"</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="s2">"a"</span> <span class="o">=></span> <span class="s2">"A"</span><span class="p">,</span> <span class="s2">"b"</span> <span class="o">=></span> <span class="s2">"B"</span><span class="p">,</span> <span class="s2">"c"</span> <span class="o">=></span> <span class="s2">"C"</span><span class="p">)</span>
</code></pre>
<p>should be equivalent to:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"blahblah"</span><span class="p">.</span><span class="nf">sub</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span> <span class="p">{</span><span class="s2">"a"</span> <span class="o">=></span> <span class="s2">"A"</span><span class="p">,</span> <span class="s2">"b"</span> <span class="o">=></span> <span class="s2">"B"</span><span class="p">,</span> <span class="s2">"c"</span> <span class="o">=></span> <span class="s2">"C"</span><span class="p">})</span>
</code></pre>
<p>where:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">pattern</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">union</span><span class="p">(</span><span class="o">*</span><span class="p">{</span><span class="s2">"a"</span> <span class="o">=></span> <span class="s2">"A"</span><span class="p">,</span> <span class="s2">"b"</span> <span class="o">=></span> <span class="s2">"B"</span><span class="p">,</span> <span class="s2">"c"</span> <span class="o">=></span> <span class="s2">"C"</span><span class="p">}.</span><span class="nf">keys</span><span class="p">.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">k</span><span class="o">|</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">escape</span><span class="p">(</span><span class="n">k</span><span class="p">)})</span>
</code></pre> Ruby master - Feature #14022 (Rejected): String#surroundhttps://bugs.ruby-lang.org/issues/140222017-10-18T04:38:07Zsawa (Tsuyoshi Sawada)
<p>After joining the elements of an array into a string using <code>Array#join</code>, I frequently need to put substrings before and after the string. In such case, I would have to use either of the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">).</span><span class="nf">prepend</span><span class="p">(</span><span class="s2">"<"</span><span class="p">).</span><span class="nf">concat</span><span class="p">(</span><span class="s2">">"</span><span class="p">)</span> <span class="c1"># => "<1, 2, 3>"</span>
<span class="s2">"<</span><span class="si">#{</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span><span class="si">}</span><span class="s2">>"</span> <span class="c1"># => "<1, 2, 3>"</span>
<span class="s2">"<"</span> <span class="o">+</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">)</span> <span class="o">+</span> <span class="s2">">"</span> <span class="c1"># => "<1, 2, 3>"</span>
</code></pre>
<p>but none of them is concise enough. I wish there were <code>String#surround</code> that works like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">].</span><span class="nf">join</span><span class="p">(</span><span class="s2">", "</span><span class="p">).</span><span class="nf">surround</span><span class="p">(</span><span class="s2">"<"</span><span class="p">,</span> <span class="s2">">"</span><span class="p">)</span> <span class="c1"># => "<1, 2, 3>"</span>
</code></pre> Ruby master - Feature #13807 (Closed): A method to filter the receiver against some conditionhttps://bugs.ruby-lang.org/issues/138072017-08-11T20:38:09Zsawa (Tsuyoshi Sawada)
<p>I frequently see code that uses some value if that value satisfies a certain condition, and something else otherwise.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">some_condition</span> <span class="p">?</span> <span class="n">a</span> <span class="p">:</span> <span class="n">b</span>
</code></pre>
<p>And in most cases, the value of <code>a</code> is non-nil when the condition is satisfied.</p>
<p>I propose to have a method, perhaps named <code>verify</code>, which would implemented to be equivalent to this definition:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">verify</span>
<span class="nb">self</span> <span class="k">if</span> <span class="k">yield</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Then, we can write the expression above (assuming <code>a</code> is non-nil when the condition is satisfied) like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">verify</span><span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="n">a</span><span class="p">.</span><span class="nf">some_condition</span><span class="p">}</span> <span class="o">||</span> <span class="n">b</span>
</code></pre>
<p>Perhaps it would also be useful to do something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">verify</span><span class="p">{</span><span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="n">a</span><span class="p">.</span><span class="nf">some_condition</span><span class="p">}</span><span class="o">&</span><span class="p">.</span><span class="nf">chaining_of_more_methods</span>
</code></pre> Ruby master - Feature #13314 (Open): dig=https://bugs.ruby-lang.org/issues/133142017-03-14T06:38:37Zsawa (Tsuyoshi Sawada)
<p>We have <code>Hash#dig</code>, and when we want to assign a key-value at a deep level, it is tempting to do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">hash</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="ss">:key1</span><span class="p">,</span> <span class="ss">:key2</span><span class="p">,</span> <span class="ss">:key3</span><span class="p">,</span> <span class="ss">:key4</span><span class="p">)</span> <span class="o">=</span> <span class="s2">"value
</span></code></pre>
<p>when we actually needed to do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">hash</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="ss">:key1</span><span class="p">,</span> <span class="ss">:key2</span><span class="p">,</span> <span class="ss">:key3</span><span class="p">)</span><span class="o">&</span><span class="p">.</span><span class="nf">[</span><span class="p">]</span><span class="o">=</span><span class="p">(</span><span class="ss">:key4</span><span class="p">,</span> <span class="s2">"value"</span><span class="p">)</span>
</code></pre>
<p>I propose a method <code>Hash#dig=</code>, which should be equivalent to the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Hash</span>
<span class="k">def</span> <span class="nf">dig</span><span class="o">=</span><span class="p">(</span><span class="o">*</span><span class="n">keys</span><span class="p">,</span> <span class="n">final_key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="n">dig</span><span class="p">(</span><span class="o">*</span><span class="n">keys</span><span class="p">)</span><span class="o">&</span><span class="p">.</span><span class="nf">[</span><span class="p">](</span><span class="n">final_key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #13309 (Rejected): Locale paramter for Integer(), Float(), Rational()https://bugs.ruby-lang.org/issues/133092017-03-13T04:28:16Zsawa (Tsuyoshi Sawada)
<p>Matz' comment to my proposal on <code>Kernel#Boolean()</code> (<a href="https://bugs.ruby-lang.org/issues/13260" class="external">https://bugs.ruby-lang.org/issues/13260</a>) led me to the idea of introducing an optional locale parameter (called under the name <code>allow</code> in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Kernel#Boolean (Rejected)" href="https://bugs.ruby-lang.org/issues/13260">#13260</a>). And now, I think that that idea can be applied generally to the <code>Kernel#Integer</code>, <code>Kernel#Float</code>, and <code>Kernel#Rational</code> methods.</p>
<p>There seems to be constant demand to parse numbers written in different languages, and there is no official clean way to handle the problem. I thought we can let these methods take an optional locale parameter to allow inputs in different languages.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Float</span><span class="p">(</span><span class="s2">"4,294,967,295.0"</span><span class="p">)</span> <span class="c1"># => 4294967295.0 English, by default</span>
<span class="no">Float</span><span class="p">(</span><span class="s2">"4,294,967,295.0"</span><span class="p">,</span> <span class="ss">locale: </span><span class="s2">"en"</span><span class="p">)</span> <span class="c1"># => 4294967295.0</span>
<span class="no">Float</span><span class="p">(</span><span class="s2">"4 294 967.295,0"</span><span class="p">,</span> <span class="ss">locale: </span><span class="s2">"de"</span><span class="p">)</span> <span class="c1"># => 4294967295.0</span>
<span class="no">Float</span><span class="p">(</span><span class="s2">"4 294 967 295,0"</span><span class="p">,</span> <span class="ss">locale: </span><span class="s2">"fr"</span><span class="p">)</span> <span class="c1"># => 4294967295.0</span>
</code></pre>
<p>Cf. <a href="https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html" class="external">https://docs.oracle.com/cd/E19455-01/806-0169/overview-9/index.html</a></p> Ruby master - Feature #13290 (Feedback): A method to use a hash like in a case constructionhttps://bugs.ruby-lang.org/issues/132902017-03-08T06:57:02Zsawa (Tsuyoshi Sawada)
<p>We often want to translate a hash into a case construction and back. For example, suppose we have a case construction like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">key</span>
<span class="k">when</span> <span class="sr">/foo/</span> <span class="k">then</span> <span class="s2">"FOO"</span>
<span class="k">when</span> <span class="sr">/bar/</span> <span class="k">then</span> <span class="s2">"BAR"</span>
<span class="k">else</span> <span class="s2">"DEFAULT"</span>
<span class="k">end</span>
</code></pre>
<p>Given that the keys are ordered within a hash since Ruby 1.9, the information used in the case construction above can be expressed as a hash <code>h</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{</span>
<span class="sr">/foo/</span> <span class="o">=></span> <span class="s2">"FOO"</span>
<span class="sr">/bar/</span> <span class="o">=></span> <span class="s2">"BAR"</span>
<span class="o">...</span>
<span class="p">}</span>
<span class="n">h</span><span class="p">.</span><span class="nf">default</span> <span class="o">=</span> <span class="s2">"DEFAULT"</span>
</code></pre>
<p>At the moment, there is no straightforward way to translate the hash <code>h</code> into the case construction as above. I would like to have a method on <code>Hash</code> that takes a key and works like a case construction (i.e., applies the <code>===</code> method) as below:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span><span class="p">.</span><span class="nf">fetch_as_in_case_construction</span><span class="p">(</span><span class="s2">"barbar"</span><span class="p">)</span> <span class="c1"># => "BAR"</span>
</code></pre>
<p>The name <code>fetch_as_in_case_construction</code> is terrible. Perhaps someone can suggest a better name.</p> Ruby master - Feature #13260 (Rejected): Kernel#Booleanhttps://bugs.ruby-lang.org/issues/132602017-02-28T02:24:48Zsawa (Tsuyoshi Sawada)
<p>I think we have lots of occasions to receive a <code>true</code> or <code>false</code> value as a string input, and want to convert it to <code>true</code> or <code>false</code>. Perhaps we can have a method <code>Kernel#Boolean</code> in a similar spirit to <code>Kernel#Integer</code> and its kins, which takes an optional keyword argument <code>exception</code> (similar to <a href="https://bugs.ruby-lang.org/issues/12732" class="external">https://bugs.ruby-lang.org/issues/12732</a>) and <code>strict</code> (defaulted to true).</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Boolean</span><span class="p">(</span><span class="s2">"true"</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"false"</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">)</span> <span class="c1"># => ArgumentError</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">nil</span><span class="p">)</span> <span class="c1"># => nil</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"1"</span><span class="p">)</span> <span class="c1"># => ArgumentError</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"1"</span><span class="p">,</span> <span class="ss">strict: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"yes"</span><span class="p">,</span> <span class="ss">strict: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"0"</span><span class="p">,</span> <span class="ss">strict: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"no"</span><span class="p">,</span> <span class="ss">strict: </span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => false</span>
<span class="no">Boolean</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="ss">strict: </span><span class="kp">false</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">nil</span><span class="p">)</span> <span class="c1"># => nil</span>
</code></pre> Ruby master - Feature #13259 (Open): Kernel#Datehttps://bugs.ruby-lang.org/issues/132592017-02-28T02:17:56Zsawa (Tsuyoshi Sawada)
<p>I often see a piece of code like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">require</span> <span class="s2">"date"</span>
<span class="k">begin</span>
<span class="no">Date</span><span class="p">.</span><span class="nf">strptime</span><span class="p">(</span><span class="n">some_string</span><span class="p">,</span> <span class="n">some_format</span><span class="p">)</span>
<span class="k">rescue</span>
<span class="kp">nil</span>
<span class="k">end</span>
</code></pre>
<p>Since we now have (<a href="https://bugs.ruby-lang.org/issues/12732" class="external">https://bugs.ruby-lang.org/issues/12732</a>) <code>Kernel#Integer</code> with a parameter to avoid raising an error in case of an invalid string, I think that having a counterpart of it in <code>Date</code> would be convenient. I propose <code>Kernel#Date</code>, which works like <code>Date.strptime</code> except that it takes an optional keyword argument, and works as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Date</span><span class="p">(</span><span class="s2">"2017/02/02"</span><span class="p">,</span> <span class="s2">"%Y/%m/%d"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">nil</span><span class="p">)</span> <span class="c1"># => #<Date: 2017-02-02 ((2457787j,0s,0n),+0s,2299161j)></span>
<span class="no">Date</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="ss">exception: </span><span class="kp">nil</span><span class="p">)</span> <span class="c1"># => nil</span>
</code></pre> Ruby master - Bug #13162 (Rejected): tr does not recognize multi-byte characters correctlyhttps://bugs.ruby-lang.org/issues/131622017-01-27T05:33:47Zsawa (Tsuyoshi Sawada)
<p>This looks as expected:</p>
<pre><code>"\\".tr('\\', '\') # => "\"
</code></pre>
<p>but this doesn't:</p>
<pre><code>"\\".tr("\\¥'", "\¥'") # => "\\"
</code></pre>
<p>I confirmed the strings are UTF-8.</p> Ruby master - Feature #13123 (Closed): NilClass#dighttps://bugs.ruby-lang.org/issues/131232017-01-11T07:07:02Zsawa (Tsuyoshi Sawada)
<p>We now have <code>Hash#dig</code>. We often have a variable that is either a hash or nil but we are not sure which. In such cases, it would be convenient if we can apply <code>dig</code> without conditioning on whether it is a hash or nil.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}</span>
<span class="n">h</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="ss">:a</span><span class="p">)</span> <span class="c1"># => 1</span>
<span class="n">h</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">h</span><span class="p">.</span><span class="nf">dig</span><span class="p">(</span><span class="ss">:a</span><span class="p">)</span> <span class="c1"># => nil</span>
</code></pre> Ruby master - Bug #12345 (Closed): A module's private constants are given with `Module#constant(f...https://bugs.ruby-lang.org/issues/123452016-05-03T22:05:25Zsawa (Tsuyoshi Sawada)
<p>A module's private constants are given with <code>Module#constant(false)</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">A</span>
<span class="no">X</span> <span class="o">=</span> <span class="mi">1</span>
<span class="no">Y</span> <span class="o">=</span> <span class="mi">2</span>
<span class="n">private_constant</span> <span class="ss">:Y</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">B</span>
<span class="no">Z</span> <span class="o">=</span> <span class="mi">3</span>
<span class="no">W</span> <span class="o">=</span> <span class="mi">4</span>
<span class="n">private_constant</span> <span class="ss">:W</span>
<span class="k">end</span>
<span class="no">A</span><span class="p">.</span><span class="nf">constants</span> <span class="c1"># => [:X]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">constants</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => [:X, :Y]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">include</span> <span class="no">B</span>
<span class="no">A</span><span class="p">.</span><span class="nf">constants</span> <span class="c1"># => [:X, :Z]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">constants</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => [:X, :Y]</span>
</code></pre>
<p>Besides this, I request a way to get the private constants of a module. I want:</p>
<pre><code class="ruby syntaxhl" data-language="ruby">
<span class="no">A</span><span class="p">.</span><span class="nf">private_constants</span> <span class="c1"># => [:Y]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">private_constants</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => [:Y]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">include</span> <span class="no">B</span>
<span class="no">A</span><span class="p">.</span><span class="nf">private_constants</span> <span class="c1"># => [:Y, :W]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">private_constants</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span> <span class="c1"># => [:Y]</span>
</code></pre> Ruby master - Bug #12186 (Third Party's Issue): /snapshot/lib/rubygems/installer.rb:233https://bugs.ruby-lang.org/issues/121862016-03-17T09:03:34Zsawa (Tsuyoshi Sawada)
<p>I downloaded the nightly snapshot (<a href="https://cache.ruby-lang.org/pub/ruby/snapshot.tar.gz" class="external">https://cache.ruby-lang.org/pub/ruby/snapshot.tar.gz</a>), and did:</p>
<pre><code>./configure
make
sudo make install
</code></pre>
<p>and got:</p>
<pre><code>.../snapshot/lib/rubygems/installer.rb:233:in `check_executable_overwrite': no implicit conversion of nil into String (TypeError)
</code></pre>
<p>The offending line installer.rb:233 looks like this,</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">question</span> <span class="o"><<</span> <span class="n">existing</span>
</code></pre>
<p>and the values seem to be:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">question</span> <span class="c1"># => "rake's executable \"rake\" conflicts with "</span>
<span class="n">existing</span> <span class="c1"># => nil</span>
</code></pre>
<p>Is this a bug, or is there something wrong with my environment?</p>
<hr>
<p>Also, I am looking forward for Ruby 2.3.1. Is there a place where the schedule for the release of teeny versions are announced? Or is it is not announced until release?</p> Ruby master - Bug #12174 (Rejected): Interpolation ignores `to_s` (and `inspect`) when `to_s` is ...https://bugs.ruby-lang.org/issues/121742016-03-14T17:36:01Zsawa (Tsuyoshi Sawada)
<p>When <code>to_s</code> is defined to return <code>nil</code>, interpolation prints the original inspection.</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="nf">to_s</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="si">}</span><span class="s2">"</span> <span class="c1"># => #<A:0x007f4edf19d720></span>
</code></pre>
<p>It even ignores an overwritten <code>inspect</code> definition.</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="k">class</span> <span class="nc">A</span>
<span class="k">def</span> <span class="nf">to_s</span><span class="p">;</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">inspect</span><span class="p">;</span> <span class="s2">"foo"</span> <span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s2">"</span><span class="si">#{</span><span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="si">}</span><span class="s2">"</span> <span class="c1"># => #<A:0x007f8176c09050></span>
</code></pre> Ruby master - Bug #12128 (Rejected): Strings in `ARGV` are frozenhttps://bugs.ruby-lang.org/issues/121282016-02-29T18:08:15Zsawa (Tsuyoshi Sawada)
<p>It is not clear how the frozen status of strings in <code>ARGV</code> are to be described, but regardless of what I try to do (i.e. set frozen string pragma as false, which is probably irrelevant because the strings are already created at the time of file load), the strings appear frozen. I ran the following file <code>foo.rb</code> as <code>ruby foo.rb bar</code>:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="c1">#!/usr/bin/env ruby</span>
<span class="c1"># frozen_string_literal: false</span>
<span class="no">ARGV</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">frozen?</span> <span class="c1">#=> true</span>
<span class="no">ARGV</span><span class="p">.</span><span class="nf">first</span><span class="p">.</span><span class="nf">upcase!</span> <span class="c1">#=> can't modify frozen String (RuntimeError)</span>
</code></pre>
<p>I believe this is a bug. If not, I would like to know what determines the frozen status of the strings in <code>ARGV</code>. Is it a feature that they are always frozen?</p> Ruby master - Bug #12108 (Rejected): Splitting an empty string returns an empty arrayhttps://bugs.ruby-lang.org/issues/121082016-02-24T15:56:15Zsawa (Tsuyoshi Sawada)
<p>Splitting an empty string returns an empty array.</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="s2">""</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span> <span class="c1"># => []</span>
<span class="s2">""</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s2">"a"</span><span class="p">)</span> <span class="c1"># => []</span>
<span class="s2">""</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="sr">//</span><span class="p">)</span> <span class="c1"># => []</span>
<span class="s2">""</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="sr">/a/</span><span class="p">)</span> <span class="c1"># => []</span>
</code></pre> Ruby master - Bug #12090 (Closed): `Range#cover` does not raise an exception when comparison failshttps://bugs.ruby-lang.org/issues/120902016-02-19T15:37:32Zsawa (Tsuyoshi Sawada)
<p>The documentation for <code>Range#cover?</code> says,</p>
<pre><code>cover?(obj) → true or false
Returns true if obj is between the begin and end of the range.
This tests begin <= obj <= end when exclude_end? is false and begin <= obj < end when exclude_end? is true.
</code></pre>
<p>which implies that, when comparison fails, <code>cover?</code> should raise an error. But actually, it doesn't:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="s2">"a"</span> <span class="o"><=</span> <span class="mi">1</span> <span class="c1"># => ArgumentError: comparison of String with 1 failed</span>
<span class="mi">1</span> <span class="o"><=</span> <span class="s2">"a"</span> <span class="c1"># => ArgumentError: comparison of Fixnum with String failed</span>
<span class="p">(</span><span class="s2">"a"</span><span class="o">..</span><span class="s2">"z"</span><span class="p">).</span><span class="nf">cover?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># => false</span>
</code></pre>
<p>It silently returns <code>false</code> instead of raising an error.</p>
<p>Either <code>Range#cover?</code> should raise an error when comparison fails, or the documentation should be changed to correctly describe this behaviour.</p> Ruby master - Bug #11991 (Closed): `Symbol#match` returns the match position, unlike `String#matc...https://bugs.ruby-lang.org/issues/119912016-01-14T22:20:45Zsawa (Tsuyoshi Sawada)
<p><code>String#match</code> and <code>Regexp#match</code> return a <code>MatchData</code> when match succeeds:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="s2">""</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">//</span><span class="p">)</span> <span class="c1"># => #<MatchData ""></span>
<span class="sr">//</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span> <span class="c1"># => #<MatchData ""></span>
<span class="sr">//</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="ss">:""</span><span class="p">)</span> <span class="c1"># => #<MatchData ""></span>
</code></pre>
<p>But <code>Symbol#match</code> returns the match position (like <code>String#=~</code>):</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="ss">:""</span><span class="p">.</span><span class="nf">match</span><span class="p">(</span><span class="sr">//</span><span class="p">)</span> <span class="c1"># => 0</span>
</code></pre>
<p>Thus, <code>Symbol#match</code> behaves differently from <code>String#match</code> and <code>Regexp#match</code>. This is the documented behavior, but it may be a bug (together with the documentation).</p>
<p>On the other hand, if it is not a bug, what is the rationale?</p> Ruby master - Bug #11878 (Rejected): Comparison of prepended moduleshttps://bugs.ruby-lang.org/issues/118782015-12-26T14:44:08Zsawa (Tsuyoshi Sawada)
<p>Including module <code>B</code> to class/module <code>A</code> gives the following results (as expected):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">A</span><span class="p">;</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">B</span><span class="p">;</span> <span class="k">end</span>
<span class="no">A</span><span class="p">.</span><span class="nf">include</span> <span class="no">B</span>
<span class="no">A</span> <span class="o"><</span> <span class="no">B</span> <span class="c1"># => true</span>
<span class="no">B</span> <span class="o"><</span> <span class="no">A</span> <span class="c1"># => false</span>
<span class="no">A</span> <span class="o"><=></span> <span class="no">B</span> <span class="c1"># => -1</span>
</code></pre>
<p>And prepending module <code>C</code> to <code>A</code> gives the following results:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">C</span><span class="p">;</span> <span class="k">end</span>
<span class="no">A</span><span class="p">.</span><span class="nf">prepend</span> <span class="no">C</span>
<span class="no">A</span> <span class="o"><</span> <span class="no">C</span> <span class="c1"># => true</span>
<span class="no">C</span> <span class="o"><</span> <span class="no">A</span> <span class="c1"># => nil</span>
<span class="no">A</span> <span class="o"><=></span> <span class="no">C</span> <span class="c1"># => -1</span>
</code></pre>
<p>It looks like including and prepending almost do not make difference with respect to module comparison, i.e., <code>A < B</code> and <code>A < C</code> are the same, and <code>A <=> B</code> and <code>A <=> C</code> are the same. However, then, the difference between <code>B < A</code> and <code>C < A</code> stands out unexplained. I suppose this is a bug. If <code>C < A</code> were to return <code>false</code>, then it would be at least consistent.</p>
<p>However, if that was what was intended, then at least to me, it is strange. In that case, I would like to make this a feature request. I would rather expect:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span> <span class="o"><</span> <span class="no">C</span> <span class="c1"># => false</span>
<span class="no">C</span> <span class="o"><</span> <span class="no">A</span> <span class="c1"># => true</span>
<span class="no">A</span> <span class="o"><=></span> <span class="no">C</span> <span class="c1"># => 1</span>
</code></pre> Ruby master - Bug #11871 (Closed): Heredoc unindentation with <<~ with single-quoted identifier f...https://bugs.ruby-lang.org/issues/118712015-12-25T16:20:10Zsawa (Tsuyoshi Sawada)
<p>Heredoc unindentation with <code><<~</code> works as expected when the identifier is bare or double-quoted:</p>
<pre><code>s = <<~_
fiwfewifjf
iofwejfweifwe
fjiofwejfweiof f
fiwejfweof
_
puts s
</code></pre>
<p>or</p>
<pre><code>s = <<~"_"
fiwfewifjf
iofwejfweifwe
fjiofwejfweiof f
fiwejfweof
_
puts s
</code></pre>
<p>Output:</p>
<pre><code>fiwfewifjf
iofwejfweifwe
fjiofwejfweiof f
fiwejfweof
</code></pre>
<p>But with a single-quoted identifier, the content is flushed left:</p>
<pre><code>s = <<~'_'
fiwfewifjf
iofwejfweifwe
fjiofwejfweiof f
fiwejfweof
_
puts s
</code></pre>
<p>Output:</p>
<pre><code>fiwfewifjf
iofwejfweifwe
fjiofwejfweiof f
fiwejfweof
</code></pre> Ruby master - Bug #11861 (Closed): `zip` with `&symbol` causes segmentation errorhttps://bugs.ruby-lang.org/issues/118612015-12-22T11:33:59Zsawa (Tsuyoshi Sawada)
<p>This code (<code>:foo</code> can be replaced with a different method, defined or not defined):</p>
<pre><code>[].zip([], &:foo)
</code></pre>
<p>causes a segmentation error:</p>
<pre><code>(irb):1: [BUG] Segmentation fault at 0x00000000e1112c
ruby 2.3.0preview2 (2015-12-11 trunk 53028) [x86_64-linux]
-- Control frame information -----------------------------------------------
c:0019 p:---- s:0076 e:000075 CFUNC :zip
c:0018 p:0012 s:0072 e:000071 EVAL (irb):1 [FINISH]
c:0017 p:---- s:0070 e:000069 CFUNC :eval
c:0016 p:0025 s:0063 e:000062 METHOD /usr/local/lib/ruby/2.3.0/irb/workspace.rb:86
c:0015 p:0027 s:0056 e:000054 METHOD /usr/local/lib/ruby/2.3.0/irb/context.rb:379
c:0014 p:0024 s:0050 e:000049 BLOCK /usr/local/lib/ruby/2.3.0/irb.rb:488
c:0013 p:0041 s:0042 e:000041 METHOD /usr/local/lib/ruby/2.3.0/irb.rb:622
c:0012 p:0011 s:0037 e:000036 BLOCK /usr/local/lib/ruby/2.3.0/irb.rb:485
c:0011 p:0128 s:0033 e:000032 BLOCK /usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:245 [FINISH]
c:0010 p:---- s:0030 e:000029 CFUNC :loop
c:0009 p:0009 s:0027 e:000026 BLOCK /usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:231 [FINISH]
c:0008 p:---- s:0025 e:000024 CFUNC :catch
c:0007 p:0018 s:0021 e:000020 METHOD /usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:230
c:0006 p:0037 s:0018 E:000570 METHOD /usr/local/lib/ruby/2.3.0/irb.rb:484
c:0005 p:0009 s:0015 e:000014 BLOCK /usr/local/lib/ruby/2.3.0/irb.rb:394 [FINISH]
c:0004 p:---- s:0013 e:000012 CFUNC :catch
c:0003 p:0177 s:0009 E:002630 METHOD /usr/local/lib/ruby/2.3.0/irb.rb:393
c:0002 p:0023 s:0004 E:000960 EVAL /usr/local/bin/irb:11 [FINISH]
c:0001 p:0000 s:0002 E:002480 (none) [FINISH]
-- Ruby level backtrace information ----------------------------------------
/usr/local/bin/irb:11:in `<main>'
/usr/local/lib/ruby/2.3.0/irb.rb:393:in `start'
/usr/local/lib/ruby/2.3.0/irb.rb:393:in `catch'
/usr/local/lib/ruby/2.3.0/irb.rb:394:in `block in start'
/usr/local/lib/ruby/2.3.0/irb.rb:484:in `eval_input'
/usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:230:in `each_top_level_statement'
/usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:230:in `catch'
/usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:231:in `block in each_top_level_statement'
/usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:231:in `loop'
/usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb:245:in `block (2 levels) in each_top_level_statement'
/usr/local/lib/ruby/2.3.0/irb.rb:485:in `block in eval_input'
/usr/local/lib/ruby/2.3.0/irb.rb:622:in `signal_status'
/usr/local/lib/ruby/2.3.0/irb.rb:488:in `block (2 levels) in eval_input'
/usr/local/lib/ruby/2.3.0/irb/context.rb:379:in `evaluate'
/usr/local/lib/ruby/2.3.0/irb/workspace.rb:86:in `evaluate'
/usr/local/lib/ruby/2.3.0/irb/workspace.rb:86:in `eval'
(irb):1:in `irb_binding'
(irb):1:in `zip'
-- Machine register context ------------------------------------------------
RIP: 0x00007f4f42c9eb09 RBP: 0x00007fff37becf50 RSP: 0x00007fff37bece90
RAX: 0x0000000000000000 RBX: 0x00007f4f4312ebb0 RCX: 0x00000000ffffffff
RDX: 0x0000000000e1110c RDI: 0x00007f4f4312eb50 RSI: 0x0000000000002007
R8: 0x00007f4f4438a960 R9: 0x00007f4f44325a00 R10: 0x00000000ffffffff
R11: 0x00007f4f4312ebb3 R12: 0x0000000000000000 R13: 0x0000000000000001
R14: 0x00007f4f4302f260 R15: 0x00007f4f4302f258 EFL: 0x0000000000010206
-- C level backtrace information -------------------------------------------
/usr/local/bin/ruby(rb_vm_bugreport+0x51f) [0x7f4f42e83d5f] vm_dump.c:688
/usr/local/bin/ruby(rb_bug_context+0xd0) [0x7f4f42e5fca0] error.c:423
/usr/local/bin/ruby(sigsegv+0x3e) [0x7f4f42d5c9ee] signal.c:890
/lib/x86_64-linux-gnu/libpthread.so.0 [0x7f4f4283b340]
/usr/local/bin/ruby(rb_block_arity+0x59) [0x7f4f42c9eb09] proc.c:958
/usr/local/bin/ruby(rb_ary_zip+0x176) [0x7f4f42e17326] array.c:3333
/usr/local/bin/ruby(vm_call_cfunc+0xf6) [0x7f4f42dddc96] vm_insnhelper.c:1709
/usr/local/bin/ruby(vm_call_method+0xe3) [0x7f4f42deaf23] vm_insnhelper.c:2241
/usr/local/bin/ruby(vm_exec_core+0x2026) [0x7f4f42de5786] insns.def:964
/usr/local/bin/ruby(vm_exec+0x81) [0x7f4f42de9361] vm.c:1637
/usr/local/bin/ruby(eval_string_with_cref+0x38c) [0x7f4f42dec63c] vm_eval.c:1359
/usr/local/bin/ruby(rb_f_eval+0x7f) [0x7f4f42decb0f] vm_eval.c:1398
/usr/local/bin/ruby(vm_call_cfunc+0xf6) [0x7f4f42dddc96] vm_insnhelper.c:1709
/usr/local/bin/ruby(vm_call_method+0xe3) [0x7f4f42deaf23] vm_insnhelper.c:2241
/usr/local/bin/ruby(vm_exec_core+0x20f9) [0x7f4f42de5859] insns.def:995
/usr/local/bin/ruby(vm_exec+0x81) [0x7f4f42de9361] vm.c:1637
/usr/local/bin/ruby(loop_i+0x14f) [0x7f4f42dec01f] vm.c:961
/usr/local/bin/ruby(rb_rescue2+0xc9) [0x7f4f42c97669] eval.c:799
/usr/local/bin/ruby(vm_call_cfunc+0xf6) [0x7f4f42dddc96] vm_insnhelper.c:1709
/usr/local/bin/ruby(vm_call_method+0xe3) [0x7f4f42deaf23] vm_insnhelper.c:2241
/usr/local/bin/ruby(vm_exec_core+0x2026) [0x7f4f42de5786] insns.def:964
/usr/local/bin/ruby(vm_exec+0x81) [0x7f4f42de9361] vm.c:1637
/usr/local/bin/ruby(catch_i+0x177) [0x7f4f42debd07] vm.c:961
/usr/local/bin/ruby(rb_catch_protect+0xaf) [0x7f4f42de061f] vm_eval.c:2013
/usr/local/bin/ruby(rb_f_catch+0x31) [0x7f4f42de07b1] vm_eval.c:1992
/usr/local/bin/ruby(vm_call_cfunc+0xf6) [0x7f4f42dddc96] vm_insnhelper.c:1709
/usr/local/bin/ruby(vm_call_method+0xe3) [0x7f4f42deaf23] vm_insnhelper.c:2241
/usr/local/bin/ruby(vm_exec_core+0x2026) [0x7f4f42de5786] insns.def:964
/usr/local/bin/ruby(vm_exec+0x81) [0x7f4f42de9361] vm.c:1637
/usr/local/bin/ruby(catch_i+0x177) [0x7f4f42debd07] vm.c:961
/usr/local/bin/ruby(rb_catch_protect+0xaf) [0x7f4f42de061f] vm_eval.c:2013
/usr/local/bin/ruby(rb_f_catch+0x31) [0x7f4f42de07b1] vm_eval.c:1992
/usr/local/bin/ruby(vm_call_cfunc+0xf6) [0x7f4f42dddc96] vm_insnhelper.c:1709
/usr/local/bin/ruby(vm_call_method+0xe3) [0x7f4f42deaf23] vm_insnhelper.c:2241
/usr/local/bin/ruby(vm_exec_core+0x2026) [0x7f4f42de5786] insns.def:964
/usr/local/bin/ruby(vm_exec+0x81) [0x7f4f42de9361] vm.c:1637
/usr/local/bin/ruby(ruby_exec_internal+0xc4) [0x7f4f42c930e4] eval.c:244
/usr/local/bin/ruby(ruby_run_node+0x2d) [0x7f4f42c96c4d] eval.c:309
/usr/local/bin/ruby(main+0x4b) [0x7f4f42c92d4b] addr2line.c:179
-- Other runtime information -----------------------------------------------
* Loaded script: irb
* Loaded features:
0 enumerator.so
1 thread.rb
2 rational.so
3 complex.so
4 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/encdb.so
5 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/trans/transdb.so
6 /usr/local/lib/ruby/2.3.0/unicode_normalize.rb
7 /usr/local/lib/ruby/2.3.0/x86_64-linux/rbconfig.rb
8 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/compatibility.rb
9 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/defaults.rb
10 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/deprecate.rb
11 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/errors.rb
12 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/version.rb
13 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/requirement.rb
14 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/platform.rb
15 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/basic_specification.rb
16 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/stub_specification.rb
17 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/util/list.rb
18 /usr/local/lib/ruby/2.3.0/x86_64-linux/stringio.so
19 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb
20 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/exceptions.rb
21 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_gem.rb
22 /usr/local/lib/ruby/2.3.0/monitor.rb
23 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb
24 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems.rb
25 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/path_support.rb
26 /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/dependency.rb
27 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/version.rb
28 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/core_ext/name_error.rb
29 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/levenshtein.rb
30 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/jaro_winkler.rb
31 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/spell_checkable.rb
32 /usr/local/lib/ruby/2.3.0/delegate.rb
33 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
34 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
35 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/spell_checkers/name_error_checkers.rb
36 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/spell_checkers/method_name_checker.rb
37 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/spell_checkers/null_checker.rb
38 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean/formatter.rb
39 /usr/local/lib/ruby/gems/2.3.0/gems/did_you_mean-1.0.0.rc1/lib/did_you_mean.rb
40 /usr/local/lib/ruby/2.3.0/e2mmap.rb
41 /usr/local/lib/ruby/2.3.0/irb/init.rb
42 /usr/local/lib/ruby/2.3.0/irb/workspace.rb
43 /usr/local/lib/ruby/2.3.0/irb/inspector.rb
44 /usr/local/lib/ruby/2.3.0/irb/context.rb
45 /usr/local/lib/ruby/2.3.0/irb/extend-command.rb
46 /usr/local/lib/ruby/2.3.0/irb/output-method.rb
47 /usr/local/lib/ruby/2.3.0/irb/notifier.rb
48 /usr/local/lib/ruby/2.3.0/irb/slex.rb
49 /usr/local/lib/ruby/2.3.0/irb/ruby-token.rb
50 /usr/local/lib/ruby/2.3.0/irb/ruby-lex.rb
51 /usr/local/lib/ruby/2.3.0/irb/src_encoding.rb
52 /usr/local/lib/ruby/2.3.0/irb/magic-file.rb
53 /usr/local/lib/ruby/2.3.0/x86_64-linux/readline.so
54 /usr/local/lib/ruby/2.3.0/irb/input-method.rb
55 /usr/local/lib/ruby/2.3.0/irb/locale.rb
56 /usr/local/lib/ruby/2.3.0/irb.rb
* Process memory map:
7f4f3f744000-7f4f405c3000 r--s 00000000 08:03 1441793 /usr/local/bin/ruby
7f4f405c3000-7f4f405d9000 r-xp 00000000 08:03 3014702 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4f405d9000-7f4f407d8000 ---p 00016000 08:03 3014702 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4f407d8000-7f4f407d9000 rw-p 00015000 08:03 3014702 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f4f407d9000-7f4f407fe000 r-xp 00000000 08:03 3015032 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f4f407fe000-7f4f409fd000 ---p 00025000 08:03 3015032 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f4f409fd000-7f4f40a01000 r--p 00024000 08:03 3015032 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f4f40a01000-7f4f40a02000 rw-p 00028000 08:03 3015032 /lib/x86_64-linux-gnu/libtinfo.so.5.9
7f4f40a02000-7f4f40a3f000 r-xp 00000000 08:03 3014923 /lib/x86_64-linux-gnu/libreadline.so.6.3
7f4f40a3f000-7f4f40c3f000 ---p 0003d000 08:03 3014923 /lib/x86_64-linux-gnu/libreadline.so.6.3
7f4f40c3f000-7f4f40c41000 r--p 0003d000 08:03 3014923 /lib/x86_64-linux-gnu/libreadline.so.6.3
7f4f40c41000-7f4f40c47000 rw-p 0003f000 08:03 3014923 /lib/x86_64-linux-gnu/libreadline.so.6.3
7f4f40c47000-7f4f40c48000 rw-p 00000000 00:00 0
7f4f40c48000-7f4f40c4f000 r-xp 00000000 08:03 1628302 /usr/local/lib/ruby/2.3.0/x86_64-linux/readline.so
7f4f40c4f000-7f4f40e4f000 ---p 00007000 08:03 1628302 /usr/local/lib/ruby/2.3.0/x86_64-linux/readline.so
7f4f40e4f000-7f4f40e50000 r--p 00007000 08:03 1628302 /usr/local/lib/ruby/2.3.0/x86_64-linux/readline.so
7f4f40e50000-7f4f40e51000 rw-p 00008000 08:03 1628302 /usr/local/lib/ruby/2.3.0/x86_64-linux/readline.so
7f4f40e51000-7f4f40e58000 r-xp 00000000 08:03 1628305 /usr/local/lib/ruby/2.3.0/x86_64-linux/stringio.so
7f4f40e58000-7f4f41058000 ---p 00007000 08:03 1628305 /usr/local/lib/ruby/2.3.0/x86_64-linux/stringio.so
7f4f41058000-7f4f41059000 r--p 00007000 08:03 1628305 /usr/local/lib/ruby/2.3.0/x86_64-linux/stringio.so
7f4f41059000-7f4f4105a000 rw-p 00008000 08:03 1628305 /usr/local/lib/ruby/2.3.0/x86_64-linux/stringio.so
7f4f4105a000-7f4f4105c000 r-xp 00000000 08:03 1755447 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/trans/transdb.so
7f4f4105c000-7f4f4125c000 ---p 00002000 08:03 1755447 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/trans/transdb.so
7f4f4125c000-7f4f4125d000 r--p 00002000 08:03 1755447 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/trans/transdb.so
7f4f4125d000-7f4f4125e000 rw-p 00003000 08:03 1755447 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/trans/transdb.so
7f4f4125e000-7f4f41260000 r-xp 00000000 08:03 1755438 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/encdb.so
7f4f41260000-7f4f4145f000 ---p 00002000 08:03 1755438 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/encdb.so
7f4f4145f000-7f4f41460000 r--p 00001000 08:03 1755438 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/encdb.so
7f4f41460000-7f4f41461000 rw-p 00002000 08:03 1755438 /usr/local/lib/ruby/2.3.0/x86_64-linux/enc/encdb.so
7f4f41461000-7f4f41d23000 r--p 00000000 08:03 1183304 /usr/lib/locale/locale-archive
7f4f41d23000-7f4f41ede000 r-xp 00000000 08:03 3034899 /lib/x86_64-linux-gnu/libc-2.19.so
7f4f41ede000-7f4f420dd000 ---p 001bb000 08:03 3034899 /lib/x86_64-linux-gnu/libc-2.19.so
7f4f420dd000-7f4f420e1000 r--p 001ba000 08:03 3034899 /lib/x86_64-linux-gnu/libc-2.19.so
7f4f420e1000-7f4f420e3000 rw-p 001be000 08:03 3034899 /lib/x86_64-linux-gnu/libc-2.19.so
7f4f420e3000-7f4f420e8000 rw-p 00000000 00:00 0
7f4f420e8000-7f4f421ed000 r-xp 00000000 08:03 3014710 /lib/x86_64-linux-gnu/libm-2.19.so
7f4f421ed000-7f4f423ec000 ---p 00105000 08:03 3014710 /lib/x86_64-linux-gnu/libm-2.19.so
7f4f423ec000-7f4f423ed000 r--p 00104000 08:03 3014710 /lib/x86_64-linux-gnu/libm-2.19.so
7f4f423ed000-7f4f423ee000 rw-p 00105000 08:03 3014710 /lib/x86_64-linux-gnu/libm-2.19.so
7f4f423ee000-7f4f423f7000 r-xp 00000000 08:03 3014789 /lib/x86_64-linux-gnu/libcrypt-2.19.so
7f4f423f7000-7f4f425f7000 ---p 00009000 08:03 3014789 /lib/x86_64-linux-gnu/libcrypt-2.19.so
7f4f425f7000-7f4f425f8000 r--p 00009000 08:03 3014789 /lib/x86_64-linux-gnu/libcrypt-2.19.so
7f4f425f8000-7f4f425f9000 rw-p 0000a000 08:03 3014789 /lib/x86_64-linux-gnu/libcrypt-2.19.so
7f4f425f9000-7f4f42627000 rw-p 00000000 00:00 0
7f4f42627000-7f4f4262a000 r-xp 00000000 08:03 3014763 /lib/x86_64-linux-gnu/libdl-2.19.so
7f4f4262a000-7f4f42829000 ---p 00003000 08:03 3014763 /lib/x86_64-linux-gnu/libdl-2.19.so
7f4f42829000-7f4f4282a000 r--p 00002000 08:03 3014763 /lib/x86_64-linux-gnu/libdl-2.19.so
7f4f4282a000-7f4f4282b000 rw-p 00003000 08:03 3014763 /lib/x86_64-linux-gnu/libdl-2.19.so
7f4f4282b000-7f4f42844000 r-xp 00000000 08:03 3034900 /lib/x86_64-linux-gnu/libpthread-2.19.so
7f4f42844000-7f4f42a43000 ---p 00019000 08:03 3034900 /lib/x86_64-linux-gnu/libpthread-2.19.so
7f4f42a43000-7f4f42a44000 r--p 00018000 08:03 3034900 /lib/x86_64-linux-gnu/libpthread-2.19.so
7f4f42a44000-7f4f42a45000 rw-p 00019000 08:03 3034900 /lib/x86_64-linux-gnu/libpthread-2.19.so
7f4f42a45000-7f4f42a49000 rw-p 00000000 00:00 0
7f4f42a49000-7f4f42a6c000 r-xp 00000000 08:03 3015621 /lib/x86_64-linux-gnu/ld-2.19.so
7f4f42aa9000-7f4f42c6b000 r--s 00000000 08:03 3034899 /lib/x86_64-linux-gnu/libc-2.19.so
7f4f42c6b000-7f4f42c6c000 r--p 00022000 08:03 3015621 /lib/x86_64-linux-gnu/ld-2.19.so
7f4f42c6c000-7f4f42c6d000 rw-p 00023000 08:03 3015621 /lib/x86_64-linux-gnu/ld-2.19.so
7f4f42c6d000-7f4f42c6e000 rw-p 00000000 00:00 0
7f4f42c6e000-7f4f42f55000 r-xp 00000000 08:03 1441793 /usr/local/bin/ruby
7f4f42f65000-7f4f4300c000 r--s 00000000 08:03 1198073 /usr/lib/debug/lib/x86_64-linux-gnu/libpthread-2.19.so
7f4f4300c000-7f4f4302f000 r--s 00000000 08:03 3034900 /lib/x86_64-linux-gnu/libpthread-2.19.so
7f4f4302f000-7f4f43134000 rw-p 00000000 00:00 0
7f4f43144000-7f4f43147000 rw-p 00000000 00:00 0
7f4f43147000-7f4f4314e000 r--s 00000000 08:03 1457857 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
7f4f4314e000-7f4f4314f000 ---p 00000000 00:00 0
7f4f4314f000-7f4f43154000 rw-p 00000000 00:00 0 [stack:7161]
7f4f43154000-7f4f43159000 r--p 002e6000 08:03 1441793 /usr/local/bin/ruby
7f4f43159000-7f4f4315a000 rw-p 002eb000 08:03 1441793 /usr/local/bin/ruby
7f4f4315a000-7f4f4316c000 rw-p 00000000 00:00 0
7f4f44324000-7f4f44856000 rw-p 00000000 00:00 0 [heap]
7fff373a2000-7fff37bf1000 rw-p 00000000 00:00 0
7fff37bf4000-7fff37bf6000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
</code></pre> Ruby master - Bug #11860 (Closed): Double splat does not work on empty hash assigned via variablehttps://bugs.ruby-lang.org/issues/118602015-12-22T08:33:54Zsawa (Tsuyoshi Sawada)
<p>When an empty hash is given as a literal, the double splat operates on it, and leaves nothing, which is expected.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">String</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span>
<span class="p">[</span><span class="o">**</span><span class="p">{}]</span> <span class="c1"># => []</span>
<span class="s2">"foo"</span><span class="p">.</span><span class="nf">foo</span><span class="p">(</span><span class="o">**</span><span class="p">{})</span> <span class="c1"># => nil</span>
<span class="s2">"foo"</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="o">**</span><span class="p">{})</span> <span class="c1"># => nil</span>
</code></pre>
<p>However, when an empty hash is given via variable, the double splat retains an empty hash in place.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{}</span>
<span class="p">[</span><span class="o">**</span><span class="n">h</span><span class="p">]</span> <span class="c1"># => [{}]</span>
<span class="s2">"foo"</span><span class="p">.</span><span class="nf">foo</span><span class="p">(</span><span class="o">**</span><span class="n">h</span><span class="p">)</span> <span class="c1"># => wrong number of arguments (given 1, expected 0)</span>
<span class="s2">"foo"</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">,</span> <span class="o">**</span><span class="n">h</span><span class="p">)</span> <span class="c1"># => wrong number of arguments (given 1, expected 0)</span>
</code></pre> Ruby master - Bug #11805 (Closed): Cannot run Rubyhttps://bugs.ruby-lang.org/issues/118052015-12-11T10:24:09Zsawa (Tsuyoshi Sawada)
<p>I installed the new Ruby, and tried to run Ruby, but it raises the following error.</p>
<p>(Since I installed Ruby 2.3.0preview1, it had a bug, and I had not been able to run Ruby, and now, after having waited for a month, I installed the new one, and there still is a bug. Disappointed a little bit.)</p>
<pre><code>/usr/local/lib/ruby/site_ruby/2.3.0/rubygems/stub_specification.rb:112:in `initialize': Permission denied @ rb_sysopen - /usr/local/lib/ruby/gems/2.3.0/specifications/did_you_mean-1.0.0.beta3.gemspec (Errno::EACCES)
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/stub_specification.rb:112:in `open'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/stub_specification.rb:112:in `data'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/stub_specification.rb:203:in `valid?'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:748:in `select'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:748:in `gemspec_stubs_in'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:773:in `block in map_stubs'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:770:in `each'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:770:in `flat_map'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:770:in `map_stubs'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:762:in `installed_stubs'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:830:in `stubs'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/specification.rb:1035:in `find_by_path'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems.rb:188:in `try_activate'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:124:in `rescue in require'
from /usr/local/lib/ruby/site_ruby/2.3.0/rubygems/core_ext/kernel_require.rb:39:in `require'
from <internal:gem_prelude>:6:in `<internal:gem_prelude>'
</code></pre> Ruby master - Bug #11691 (Closed): Permission denied @ rb_sysopen did_you_mean-1.0.0.beta3.gemspechttps://bugs.ruby-lang.org/issues/116912015-11-15T16:47:07Zsawa (Tsuyoshi Sawada)
<p>When I ruby Ruby, I get this error:</p>
<pre><code>/usr/local/lib/ruby/2.3.0/rubygems/stub_specification.rb:80:in `initialize': Permission denied @ rb_sysopen - /usr/local/lib/ruby/gems/2.3.0/specifications/did_you_mean-1.0.0.beta3.gemspec (Errno::EACCES)
from /usr/local/lib/ruby/2.3.0/rubygems/stub_specification.rb:80:in `open'
from /usr/local/lib/ruby/2.3.0/rubygems/stub_specification.rb:80:in `data'
from /usr/local/lib/ruby/2.3.0/rubygems/stub_specification.rb:186:in `valid?'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:749:in `select'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:749:in `gemspec_stubs_in'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:755:in `block in map_stubs'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:755:in `each'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:755:in `flat_map'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:755:in `map_stubs'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:806:in `stubs'
from /usr/local/lib/ruby/2.3.0/rubygems/specification.rb:1009:in `find_by_path'
from /usr/local/lib/ruby/2.3.0/rubygems.rb:188:in `try_activate'
from /usr/local/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:126:in `rescue in require'
from /usr/local/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:39:in `require'
from <internal:gem_prelude>:4:in `<compiled>'
</code></pre> Ruby master - Bug #11471 (Closed): min, min_by, max, max_by with optional parameter return a wron...https://bugs.ruby-lang.org/issues/114712015-08-20T17:51:06Zsawa (Tsuyoshi Sawada)
<p>This is reported in StackOverflow: <a href="http://stackoverflow.com/questions/32121749/why-20-13-14-min2-13-20" class="external">http://stackoverflow.com/questions/32121749/why-20-13-14-min2-13-20</a>. Sometimes <code>min</code>, <code>min_by</code>, <code>max</code>, <code>max_by</code> with an optional parameter return a wrong value.</p>
<pre><code>[20, 32, 32, 21, 30, 25, 29, 13, 14].min(2) # => [13, 20]
[20, 32, 32, 21, 30, 25, 29, 13, 14].min_by(2, &:itself) # => [13, 20]
[0, 0, 0, 0, 0, 0, 1, 3, 2].max(2) # => [3, 1]
[0, 0, 0, 0, 0, 0, 1, 3, 2].max_by(2, &:itself) # => [3, 1]
</code></pre> Ruby master - Bug #10845 (Closed): Subclassing Stringhttps://bugs.ruby-lang.org/issues/108452015-02-10T23:41:25Zsawa (Tsuyoshi Sawada)
<p>If I make a subclass of <code>String</code>, the method <code>*</code> returns an instance of that class.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">MyString</span> <span class="o"><</span> <span class="no">String</span>
<span class="k">end</span>
<span class="no">MyString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">).</span><span class="nf">*</span><span class="p">(</span><span class="mi">2</span><span class="p">).</span><span class="nf">class</span> <span class="c1">#=> MyString</span>
</code></pre>
<p>This is different from other similar operations like <code>+</code> and <code>%</code>, which return a <code>String</code> instance.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">MyString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"foo"</span><span class="p">).</span><span class="nf">+</span><span class="p">(</span><span class="s2">"bar"</span><span class="p">).</span><span class="nf">class</span> <span class="c1">#=> String</span>
<span class="no">MyString</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">"%{foo}"</span><span class="p">).</span><span class="nf">%</span><span class="p">(</span><span class="ss">foo: </span><span class="s2">"bar"</span><span class="p">).</span><span class="nf">class</span> <span class="c1">#=> String</span>
</code></pre>
<p>I don't see clear reason why <code>*</code> is to be different from <code>+</code> and <code>%</code>, and thought that perhaps either the behaviour with <code>*</code> is a bug, or the behaviour with <code>+</code> and <code>%</code> is a bug.</p>
<p>Or, is a reason why they are different?</p> Ruby master - Bug #10422 (Closed): RDoc for BasicObject has methods that do not existhttps://bugs.ruby-lang.org/issues/104222014-10-23T07:44:37Zsawa (Tsuyoshi Sawada)
<p>RDoc for BasicObject (<a href="http://www.ruby-doc.org/core-2.1.3/BasicObject.html" class="external">http://www.ruby-doc.org/core-2.1.3/BasicObject.html</a>) has descriptions for methods <code>object_id</code> and <code>send</code>, which do not exist. Also, <code>send</code> and <code>__send__</code> are listed twice.</p> Ruby master - Bug #10260 (Third Party's Issue): Cannot install "thin" gemhttps://bugs.ruby-lang.org/issues/102602014-09-18T18:39:19Zsawa (Tsuyoshi Sawada)
<p>When I try to install "thin" gem, I get the following error:</p>
<pre><code>$ sudo gem install thin
Building native extensions. This could take a while...
ERROR: Error installing thin:
ERROR: Failed to build gem native extension.
/usr/local/bin/ruby -r ./siteconf20140919-24244-x0j5an.rb extconf.rb
checking for rb_trap_immediate in ruby.h,rubysig.h... no
checking for rb_thread_blocking_region()... no
checking for inotify_init() in sys/inotify.h... yes
checking for writev() in sys/uio.h... yes
checking for rb_wait_for_single_fd()... yes
checking for rb_enable_interrupt()... no
checking for rb_time_new()... yes
checking for sys/event.h... no
checking for epoll_create() in sys/epoll.h... yes
creating Makefile
make "DESTDIR=" clean
make "DESTDIR="
compiling binder.cpp
compiling kb.cpp
compiling ssl.cpp
compiling rubymain.cpp
compiling ed.cpp
compiling cmain.cpp
compiling pipe.cpp
compiling em.cpp
em.cpp: In member function ‘void EventMachine_t::_RunEpollOnce()’:
em.cpp:574:37: error: ‘rb_thread_select’ was not declared in this scope
EmSelect (0, NULL, NULL, NULL, &tv);
^
em.cpp: In member function ‘int SelectData_t::_Select()’:
em.cpp:827:67: error: ‘rb_thread_select’ was not declared in this scope
return EmSelect (maxsocket+1, &fdreads, &fdwrites, &fderrors, &tv);
^
em.cpp: In member function ‘void EventMachine_t::_RunSelectOnce()’:
em.cpp:946:40: error: ‘rb_thread_select’ was not declared in this scope
EmSelect (0, NULL, NULL, NULL, &tv);
^
make: *** [em.o] Error 1
make failed, exit code 2
Gem files will remain installed in /usr/local/lib/ruby/gems/2.2.0/gems/eventmachine-1.0.3 for inspection.
Results logged to /usr/local/lib/ruby/gems/2.2.0/extensions/x86_64-linux/2.2.0-static/eventmachine-1.0.3/gem_make.out
</code></pre>
<p>I didn't have this problem with previous version of Ruby.</p> Ruby master - Bug #10184 (Closed): irb terminates with no method errorhttps://bugs.ruby-lang.org/issues/101842014-08-29T16:33:54Zsawa (Tsuyoshi Sawada)
<p>When I input the following lines in irb, the irb terminates.</p>
<pre><code>$ irb
irb(main):001:0> def !; end
=> :!
irb(main):002:0> !
/usr/local/lib/ruby/2.1.0/irb/input-method.rb:153:in `gets': private method `!' called for false:FalseClass (NoMethodError)
...
$
</code></pre>
<p>A corresponding question is posted on StackOverflow at <a href="http://stackoverflow.com/questions/25572126/irb-terminates-with-no-method-error/25572313#25572313" class="external">http://stackoverflow.com/questions/25572126/irb-terminates-with-no-method-error/25572313#25572313</a>.</p> Ruby master - Bug #10049 (Closed): RDoc bug for time formathttps://bugs.ruby-lang.org/issues/100492014-07-16T20:26:06Zsawa (Tsuyoshi Sawada)
<p>A bug report <a href="https://bugs.ruby-lang.org/issues/8941" class="external">https://bugs.ruby-lang.org/issues/8941</a> notes a contradiction between RDoc and Ruby behavior. If tadayoshi funaba is correct and <code>%Y</code> should be able to accept digits less than four, then the following RDoc description is a bug, and should be corrected.</p>
<pre><code>%Y - Year with century (can be negative, 4 digits at least)
</code></pre> Ruby master - Bug #9900 (Closed): Segmentation fault with recursive reference of a hashhttps://bugs.ruby-lang.org/issues/99002014-06-04T04:10:47Zsawa (Tsuyoshi Sawada)
<p>The following code raises a segmentation fault.</p>
<pre><code>Hash.new{|h,k| h[k]}[:foo]
# => [BUG] Segmentation fault at 0x007fff5f3fff80
</code></pre>
<p>This bug was found on stackoverflow <a href="http://stackoverflow.com/questions/24028557/irb-crash-segmentation-bug-and-ruby-syntax-clarification" class="external">http://stackoverflow.com/questions/24028557/irb-crash-segmentation-bug-and-ruby-syntax-clarification</a></p> Ruby master - Bug #9883 (Closed): Different behaviour between `==` and hash key lookup regarding ...https://bugs.ruby-lang.org/issues/98832014-05-30T04:06:14Zsawa (Tsuyoshi Sawada)
<p>This question is reported in stackoverflow (<a href="http://stackoverflow.com/questions/23946127" class="external">http://stackoverflow.com/questions/23946127</a>). When a multibyte character is split by <code>slice</code>, <code>==</code> ignores the split fragment of the character, while key lookup on hash does not:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">s1</span> <span class="o">=</span> <span class="s2">"’xxxxxxxxxxxxxxxxxxxxxxxx"</span><span class="p">.</span><span class="nf">slice</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">24</span><span class="p">)</span>
<span class="n">s2</span> <span class="o">=</span> <span class="s2">"xxxxxxxxxxxxxxxxxxxxxxxx"</span>
<span class="n">s1</span> <span class="o">==</span> <span class="n">s2</span> <span class="c1"># => true</span>
<span class="p">{</span><span class="n">s2</span><span class="o">=></span><span class="s2">""</span><span class="p">}.</span><span class="nf">key?</span><span class="p">(</span><span class="n">s1</span><span class="p">)</span> <span class="c1"># => false</span>
</code></pre>
<p>This is inconsistent, and I believe either of the above two is a bug. If it is not a bug, but intended, then it is misleading, and I propose the feature should be changed.</p> Ruby master - Bug #9873 (Closed): YAML conversion of empty symbolhttps://bugs.ruby-lang.org/issues/98732014-05-28T15:26:59Zsawa (Tsuyoshi Sawada)
<p>The yaml gem changes the empty symbol into a string of a colon:</p>
<pre><code>require "yaml"
:"".to_yaml # => "--- ! ':'\n"
</code></pre>
<p>So, the following round trip fails to maintain the original:</p>
<pre><code>YAML.load(:"".to_yaml) # => ":"
</code></pre> Ruby master - Bug #9728 (Closed): Regexp bughttps://bugs.ruby-lang.org/issues/97282014-04-11T06:41:13Zsawa (Tsuyoshi Sawada)
<p>As reported in StackOverflow (<a href="http://stackoverflow.com/questions/23004527" class="external">http://stackoverflow.com/questions/23004527</a>) (with a wrong expectation), the following regex pattern with the <code>*</code> operator does not match.</p>
<pre><code>"ab" =~ /(?!^a).*b/
# => nil
</code></pre>
<p>When <code>?</code> is used instead, it seems to match correctly:</p>
<pre><code>"ab" =~ /(?!^a).?b/
# => 1
</code></pre>
<p>According to the original reporter of the linked site, this does not happen in Ruby 1.9.3.</p> Ruby master - Bug #9701 (Closed): RDoc description for `String#<<` and `String#concat`https://bugs.ruby-lang.org/issues/97012014-04-04T04:52:41Zsawa (Tsuyoshi Sawada)
<p>As far as I can see, <code>String#<<</code> is an alias of <code>String#concat</code>, but in the RDoc, there is no mentioning of the connection between them. <code>String#<<</code> should be simply described as an alias of <code>String#concat</code>.</p> Ruby master - Bug #9581 (Closed): `=~` defined on a subclass of `String` is sometimes ignored, an...https://bugs.ruby-lang.org/issues/95812014-02-28T21:21:32Zsawa (Tsuyoshi Sawada)
<p>As is reported on StackOverflow (<a href="http://stackoverflow.com/questions/22103018" class="external">http://stackoverflow.com/questions/22103018</a>) by Gabriel, overridden <code>=~</code> on a subclass of <code>String</code> is sometimes ignored, and the original <code>String#=~</code> is called. Particularly, when we have:</p>
<pre><code>class MyString < String
def =~ re; :foo end
end
s = MyString.new("abc")
</code></pre>
<p>these give the correct result:</p>
<pre><code>r = /abc/; s =~ r # => :foo
s.send(:=~, r) # => :foo
s.send(:=~, /abc/) # => :foo
</code></pre>
<p>but in this case, <code>MyString#=~</code> is ignored, and <code>String#=~</code> is called instead:</p>
<pre><code>s =~ /abc/ # => 0
</code></pre> Ruby master - Bug #9295 (Closed): `Exception#backtrace_locations` returns `nil`https://bugs.ruby-lang.org/issues/92952013-12-25T04:32:13Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
If I raise an <code>ArgumentError</code> by calling a method with wrong number of arguments, <code>Exception#backtrace_locations</code> returns <code>nil</code>, which I think is a bug:</p>
<pre><code>def foo; end
begin
foo(:bar)
rescue => e
p e.backtrace_locations
end
# => nil
</code></pre>
<p>If, instead, I raise an error manually, then it returns an array as expected:</p>
<pre><code>begin
raise ArgumentError.new
rescue => e
p e.backtrace_locations
end
# => ["this_file:2:in `<main>'"]
</code></pre>
<p>=end</p> Ruby master - Bug #9077 (Closed): RDoc typographical errorhttps://bugs.ruby-lang.org/issues/90772013-11-05T02:50:05Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
There is a typographical error in <a href="http://www.ruby-doc.org/core-2.0.0/_lib/racc/rdoc/grammar_en_rdoc.html#label-Operator+Precedance" class="external">http://www.ruby-doc.org/core-2.0.0/_lib/racc/rdoc/grammar_en_rdoc.html#label-Operator+Precedance</a>.</p>
<pre><code>Operator Precedance => Operator Precedence
</code></pre>
<p>=end</p> Ruby master - Bug #8885 (Rejected): Incorrect time is created for time including leap secondshttps://bugs.ruby-lang.org/issues/88852013-09-10T16:13:11Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
<code>Time.new</code> creates incorrect time when the time includes a leap second.</p>
<pre><code>Time.new(2012, 6, 30, 23, 59, 60)
# => 2012-07-01 00:00:00 +0900 # Wrong. Should be 2012-06-30 23:59:60 +0900
Time.new(2012, 6, 30, 23, 59, 60) == Time.new(2012, 7, 1, 0, 0, 0)
# => true # Wrong. Should be `false`.
</code></pre>
<p>=end</p> Ruby master - Bug #8766 (Closed): RDoc documentation bug: Symbol literalhttps://bugs.ruby-lang.org/issues/87662013-08-10T23:04:22Zsawa (Tsuyoshi Sawada)
<p>RDoc page <a href="http://www.ruby-doc.org/core-2.0/doc/syntax/literals_rdoc.html#label-Symbols" class="external">http://www.ruby-doc.org/core-2.0/doc/syntax/literals_rdoc.html#label-Symbols</a> has a description and an example:</p>
<pre><code>Like strings, a single-quote may be used to disable interpolation:
:"my_symbol#{1 + 1}" #=> :"my_symbol\#{1 + 1}"
</code></pre>
<p>Whereas the text mentions single quote, the example has double quotes.</p> Ruby master - Bug #8607 (Closed): Stack consistency error (sp: 16, bp: 17)https://bugs.ruby-lang.org/issues/86072013-07-08T00:01:32Zsawa (Tsuyoshi Sawada)
<p>The following code:</p>
<pre><code>class A
attr_accessor :foo
end
class B
def initialize(parent)
@parent = parent
end
def method_missing(method, *args, &block)
@parent.send(method)
end
end
B.new(A.new).foo = :bar
</code></pre>
<p>returns:</p>
<pre><code>[BUG] Stack consistency error (sp: 16, bp: 17)
</code></pre>
<p>It has been reported on Stackoverflow (<a href="http://stackoverflow.com/questions/17513074/ruby-2-0-throws-bug-stack-consistency-error" class="external">http://stackoverflow.com/questions/17513074/ruby-2-0-throws-bug-stack-consistency-error</a>) by NicoSantangelo.</p> Ruby master - Bug #7803 (Closed): RDoc documentation: `Array#&` clarificationhttps://bugs.ruby-lang.org/issues/78032013-02-08T15:38:57Zsawa (Tsuyoshi Sawada)
<p>In the RDoc documentation for <code>Array#&</code>, it does not mention whether the order of the elements in the returned array preserves the order in the receiver. There is a question raised regarding this point in stackoverflow:</p>
<pre><code>http://stackoverflow.com/questions/14764135/is-order-preserved-in-arrays-when-intersection-is-done
</code></pre>
<p>and it mentions that that is included in the test for RubySpec</p>
<pre><code>https://github.com/rubyspec/rubyspec/blob/master/core/array/intersection_spec.rb#L16
</code></pre>
<p>so it looks like that is taken for granted, but it is not guaranteed. If it is indeed a feature, then that should be written in the document. If not, (meaning the order might not be preserved in a future implementation), then that should also be mentioned in the document as a warning. The documentation for <code>Array#-</code> makes that point clear:</p>
<pre><code>Array Difference---Returns a new array that is a copy of the original array, removing any items that ...
</code></pre>
<p>so, perhaps the docmentation for <code>Array#&</code> should be written along the same line.</p> Ruby master - Bug #7571 (Closed): RDoc documentation bug in Regexp#===https://bugs.ruby-lang.org/issues/75712012-12-16T10:55:54Zsawa (Tsuyoshi Sawada)
<p>RDoc documentation for `Regexp#===' says:</p>
<pre><code>Case Equality—Synonym for Regexp#=~ used in case statements.
</code></pre>
<p>but it is not a synonym for <code>Regexp#=~' as </code>Regexp#===' returns <code>true' or </code>false' and <code>Regexp#=~' return an integer or </code>nil`.</p> Ruby master - Bug #7190 (Closed): warning: already initialized constant の書式https://bugs.ruby-lang.org/issues/71902012-10-20T11:00:58Zsawa (Tsuyoshi Sawada)
<p>未定義の定数を参照した場合のエラーメッセージでは名前空間がすべて表示されます:</p>
<pre><code>module A; B; end
#=> NameError: uninitialized constant A::B
A::B
#=> NameError: uninitialized constant A::B
</code></pre>
<p>しかし、既に定義してある定数を再定義した場合の警告メッセージでは名前空間が表示されません:</p>
<pre><code>module A; B = :foo end
module A; B = :bar end
#=> warning: already initialized constant B
A::B = :baz
#=> warning: already initialized constant B
</code></pre>
<p>後者の場合も前者の場合にならって名前空間を表示した方がよいと思います。</p>
<pre><code>warning: already initialized constant A::B
</code></pre>
<p>メタプログラミングで、$stderr = StringIO.new のように警告メッセージをリダイレクトしてコード内で定数の再定義を捕捉したい場合に、名前空間なしでは問題になっている定数を再現できません。</p> Ruby master - Bug #4781 (Closed): Engrish in comment in Regexp#=~https://bugs.ruby-lang.org/issues/47812011-05-26T01:02:09Zsawa (Tsuyoshi Sawada)
<p>I see the following grammatical mistakes in ruby-doc, probably reflecting the comments in the source:</p>
<p>Regexp#=~</p>
<p>wrong: The assignment is not occur if the regexp is not a literal.<br>
correct: The assignment does not occur if the regexp is not a literal.</p>
<p>wrong: The assignment is not occur if the regexp is placed at right hand side.<br>
correct: The assignment does not occur if the regexp is placed at the right hand side.</p>