Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112023-04-14T12:47:47ZRuby Issue Tracking System
Redmine 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 - Misc #19111 (Closed): Issues with "feedback" status are tagged as "closedhttps://bugs.ruby-lang.org/issues/191112022-11-08T04:15:18Zsawa (Tsuyoshi Sawada)
<p>I see that the issues under the status "feedback" are tagged as "closed" in the title and in the list. Is this a bug or an intended setting? <a href="https://www.redmineup.com/pages/help/redmine/set-issue-statuses#:~:text=Predefined%20Issue%20statuses%20in%20Redmine,means%20%E2%80%9Copen%E2%80%9D%20issues%20category." class="external">Redmine's document</a> says (bold face mine):</p>
<blockquote>
<p>Predefined Issue statuses in Redmine are New, In progress, Resolved, Feedback, Closed, and Rejected. Statuses marked for Issue closed belong to “closed” issues category; <strong>any other status means “open” issues category</strong>.</p>
</blockquote> 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 #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 #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 #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 - 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 #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 - 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 #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 #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 - Misc #15654 (Open): Documentation for Complex is wrong or misleadinghttps://bugs.ruby-lang.org/issues/156542019-03-11T08:43:36Zsawa (Tsuyoshi Sawada)
<p>The documentation for <code>Complex</code> <a href="https://ruby-doc.org/core-2.6/Complex.html" class="external">https://ruby-doc.org/core-2.6/Complex.html</a> says or implies that a complex can be created by literal like <code>2+1i</code>, but that is actually calling the method <code>+</code> on receiver <code>2</code> with argument <code>1i</code>. The description should be changed to make it clear that <code>2+ 1i</code> is not a literal but is applying a method.</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 #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 #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 #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 - 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 - Feature #12648 (Open): `Enumerable#sort_by` with descending optionhttps://bugs.ruby-lang.org/issues/126482016-08-02T09:57:26Zsawa (Tsuyoshi Sawada)
<p>I would like to pass an optional argument to <code>Enumerable#sort_by</code> or <code>Enumerable#sort_by!</code> to allow descending sort. When the sort key is singular, this could be done by passing a single optinal boolean variable that represents ascending when <code>false</code> (default) and descending when <code>true</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">3</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="nf">sort_by</span><span class="p">(</span><span class="o">&</span><span class="ss">:itself</span><span class="p">)</span> <span class="c1"># => [1, 2, 3]</span>
<span class="p">[</span><span class="mi">3</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="nf">sort_by</span><span class="p">(</span><span class="kp">false</span><span class="p">,</span> <span class="o">&</span><span class="ss">:itself</span><span class="p">)</span> <span class="c1"># => [1, 2, 3]</span>
<span class="p">[</span><span class="mi">3</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="nf">sort_by</span><span class="p">(</span><span class="kp">true</span><span class="p">,</span> <span class="o">&</span><span class="ss">:itself</span><span class="p">)</span> <span class="c1"># => [3, 2, 1]</span>
</code></pre>
<p>When there are multiple sort keys, corresponding numbers of arguments should be passed:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">3</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">0</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="n">e</span> <span class="o">%</span> <span class="mi">2</span><span class="p">,</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [0, 2, 1, 3]</span>
<span class="p">[</span><span class="mi">3</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">0</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">(</span><span class="kp">false</span><span class="p">,</span> <span class="kp">false</span><span class="p">){</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="n">e</span> <span class="o">%</span> <span class="mi">2</span><span class="p">,</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [0, 2, 1, 3]</span>
<span class="p">[</span><span class="mi">3</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">0</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">(</span><span class="kp">false</span><span class="p">,</span> <span class="kp">true</span><span class="p">){</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="n">e</span> <span class="o">%</span> <span class="mi">2</span><span class="p">,</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [2, 0, 3, 1]</span>
<span class="p">[</span><span class="mi">3</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">0</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">(</span><span class="kp">true</span><span class="p">,</span> <span class="kp">false</span><span class="p">){</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="n">e</span> <span class="o">%</span> <span class="mi">2</span><span class="p">,</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [1, 3, 0, 2]</span>
<span class="p">[</span><span class="mi">3</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">0</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">(</span><span class="kp">true</span><span class="p">,</span> <span class="kp">true</span><span class="p">){</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="n">e</span> <span class="o">%</span> <span class="mi">2</span><span class="p">,</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [3, 1, 2, 0]</span>
</code></pre> Ruby master - Feature #12523 (Open): `Object#values_at`https://bugs.ruby-lang.org/issues/125232016-06-27T14:59:57Zsawa (Tsuyoshi Sawada)
<p>It might be convenient to have a method that returns multiple attributes of an object.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="n">attr_accessors</span> <span class="ss">:foo</span><span class="p">,</span> <span class="ss">:bar</span><span class="p">,</span> <span class="ss">:baz</span>
<span class="k">def</span> <span class="nf">initialize</span> <span class="n">foo</span><span class="p">,</span> <span class="n">bar</span><span class="p">,</span> <span class="n">baz</span><span class="p">;</span> <span class="vi">@foo</span><span class="p">,</span> <span class="vi">@bar</span><span class="p">,</span> <span class="vi">@baz</span> <span class="o">=</span> <span class="n">foo</span><span class="p">,</span> <span class="n">bar</span><span class="p">,</span> <span class="n">baz</span> <span class="k">end</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="p">(</span><span class="s2">"a"</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">a</span><span class="p">.</span><span class="nf">values_at</span><span class="p">(</span><span class="ss">:baz</span><span class="p">,</span> <span class="ss">:foo</span><span class="p">)</span> <span class="c1"># => ["c", "a"]</span>
</code></pre> Ruby master - Feature #12380 (Open): `Struct` as a subclass of `Class`https://bugs.ruby-lang.org/issues/123802016-05-14T06:22:27Zsawa (Tsuyoshi Sawada)
<p>This issue is somewhat of the same flavor as <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: SingletonClass (Closed)" href="https://bugs.ruby-lang.org/issues/12374">#12374</a>.</p>
<p><code>Struct</code> has a constructor that creates a class:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:foo</span><span class="p">)</span>
<span class="c1"># => #<Class:0x007f605f892cb0></span>
</code></pre>
<p>and this is the same situation with <code>Class</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Class</span><span class="p">.</span><span class="nf">new</span>
<span class="c1"># => #<Class:0x007f605f70c788></span>
</code></pre>
<p>Hence, most naturally, <code>Struct</code> should be a subclass of <code>Class</code>. But in reality, it isn't:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Struct</span><span class="p">.</span><span class="nf">ancestors</span>
<span class="c1"># => [Struct, Enumerable, Object, Kernel, BasicObject]</span>
</code></pre>
<p>The current structure around <code>Struct</code> is counter-intuitive to me.</p>
<p>I propose that either <code>Struct</code> should be redefined as a subclass of <code>Class</code>, or a new class <code>StructClass</code> should be introduced as a subclass of <code>Class</code>, and take over the functionality of <code>Struct</code>.</p> Ruby master - Feature #12374 (Closed): SingletonClasshttps://bugs.ruby-lang.org/issues/123742016-05-12T18:28:21Zsawa (Tsuyoshi Sawada)
<p>I propose to have a class <code>SingletonClass</code>, a subclass of the class <code>Class</code>, to which all singleton classes belong. It should be the owner of all the properties that are specific to singleton classes. Also, the methods defined on <code>Singleton</code> module should be moved to this class.</p>
<p>Reasons are as follows:</p>
<ol>
<li>
<p>I was thinking that the reason <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: `Class#instance` (Closed)" href="https://bugs.ruby-lang.org/issues/12084">#12084</a> hasn't been seen positively may be because the developers do not want to define a method only on limited instances of a class. If we have <code>SingletonClass</code>, the method <code>#instance</code> proposed in <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: `Class#instance` (Closed)" href="https://bugs.ruby-lang.org/issues/12084">#12084</a> could be defined as an instance method of <code>SingletonClass</code>.</p>
</li>
<li>
<p>The way to introduce the singleton pattern using the <code>Singleton</code> module (<a href="http://ruby-doc.org/stdlib-2.3.0/libdoc/singleton/rdoc/Singleton.html" class="external">http://ruby-doc.org/stdlib-2.3.0/libdoc/singleton/rdoc/Singleton.html</a>):</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span>
<span class="kp">include</span> <span class="no">Singleton</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</code></pre>
<p>is a bit unnatural and verbose. If we have <code>SingletonClass</code>, then we can define a singleton class more naturally:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span> <span class="o">=</span> <span class="no">SingletonClass</span><span class="p">.</span><span class="nf">new</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 - Feature #12333 (Closed): `String#concat`, `Array#concat`, `String#prepend` to take ...https://bugs.ruby-lang.org/issues/123332016-04-30T12:25:13Zsawa (Tsuyoshi Sawada)
<p>I would like <code>String#concat</code>, <code>Array#concat</code>, <code>String#prepend</code> to take multiple arguments</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">s</span> <span class="o">=</span> <span class="s2">""</span>
<span class="n">s</span><span class="p">.</span><span class="nf">concat</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="s2">"c"</span><span class="p">)</span>
<span class="n">a</span><span class="p">.</span><span class="nf">prepend</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="s2">"C"</span><span class="p">)</span>
<span class="n">s</span> <span class="c1"># => "ABCabc"</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">concat</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">a</span> <span class="c1"># => ["a", "b", "c"]</span>
</code></pre> Ruby master - Feature #12319 (Open): `Module#const_get` does not accept symbol with nested namehttps://bugs.ruby-lang.org/issues/123192016-04-26T01:25:39Zsawa (Tsuyoshi Sawada)
<p><code>Module#const_get</code> accepts non-nested string, nested string, and non-nested symbol:</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">C</span> <span class="k">end</span> <span class="k">end</span> <span class="k">end</span>
<span class="no">A</span><span class="p">.</span><span class="nf">const_get</span><span class="p">(</span><span class="s2">"B"</span><span class="p">)</span> <span class="c1"># => A::B</span>
<span class="no">A</span><span class="p">.</span><span class="nf">const_get</span><span class="p">(</span><span class="s2">"B::C"</span><span class="p">)</span> <span class="c1"># => A::B::C</span>
<span class="no">A</span><span class="p">.</span><span class="nf">const_get</span><span class="p">(</span><span class="ss">:B</span><span class="p">)</span> <span class="c1"># => A::B</span>
</code></pre>
<p>but does not accept nested symbol:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span><span class="p">.</span><span class="nf">const_get</span><span class="p">(</span><span class="ss">:"B::C"</span><span class="p">)</span> <span class="c1"># => NameError: wrong constant name B::C</span>
</code></pre>
<p>I would like this to be made possible.</p> Ruby master - Feature #12318 (Closed): Returning the evaluated value of a blockhttps://bugs.ruby-lang.org/issues/123182016-04-26T00:53:05Zsawa (Tsuyoshi Sawada)
<p>I often achieve an element using an iterator with a block, and then apply the same/a similar block to the element I get. Examples are:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="p">.</span><span class="nf">max_by</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span> <span class="o">%</span> <span class="mi">3</span><span class="p">}</span>
<span class="p">.</span><span class="nf">tap</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="k">break</span> <span class="n">e</span> <span class="o">%</span> <span class="mi">3</span><span class="p">}</span>
<span class="c1"># => 2</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="p">.</span><span class="nf">find</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span><span class="p">[</span><span class="sr">/(.)\1/</span><span class="p">]}</span>
<span class="p">.</span><span class="nf">tap</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="k">break</span> <span class="n">e</span><span class="p">[</span><span class="sr">/(.)\1/</span><span class="p">]}</span>
<span class="c1"># => "oo"</span>
</code></pre>
<p>I would like a method on <code>Enumerator</code> that returns the result of the block rather than the original element in the iterator. Not sure about the name, but if I call it <code>and_return</code> temporary, it should look like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="p">.</span><span class="nf">max_by</span><span class="p">.</span><span class="nf">and_return</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span> <span class="o">%</span> <span class="mi">3</span><span class="p">}</span>
<span class="c1"># => 2</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="p">.</span><span class="nf">find</span><span class="p">.</span><span class="nf">and_return</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span><span class="p">[</span><span class="sr">/(.)\1/</span><span class="p">]}</span>
<span class="c1"># => "oo"</span>
</code></pre> Ruby master - Feature #12317 (Open): Name space of a modulehttps://bugs.ruby-lang.org/issues/123172016-04-26T00:15:58Zsawa (Tsuyoshi Sawada)
<p>I want a method to return the name space of a module, something like:</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">module</span> <span class="nn">B</span><span class="p">;</span> <span class="k">module</span> <span class="nn">C</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">namespace</span> <span class="o">=></span> <span class="p">[</span><span class="no">A</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="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>
</code></pre>
<p>There is <code>nesting</code> method that is similar, but that only returns the lexical nesting information.</p>
<p>There are also some known hacks for this, converting the module to the string representation using <code>to_s</code> or <code>name</code>, and then splitting it by <code>::</code>. But that easily breaks if the module is anonymous, or is a singleton module. I would like a more robust, core method.</p> Ruby master - Feature #12272 (Open): Accepting HTML entity name in string literalhttps://bugs.ruby-lang.org/issues/122722016-04-12T13:00:03Zsawa (Tsuyoshi Sawada)
<p>String literal allows the escape character <code>\u</code> to describe a character using UTF-8 character code like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"</span><span class="se">\u</span><span class="s2">201c"</span> <span class="c1"># left double quote</span>
<span class="s2">"</span><span class="se">\u</span><span class="s2">2191"</span> <span class="c1"># up arrow</span>
</code></pre>
<p>This is useful in typing characters that are not easy to input from the keyboard. However, normal people do not memorize the UTF-8 codes by heart.</p>
<p>The HTML symbol entity name is the place where we can compromise (although it is not available for the entire UTF-8), I think. I would like the string literal to be extended to accept HTML entity names and interpret them as the corresponding UTF-8 characters. I do not have a definite idea for the syntax, but a candidate can be an escape character <code>\& ... ;</code>, so that we can type:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"</span><span class="se">\&</span><span class="s2">ldquo;"</span> <span class="c1"># left double quote</span>
<span class="s2">"</span><span class="se">\&</span><span class="s2">uarr;"</span> <span class="c1"># up arrow</span>
</code></pre>
<p>Currently, <code>"\&"</code> is interpreted as <code>"&"</code>, so this will be a compatibility breaking change, and if that is not desirable, perhaps a different syntax may be considered.</p> Ruby master - Feature #12262 (Open): Anti-loophttps://bugs.ruby-lang.org/issues/122622016-04-08T07:21:19Zsawa (Tsuyoshi Sawada)
<p>The <code>loop</code> method continues by default, and requires the keyword <code>break</code> to escape. This is good when the continuing cases are the norm and the escaping cases are exceptional:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="kp">loop</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">if</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">break</span> <span class="c1"># breaks on exceptional cases</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">else</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>But when the continuing cases are exceptional and the escaping cases are the norm, the construction requires a lot of <code>break</code>, and it becomes cumbersome:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="kp">loop</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">if</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">break</span> <span class="c1"># lot of breaks</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">break</span> <span class="c1"># lot of breaks</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">break</span> <span class="c1"># lot of breaks</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">else</span>
<span class="o">...</span>
<span class="k">break</span> <span class="c1"># lot of breaks</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>I actually see this use case a lot when user input is asked with validation on a command line script.</p>
<p>I request a <code>loop</code>-like method that works in the opposite way to <code>loop</code>, that is, it escapes (i.e., runs only once) by default, and requires a keyword to continue (perhaps <code>next</code>). The second code above would then be written like:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">some_loop_like_method</span> <span class="k">do</span>
<span class="o">...</span>
<span class="k">if</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">elsif</span> <span class="o">...</span>
<span class="o">...</span>
<span class="k">next</span> <span class="c1"># continues on exceptional cases</span>
<span class="k">else</span>
<span class="o">...</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #12173 (Open): `Time#till_now`https://bugs.ruby-lang.org/issues/121732016-03-14T16:57:25Zsawa (Tsuyoshi Sawada)
<p>It is very frequent to have a time instance:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">t</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
</code></pre>
<p>and then after some operations, do:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="n">t</span>
</code></pre>
<p>I propose <code>Time#till_now</code>, which is equivalent to:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="k">class</span> <span class="nc">Time</span>
<span class="k">def</span> <span class="nf">till_now</span><span class="p">;</span> <span class="nb">self</span><span class="p">.</span><span class="nf">class</span><span class="p">.</span><span class="nf">now</span> <span class="o">-</span> <span class="nb">self</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>and similar methods can perhaps be defined on <code>Date</code> and <code>DateTime</code> classes as well. Another candidate for the method name is <code>until_now</code>.</p>
<p>Then we can do:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">t</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="c1"># some heavy operation</span>
<span class="nb">puts</span> <span class="s2">"It took </span><span class="si">#{</span><span class="n">t</span><span class="p">.</span><span class="nf">till_now</span><span class="si">}</span><span class="s2"> secs."</span>
</code></pre> Ruby master - Feature #12145 (Open): Aliashood between `size` and `length` is not consistenthttps://bugs.ruby-lang.org/issues/121452016-03-05T19:12:01Zsawa (Tsuyoshi Sawada)
<p>When <code>size</code> and <code>length</code> have the same implementation, depending on the class, they are either independently defined methods, or the former is an alias of the latter. Particularly for <code>Array</code>:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="p">[].</span><span class="nf">method</span><span class="p">(</span><span class="ss">:size</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :length</span>
<span class="p">[].</span><span class="nf">method</span><span class="p">(</span><span class="ss">:length</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :length</span>
</code></pre>
<p>but for <code>Hash</code>, <code>String</code>, and <code>Symbol</code>:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="p">{}.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:size</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :size</span>
<span class="p">{}.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:length</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :length</span>
<span class="s2">""</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:size</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :size</span>
<span class="s2">""</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:length</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :length</span>
<span class="ss">:""</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:size</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :size</span>
<span class="ss">:""</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:length</span><span class="p">).</span><span class="nf">original_name</span> <span class="c1"># => :length</span>
</code></pre>
<p>This might be a big issue, but since there is a standard Ruby method <code>original_name</code>, which returns different results, whether this being one way or another should matter. And I see no reason why they should behave differently. They should be unified in one way. Perhaps <code>Hash</code>, <code>String</code>, and <code>Symbol</code> should be made in the same way as with <code>Array</code>.</p> Ruby master - Feature #12134 (Open): Comparison between `true` and `false`https://bugs.ruby-lang.org/issues/121342016-03-02T10:56:01Zsawa (Tsuyoshi Sawada)
<p>There are some needs to sort elements depending on whether they satisfy certain condition expressed as a predicate. For example, to place prime numbers before others:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="nb">require</span> <span class="s2">"prime"</span>
<span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="no">Prime</span><span class="p">.</span><span class="nf">prime?</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">?</span> <span class="mi">0</span> <span class="p">:</span> <span class="mi">1</span><span class="p">}</span> <span class="c1"># => [7, 5, 3, 2, 6, 4, 1]</span>
</code></pre>
<p>or to do such sort with the secondary condition to sort by the size:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="no">Prime</span><span class="p">.</span><span class="nf">prime?</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="p">?</span> <span class="mi">0</span> <span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [2, 3, 5, 7, 1, 4, 6]</span>
</code></pre>
<p>Here, the temporal assignment of magic numbers <code>0</code> and <code>1</code> is ad hoc, but ordering between <code>true</code> and <code>false</code> makes sense. And given that there are <code>if</code> construction (which is unmarked case compared to the <code>unless</code> construction) and the ternary operator, in which the truthy branch is placed before the falsy branch, I think it makes sense to assume an inherent ordering of <code>true</code> being placed before <code>false</code>.</p>
<p>So I propose comparison between <code>true</code> and <code>false</code>:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="kp">true</span> <span class="o"><=></span> <span class="kp">false</span> <span class="c1"># => -1</span>
<span class="kp">false</span> <span class="o"><=></span> <span class="kp">true</span> <span class="c1"># => 1</span>
</code></pre>
<p>Using this, the cases above can be written more directly as:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="no">Prime</span><span class="p">.</span><span class="nf">prime?</span><span class="p">(</span><span class="n">e</span><span class="p">)}</span> <span class="c1"># => [7, 5, 3, 2, 6, 4, 1]</span>
<span class="p">[</span><span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nf">sort_by</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="p">[</span><span class="no">Prime</span><span class="p">.</span><span class="nf">prime?</span><span class="p">(</span><span class="n">e</span><span class="p">),</span> <span class="n">e</span><span class="p">]}</span> <span class="c1"># => [2, 3, 5, 7, 1, 4, 6]</span>
</code></pre>
<hr>
<p>Please do not confuse this with the common proposal to map booleans to integers, particularly <code>true.to_i # => 1</code> and <code>false.to_i # => 0</code>. That is arbitrary, and does not make sense. In fact, my proposal goes against such proposal (under the proposal to map booleans, <code>true.to_i <=> false.to_i</code> translates to <code>1 <=> 0 # => 1</code>, which goes against my proposal <code>true <=> false # => 01</code>).</p> Ruby master - Feature #12116 (Open): `Fixnum#divmod`, `Bignum#divmod` with multiple argumentshttps://bugs.ruby-lang.org/issues/121162016-02-26T18:04:45Zsawa (Tsuyoshi Sawada)
<p>Sometimes, I need to apply <code>divmod</code> repeatedly. For example, in order to convert a number expressing seconds into approx year, day, hour, minutes, seconds (approx in the sense of ignoring leap day and leap second), I can repeatedly apply <code>divmod</code>:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">seconds</span> <span class="o">=</span> <span class="mi">289342751</span>
<span class="n">minutes</span><span class="p">,</span> <span class="n">seconds</span> <span class="o">=</span> <span class="n">seconds</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> <span class="c1"># => [4822379, 11]</span>
<span class="n">hours</span><span class="p">,</span> <span class="n">minutes</span> <span class="o">=</span> <span class="n">minutes</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="mi">60</span><span class="p">)</span> <span class="c1"># => [80372, 59]</span>
<span class="n">days</span><span class="p">,</span> <span class="n">hours</span> <span class="o">=</span> <span class="n">hours</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="mi">24</span><span class="p">)</span> <span class="c1"># => [3348, 20]</span>
<span class="n">years</span><span class="p">,</span> <span class="n">days</span> <span class="o">=</span> <span class="n">days</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="mi">365</span><span class="p">)</span> <span class="c1"># => [9, 63]</span>
</code></pre>
<p>so that I get that 289342751 seconds is approx 9 years 63 days 20 hours 59 minutes and 11 seconds. But it is cumbersome to do all that. It would be convenient if <code>divmod</code> can take multiple arguments so that the conventional <code>divmod</code> is applied from the right-most argument to the left, returning the above result at once:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="mi">289342751</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="mi">365</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">60</span><span class="p">,</span> <span class="mi">60</span><span class="p">)</span> <span class="c1"># => [9, 63, 20, 59, 11]</span>
</code></pre>
<p>In general, when <code>n</code> arguments are passed to the proposed <code>divmod</code>, an array of <code>n + 1</code> elements should be returned.</p>
<p>Another use case is nested arrays. Some people tend to express a matrix as a nested array, and try to access the innermost elements using multiple indices. To list the coordinates of the occurrences of <code>1</code>, one may do:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">m</span> <span class="o">=</span> <span class="p">[</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">0</span><span class="p">],</span>
<span class="p">[</span><span class="mi">0</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="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">],</span>
<span class="p">]</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">m</span><span class="p">.</span><span class="nf">each_with_index</span> <span class="k">do</span> <span class="o">|</span><span class="n">row</span><span class="p">,</span> <span class="n">i</span><span class="o">|</span>
<span class="n">row</span><span class="p">.</span><span class="nf">each_with_index</span> <span class="k">do</span> <span class="o">|</span><span class="n">e</span><span class="p">,</span> <span class="n">j</span><span class="o">|</span>
<span class="n">a</span><span class="p">.</span><span class="nf">push</span><span class="p">([</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">])</span> <span class="k">if</span> <span class="n">e</span> <span class="o">==</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">a</span> <span class="c1"># => [[0, 0], [1, 1], [2, 2]]</span>
</code></pre>
<p>But it is often easier to have a flat array and use <code>divmod</code> with it:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">m</span> <span class="o">=</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">0</span><span class="p">,</span>
<span class="mi">0</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">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span>
<span class="p">]</span>
<span class="n">m</span><span class="p">.</span><span class="nf">each</span><span class="p">.</span><span class="nf">with_index</span><span class="p">.</span><span class="nf">select</span><span class="p">{</span><span class="o">|</span><span class="n">e</span><span class="p">,</span> <span class="n">_</span><span class="o">|</span> <span class="n">e</span> <span class="o">==</span> <span class="mi">1</span><span class="p">}.</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">_</span><span class="p">,</span> <span class="n">i</span><span class="o">|</span> <span class="n">i</span><span class="p">.</span><span class="nf">divmod</span><span class="p">(</span><span class="mi">3</span><span class="p">)}</span> <span class="c1"># => [[0, 0], [1, 1], [2, 2]]</span>
</code></pre>
<p>However, once the nesting achieves another level, it becomes cumbersome. Instead of using a nested array:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="n">t</span> <span class="o">=</span> <span class="p">[</span>
<span class="p">[</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="s2">"d"</span><span class="p">],</span>
<span class="p">],</span>
<span class="p">[</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="s2">"d"</span><span class="p">],</span>
<span class="p">],</span>
<span class="p">]</span>
</code></pre>
<p>one can keep using a flat array, but that would require repeated application of <code>divmod</code> to covert between the flat index and the nested index. The proposed feature would also help in such case.</p> Ruby master - Feature #12096 (Closed): New notation for instance variables and class variableshttps://bugs.ruby-lang.org/issues/120962016-02-21T15:09:45Zsawa (Tsuyoshi Sawada)
<p>In order to create symbols that include non-word characters, we have the <code>:'...'</code> notation:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="ss">:'foo-bar'</span>
<span class="ss">:"foo-bar"</span>
</code></pre>
<p>What about extending this notation to instance variables and class variables? The use case is to solve the problems raised in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Allow attr_reader :foo? to define instance method foo? for accessing @foo (Rejected)" href="https://bugs.ruby-lang.org/issues/12046">#12046</a>, <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Allow an attr_ variant for query-methods that end with a question mark '?' character, such as: d... (Rejected)" href="https://bugs.ruby-lang.org/issues/11167">#11167</a>, <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: A proposal for something like: attr_reader :foo? - with the trailing '?' question mark (Rejected)" href="https://bugs.ruby-lang.org/issues/10720">#10720</a>. There, the problem was that, even though we can have methods like <code>foo?</code> or symbols like <code>:foo?</code>, we cannot have corresponding instance variables. My proposal is to introduce a similar notation for instance variables:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="err">@</span><span class="s1">'foo?'</span>
<span class="err">@</span><span class="s2">"foo?"</span>
</code></pre>
<p>I can't think of a similar use case for class variables, but there is no reason to make class variables to behave different from instance variables more than necessary, so there can also be the corresponding notation for class variables:</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="err">@@</span><span class="s1">'foo?'</span>
<span class="err">@@</span><span class="s2">"foo?"</span>
</code></pre>
<p>Right now, these notations raise syntax errors, so I don't think it conflicts (raises ambiguity) with the existing syntax.</p> 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 - Feature #12084 (Closed): `Class#instance`https://bugs.ruby-lang.org/issues/120842016-02-18T09:31:05Zsawa (Tsuyoshi Sawada)
<p>For meta-programming/debugging purposes, I would like to request the inverse of <code>Object#singleton_class</code>. Namely, a method that is called on a class that is a singleton class, and returns the object it is a singleton of. Since the <code>Singleton</code> module in the standard library <a href="http://ruby-doc.org/stdlib-2.3.0/libdoc/singleton/rdoc/Singleton.html" class="external">http://ruby-doc.org/stdlib-2.3.0/libdoc/singleton/rdoc/Singleton.html</a> assigns the method name <code>instance</code> to such classes, I think <code>Class#instance</code> should be the name for such feature.</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="no">Array</span><span class="p">.</span><span class="nf">singleton_class</span><span class="p">.</span><span class="nf">instance</span> <span class="c1"># => Array</span>
<span class="s2">"foo"</span><span class="p">.</span><span class="nf">singleton_class</span><span class="p">.</span><span class="nf">instance</span> <span class="c1"># => "foo"</span>
</code></pre>
<p>When the receiver is a class but is not a singleton class, then it should raise an error.</p>
<pre><code class="RUBY syntaxhl" data-language="RUBY"><span class="no">Array</span><span class="p">.</span><span class="nf">instance</span> <span class="c1"># => error</span>
</code></pre> Ruby master - Feature #12059 (Open): `Array#single?`, `Hash#single?`https://bugs.ruby-lang.org/issues/120592016-02-09T15:37:03Zsawa (Tsuyoshi Sawada)
<p>There are some use cases when one wants to check if an array or a hash has exactly one element. I propose <code>Array#single?</code> and <code>Hash#single?</code> that checks for such cases and returns either <code>true</code> or <code>false</code>. This is an analogy from the <code>empty?</code> method on the respective class.</p>
<ul>
<li>When creating an inflectional form out of an array:</li>
</ul>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"object1"</span><span class="p">,</span> <span class="s2">"object2"</span><span class="p">]</span>
<span class="s2">"There </span><span class="si">#{</span><span class="n">a</span><span class="p">.</span><span class="nf">single</span> <span class="p">?</span> <span class="s2">"is"</span> <span class="p">:</span> <span class="s2">"are"</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">a</span><span class="p">.</span><span class="nf">length</span><span class="si">}</span><span class="s2"> </span><span class="si">#{</span><span class="n">a</span><span class="p">.</span><span class="nf">single?</span> <span class="p">?</span> <span class="s2">"object"</span> <span class="p">:</span> <span class="s2">"objects"</span><span class="si">}</span><span class="s2">."</span>
<span class="c1"># => "There are 2 objects."</span>
</code></pre>
<ul>
<li>When checking if all elements of the array are the same:</li>
</ul>
<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">2</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nf">uniq</span><span class="p">.</span><span class="nf">single?</span> <span class="c1"># => false</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">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">].</span><span class="nf">uniq</span><span class="p">.</span><span class="nf">single?</span> <span class="c1"># => true</span>
</code></pre> 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 - Feature #11951 (Closed): `RubyVM::InstructionSequence.compile` should return the er...https://bugs.ruby-lang.org/issues/119512016-01-05T07:35:55Zsawa (Tsuyoshi Sawada)
<p>When <code>RubyVM::InstructionSequence.compile</code> raises a syntax error, it outputs the syntax error message to <code>$stderr</code>, and then raises a <code>SyntaxError</code> anyway, whose message is simply: <code>"compile error"</code>.</p>
<p>I don't think this is useful. For example, if I want to analyze within Ruby code whether a certain string is syntactically correct Ruby code, I would have to reasign <code>$stderr</code> to something such as <code>StringIO.new</code>, run <code>RubyVM::InstructionSequence.compile</code>, rescue the syntax error, (but instead of reading the error message from the error), read the error message by doing <code>$stderr.string</code>. This is cumbersome.</p>
<p>On the other hand, there is <code>eval</code>, which also can raise a SyntaxError. But with <code>eval</code>, the error message comes out with the raised error, and is useful. I don't see any reason why <code>RubyVM::InstructionSequence.compile</code> should behave differently from <code>eval</code> with respect to returning the error message.</p>
<p>I request <code>RubyVM::InstructionSequence.compile</code> to return the error message as the message on the raised error rather than directly printing it to <code>$stderr</code>.</p> Ruby master - Feature #11939 (Open): Syntax sugar to apply a method replace a variablehttps://bugs.ruby-lang.org/issues/119392016-01-02T13:59:28Zsawa (Tsuyoshi Sawada)
<p>There is frequent use case to modify the value of a variable and keep it referred to by the same variable name. When method chaining cannot be done (for example, when the method is conditionally called), the same variable name would have to be repeated:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">var</span> <span class="o">=</span> <span class="o">...</span>
<span class="n">var</span> <span class="o">=</span> <span class="n">var</span><span class="p">.</span><span class="nf">some_method</span><span class="p">(</span><span class="n">some_args</span><span class="p">)</span> <span class="k">if</span> <span class="n">some_condition</span>
<span class="n">var</span> <span class="o">=</span> <span class="o">...</span>
<span class="o">...</span>
</code></pre>
<p>I would like to propose a syntax sugar for this kind of situation. I have two options in mind.</p>
<p>(1) <code>=.</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">var</span> <span class="o">=</span> <span class="o">...</span>
<span class="n">var</span> <span class="o">=</span><span class="p">.</span><span class="nf">some_method</span><span class="p">(</span><span class="n">some_args</span><span class="p">)</span> <span class="k">if</span> <span class="n">some_condition</span>
<span class="n">var</span> <span class="o">=</span> <span class="o">...</span>
<span class="o">...</span>
</code></pre>
<p>(2) <code>.=</code></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">var</span> <span class="o">=</span> <span class="o">...</span>
<span class="n">var</span> <span class="p">.</span><span class="nf">=</span> <span class="n">some_method</span><span class="p">(</span><span class="n">some_args</span><span class="p">)</span> <span class="k">if</span> <span class="n">some_condition</span>
<span class="n">var</span> <span class="o">=</span> <span class="o">...</span>
<span class="o">...</span>
</code></pre>
<p>Notation (2) seems to be in line with syntax sugar like <code>+=</code>, but option (1) has the advantage that the period comes together with the method name.</p> Ruby master - Feature #11927 (Open): Return value for `Module#include` and `Module#prepend`https://bugs.ruby-lang.org/issues/119272015-12-30T11:40:36Zsawa (Tsuyoshi Sawada)
<p>Currently, <code>Module#include</code> and <code>Module#prepend</code> return the receiver, regardless of whether the ancestor chain has been modified. It is not straightforward to know whether it actually had effect.</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="c1"># => A</span>
<span class="no">A</span><span class="p">.</span><span class="nf">ancestors</span> <span class="c1"># => [A, B]</span>
<span class="no">A</span><span class="p">.</span><span class="nf">prepend</span> <span class="no">B</span> <span class="c1"># => A</span>
<span class="no">A</span><span class="p">.</span><span class="nf">ancestors</span> <span class="c1"># => [A, B]</span>
</code></pre>
<p>I propose that, when <code>Module#include</code> and <code>Module#prepend</code> have no effect, they should either:</p>
<p>(1) return <code>nil</code><br>
(2) return <code>false</code>, or<br>
(3) raise an exception</p>
<p>This is similar to <code>Kernel#require</code>, which returns <code>false</code> when it has no effect. To make it parallel with <code>Kernel#require</code>, it might be even better to return <code>true</code> when <code>Module#include</code> and <code>Module#prepend</code> have effect, and <code>false</code> otherwise. It makes no sense to return the receiver because that is known.</p>
<p>Some relevant cases with expectations are:</p>
<ul>
<li>prepend after include</li>
</ul>
<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="c1"># => A/true</span>
<span class="no">A</span><span class="p">.</span><span class="nf">prepend</span> <span class="no">B</span> <span class="c1"># => nil/false/exception</span>
</code></pre>
<ul>
<li>include after prepend</li>
</ul>
<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">prepend</span> <span class="no">B</span> <span class="c1"># => A/true</span>
<span class="no">A</span><span class="p">.</span><span class="nf">include</span> <span class="no">B</span> <span class="c1"># => nil/false/exception</span>
</code></pre>
<ul>
<li>include/prepend after include/include at superclass</li>
</ul>
<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="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">M</span> <span class="c1"># => A/true</span>
<span class="k">class</span> <span class="nc">B</span> <span class="o"><</span> <span class="no">A</span><span class="p">;</span> <span class="k">end</span>
<span class="no">B</span><span class="p">.</span><span class="nf">include</span> <span class="no">M</span> <span class="c1"># => nil/false/exception</span>
</code></pre> Ruby master - Feature #11879 (Closed): `Module#prepended_modules`https://bugs.ruby-lang.org/issues/118792015-12-26T14:52:58Zsawa (Tsuyoshi Sawada)
<p><code>Module#included_modules</code> include prepended modules:</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">prepend</span> <span class="no">B</span>
<span class="no">A</span><span class="p">.</span><span class="nf">included_modules</span> <span class="c1"># => [B]</span>
</code></pre>
<p>This is confusing, and is not useful. I think prepended modules should not be included in <code>Module#included_modules</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span><span class="p">.</span><span class="nf">included_modules</span> <span class="c1"># => []</span>
</code></pre>
<p>I also propose that prepended modules should be included in a new method <code>Module#prepended_modules</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">A</span><span class="p">.</span><span class="nf">prepended_modules</span> <span class="c1"># => [B]</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 - Feature #11818 (Closed): `Hash#compact`https://bugs.ruby-lang.org/issues/118182015-12-15T05:09:54Zsawa (Tsuyoshi Sawada)
<p>I request <code>Hash#compact</code> and <code>Hash#compact!</code> that remove the key-value pairs whose value is <code>nil</code>, as follows:</p>
<pre><code>h1 = {a:, 1, b: nil, c: 2}
h1.compact # => {a: 1, c: 2}
h1 # => {a: 1, b: nil, c: 2}
h2 = {a:, 1, b: nil, c: 2}
h2.compact! # => {a: 1, c: 2}
h2 # => {a: 1, c: 2}
h3 = {a:, 1, c: 2}
h3.compact! # => nil
h3 # => {a: 1, c: 2}
</code></pre>
<p>I believe people have frequent need to do this.</p> 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 - Feature #11797 (Closed): `Enumerator#with_object` with multiple objectshttps://bugs.ruby-lang.org/issues/117972015-12-09T16:15:51Zsawa (Tsuyoshi Sawada)
<p>Sometimes, when working with <code>Enumerator#with_object</code>, I want to keep some additional temporary objects besides the one to return. A use case is as follows (I got this from this StackOverflow question: <a href="http://stackoverflow.com/questions/3418123" class="external">http://stackoverflow.com/questions/3418123</a>). Suppose I have an enumerator created from an array:</p>
<pre><code>e = ["a", "b", "c", "c", "a", "c"].to_enum
</code></pre>
<p>and want to get an array of its repeated elements in the order they are repeated (i.e., appears for the second time):</p>
<pre><code># => ["c", "a"]
</code></pre>
<p>I can do it using <code>Enumerator#with_object</code> like this:</p>
<pre><code>e.to_enum.with_object([{}, []]){|c, (h, a)| h[c] ? a.push(c) : h.store(c, true)}.last.uniq
</code></pre>
<p>Here, I am getting the array referred to as <code>a</code> in the block, but besides that, I am using a temporal hash <code>h</code>. I thought it would be nice if <code>Enumerator#with_object</code> accepts one or more objects, pass them individually as block arguments, and returns only the last argument so that I can do this:</p>
<pre><code>e.to_enum.with_object({}, []){|c, h, a| h[c] ? a.push(c) : h.store(c, true)}.uniq
</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 - Feature #11568 (Closed): Misleading warning for duplicate keys in a hashhttps://bugs.ruby-lang.org/issues/115682015-10-05T20:41:10Zsawa (Tsuyoshi Sawada)
<p>When a hash literal has duplicate keys as follows,</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span>
<span class="ss">a: </span><span class="s2">"foo"</span><span class="p">,</span>
<span class="ss">a: </span><span class="s2">"bar"</span><span class="p">,</span>
<span class="p">}</span>
</code></pre>
<p>the warning message goes as follows:</p>
<pre><code>warning: duplicated key at line 3 ignored: :a
</code></pre>
<p>This message gives the impression as if it is the value <code>"bar"</code> at line 3 that is ignored, even though in reality it is the value <code>"foo"</code> at line 2 that is ignored. It is misleading. I suggest the message to be changed.</p> 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 - Feature #11309 (Open): Iterator over string matcheshttps://bugs.ruby-lang.org/issues/113092015-06-26T14:55:43Zsawa (Tsuyoshi Sawada)
<p>This was hinted from a problem in stackoverflow (<a href="http://stackoverflow.com/questions/31074050/build-list-of-strings-containing-substrings-separated-by-an-from-a-string/31075511#31075511" class="external">http://stackoverflow.com/questions/31074050/build-list-of-strings-containing-substrings-separated-by-an-from-a-string/31075511#31075511</a>).</p>
<p>Suppose there is a string:</p>
<pre><code>s = "a_b_c_d_e"
</code></pre>
<p>To get an array of pre-matches that result from matching <code>s</code> with <code>"_"</code>, I can do this:</p>
<pre><code>a = []
s.scan("_"){a.push($`)}
a # => ["a", "a_b", "a_b_c", "a_b_c_d"]
</code></pre>
<p>But this looks too Perlish. I thought it would be nice if there is a method on <code>String</code> that creates an enumerator over matches so that I can do something like this:</p>
<pre><code>"a_b_c_d_e".some_method("_").with_object([]){|m, a| a.push(m.post_match)}
# => ["a", "a_b", "a_b_c", "a_b_c_d"]
</code></pre>
<p>where <code>m</code> is the last matchdata instance at that point. I believe such method would have wider application.</p> Ruby master - Feature #11308 (Closed): Optional `include_super=true` parameter for `*method_defin...https://bugs.ruby-lang.org/issues/113082015-06-26T04:47:24Zsawa (Tsuyoshi Sawada)
<p>I request the following methods in the <code>Module</code> class:</p>
<ul>
<li><code>method_defined?</code></li>
<li><code>private_method_defined?</code></li>
<li><code>protected_method_defined?</code></li>
<li><code>public_method_defined?</code></li>
</ul>
<p>to take an optional <code>include_super</code> parameter with the default value <code>true</code>, and work similar to the methods:</p>
<ul>
<li><code>instance_methods</code></li>
<li><code>private_instance_methods</code></li>
<li><code>protected_instance_methods</code></li>
<li>and <code>public_instance_methods</code>
</li>
</ul> 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 - Feature #10797 (Closed): `inherit` parameter for `..._defined?` methods in Modulehttps://bugs.ruby-lang.org/issues/107972015-01-28T22:27:49Zsawa (Tsuyoshi Sawada)
<p><code>Module#const_defined?</code> takes an optional argument <code>inherit</code> with default value <code>true</code> to control whether to consider inheritance. But the following methods do not:</p>
<ul>
<li><code>Module#method_defined?</code></li>
<li><code>Module#private_method_defined?</code></li>
<li><code>Module#protected_method_defined?</code></li>
<li><code>Module#public_method_defined?</code></li>
</ul>
<p>They only allow what would correspond to <code>inherit = true</code>. I request an optional argument <code>inherit</code> with default value <code>true</code> to be added to these methods to control whether inheritance should be considered.</p> Ruby master - Feature #10771 (Closed): An easy way to get the source location of a constanthttps://bugs.ruby-lang.org/issues/107712015-01-22T05:50:18Zsawa (Tsuyoshi Sawada)
<p>For constants, it is difficult to get the source location where it was (last) defined. I request either of the following to be implemented:</p>
<ul>
<li>
<p>Tracepoint emits a signal when a constant is defined.</p>
</li>
<li>
<p>Implement a <code>Constant</code> class (similar to <code>Method</code> class) and a <code>constant</code> method (similar to <code>method</code> method) that behave as follows:</p>
<pre><code> foo1.rb
1| module Foo
2| Bar = :bar
3| end
4| Foo.constant(:Bar) #=> #<Constant: Foo#Bar>
5| Foo.constant(:Bar).source_location #=> ["foo1.rb", 2]
</code></pre>
</li>
<li>
<p>Implement <code>Module#constant_source_location</code></p>
<pre><code> foo2.rb
1| module Foo
2| Bar = :bar
3| end
4| Foo.constant_source_location(:Bar) #=> ["foo2.rb", 2]
</code></pre>
</li>
</ul> Ruby master - Feature #10769 (Closed): Negative counterpart to Enumerable#slice_whenhttps://bugs.ruby-lang.org/issues/107692015-01-22T00:35:57Zsawa (Tsuyoshi Sawada)
<p>It seems to me that most useful cases of <code>Enumerable#slice_when</code> involve a negative condition inside the block. That observation seems to be confirmed by the official examples in <a href="http://docs.ruby-lang.org/ja/2.2.0/method/Enumerable/i/slice_when.html" class="external">http://docs.ruby-lang.org/ja/2.2.0/method/Enumerable/i/slice_when.html</a>. In these examples, the conditions inside the block are negations of what would is intended (which is expressed in the comment above each code).</p>
<pre><code># 1ずつ増加する部分配列ごとに分ける。
[1,2,4,9,10,11,12,15,16,19,20,21]
.slice_when{|i, j| i + 1 != j}.to_a # => [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]
# ソート済の配列を近い値(差が6以内)の部分配列ごとに分ける。
[3, 11, 14, 25, 28, 29, 29, 41, 55, 57]
.slice_when{|i, j| 6 < j - i}.to_a # => [[3], [11, 14], [25, 28, 29, 29], [41], [55, 57]]
# 増加のみの部分配列ごとに分ける。
[0, 9, 2, 2, 3, 2, 7, 5, 9, 5]
.slice_when{|i, j| i > j}.to_a # => [[0, 9], [2, 2, 3], [2, 7], [5, 9], [5]]
# 隣り合う偶数同士、奇数同士の部分配列ごとに分ける。
[7, 5, 9, 2, 0, 7, 9, 4, 2, 0]
.slice_when{|i, j| i.even? != j.even?}.to_a # => [[7, 5, 9], [2, 0], [7, 9], [4, 2, 0]]
</code></pre>
<p>I propose that there should be a method on <code>Enumerable</code> that works like <code>slice_when</code> except that it works with the block negatively as compared to <code>slice_when</code>. Let us call this method <code>Enumerable#chunk_while</code>. Then, the examples above would be written more naturally without having a negative notion in the blocks.</p>
<pre><code># 1ずつ増加する部分配列ごとに分ける。
[1,2,4,9,10,11,12,15,16,19,20,21]
.chunk_while{|i, j| i + 1 == j}.to_a
# ソート済の配列を近い値(差が6以内)の部分配列ごとに分ける。
[3, 11, 14, 25, 28, 29, 29, 41, 55, 57]
.chunk_while{|i, j| j - i <= 6}.to_a
# 増加のみの部分配列ごとに分ける。
[0, 9, 2, 2, 3, 2, 7, 5, 9, 5]
.chunk_while{|i, j| i <= j}.to_a
# 隣り合う偶数同士、奇数同士の部分配列ごとに分ける。
[7, 5, 9, 2, 0, 7, 9, 4, 2, 0]
.chunk_while{|i, j| i.even? == j.even?}.to_a
</code></pre>
<p>I am not sure about the method name. There can be a better name.</p> Ruby master - Feature #10729 (Open): Array method to subtract in placehttps://bugs.ruby-lang.org/issues/107292015-01-10T22:36:02Zsawa (Tsuyoshi Sawada)
<p>I request a method on array that takes another array, subtract that from self in place (= destructively), and return the subtracted elements:</p>
<pre><code>a = [1, 2, 3, 4, 5]
a.some_method([2, 4, 6]) #=> [2, 4]
a #=> [1, 3, 5]
</code></pre>
<p>Ideally, it should also allow a block:</p>
<pre><code>a = [1, 2, 3, 4, 5]
a.some_method(&:even?) #=> [2, 4]
a #=> [1, 3, 5]
</code></pre>
<p>This operation is quite frequent, but at the moment, it requires several steps to do.</p> Ruby master - Feature #10426 (Open): A predicate to express congruencehttps://bugs.ruby-lang.org/issues/104262014-10-26T00:55:20Zsawa (Tsuyoshi Sawada)
<p>I occasionally felt the necessity of a predicate that checks congruence with respect to some operations:</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">equal_by?</span> <span class="n">other</span><span class="p">,</span> <span class="o">&</span><span class="n">pr</span>
<span class="n">pr</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="nb">self</span><span class="p">)</span> <span class="o">==</span> <span class="n">pr</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">alias</span> <span class="n">congruent?</span> <span class="n">equal_by?</span>
<span class="k">end</span>
<span class="mi">5</span><span class="p">.</span><span class="nf">congruent?</span><span class="p">(</span><span class="mi">2</span><span class="p">){</span><span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">e</span> <span class="o">%</span> <span class="mi">3</span><span class="p">}</span> <span class="c1">#=> true</span>
<span class="s2">"HELLO"</span><span class="p">.</span><span class="nf">equal_by?</span><span class="p">(</span><span class="s2">"Hello"</span><span class="p">,</span> <span class="o">&</span><span class="ss">:downcase</span><span class="p">)</span> <span class="c1">#=> true</span>
</code></pre> Ruby master - Feature #10425 (Open): A predicate method to tell if a number is near anotherhttps://bugs.ruby-lang.org/issues/104252014-10-26T00:38:58Zsawa (Tsuyoshi Sawada)
<p>A method <code>near?</code> like the following would be useful.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Numeric</span>
<span class="k">def</span> <span class="nf">near?</span> <span class="n">other</span><span class="p">,</span> <span class="ss">delta: </span><span class="no">Float</span><span class="o">::</span><span class="no">EPSILON</span>
<span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="nf">to_f</span> <span class="o">-</span> <span class="n">to_f</span><span class="p">).</span><span class="nf">abs</span> <span class="o"><=</span> <span class="n">delta</span><span class="p">.</span><span class="nf">to_f</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Time</span>
<span class="k">def</span> <span class="nf">near?</span> <span class="n">other</span><span class="p">,</span> <span class="ss">delta: </span><span class="no">Float</span><span class="o">::</span><span class="no">EPSILON</span>
<span class="n">to_f</span><span class="p">.</span><span class="nf">near?</span><span class="p">(</span><span class="n">other</span><span class="p">.</span><span class="nf">to_f</span><span class="p">,</span> <span class="ss">delta: </span><span class="n">delta</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>It can be used to check errors, or whether something is around something.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mf">23.24324</span><span class="p">.</span><span class="nf">near?</span><span class="p">(</span><span class="mf">23.23</span><span class="p">,</span> <span class="ss">delta: </span><span class="mf">0.5</span><span class="p">)</span> <span class="c1"># => true</span>
<span class="n">t1</span> <span class="o">=</span> <span class="n">t2</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">t3</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span>
<span class="n">t1</span><span class="p">.</span><span class="nf">near?</span><span class="p">(</span><span class="n">t2</span><span class="p">)</span> <span class="c1">#=> true</span>
<span class="n">t1</span><span class="p">.</span><span class="nf">near?</span><span class="p">(</span><span class="n">t3</span><span class="p">)</span> <span class="c1">#=> false</span>
<span class="mi">5</span><span class="p">.</span><span class="nf">near?</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="ss">delta: </span><span class="mi">1</span><span class="p">)</span> <span class="c1">#=> true</span>
</code></pre>
<p>Some testing frameworks have something similar to this, but I think this is an elementary concept that Ruby should support at it core.</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 - Feature #10366 (Open): New inspection form for rationalhttps://bugs.ruby-lang.org/issues/103662014-10-11T00:50:15Zsawa (Tsuyoshi Sawada)
<p>Currently, rational inspection is expressed with parentheses:</p>
<pre><code>(2/51)
</code></pre>
<p>If this were taken as a Ruby expression, it would mean integer division, whose value is <code>0</code> in this case. It does not make much sense to express that it is indeed not integer division and that it is rational by using parentheses. Now that we have rational literal using <code>r</code>, we can make the inspection form as:</p>
<pre><code>2/51r
</code></pre>
<p>This would be much less confusing.</p> Ruby master - Feature #10332 (Open): Rational literal for mixed fractionshttps://bugs.ruby-lang.org/issues/103322014-10-06T14:55:48Zsawa (Tsuyoshi Sawada)
<p>Current behavior of rational literal and <code>String#to_r</code> does not recognize mixed fractions. Mixed fraction is not rare, and is frequently used in places such as US length measurement.</p>
<p><img src="http://www.strongtie.com/graphics/anchorsystems/catalog/tables/217b-2012.gif" alt="drill bits"></p>
<p>I propose that rational literal and <code>String#to_r</code> should be extended to handle mixed fractions. Perhaps something like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">8</span> <span class="mi">1</span><span class="o">/</span><span class="mi">2</span><span class="n">r</span> <span class="c1">#=> (17/2)</span>
<span class="s2">"8 1/2"</span><span class="p">.</span><span class="nf">to_r</span> <span class="c1">#=> (17/2)</span>
</code></pre>
<p>or</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">8</span> <span class="mi">1</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="n">r</span> <span class="c1">#=> (17/2)</span>
</code></pre> Ruby master - Feature #10331 (Open): String#to_r to recognize negative denominatorshttps://bugs.ruby-lang.org/issues/103312014-10-06T14:44:18Zsawa (Tsuyoshi Sawada)
<p>Current behavior or <code>String#to_r</code> does not recognize negative denominators. This can lead to confusing results:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"1/-3"</span><span class="p">.</span><span class="nf">to_r</span>
<span class="c1">#=> (1/1)</span>
</code></pre>
<p>I propose negative denominators to be recognized.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="s2">"1/-3"</span><span class="p">.</span><span class="nf">to_r</span>
<span class="c1">#=> (-1/3)</span>
</code></pre> 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 - Feature #10183 (Open): An alternative name for method `class`https://bugs.ruby-lang.org/issues/101832014-08-29T12:52:13Zsawa (Tsuyoshi Sawada)
<p>The method <code>class</code> is special in that it always has to have an explicit receiver in order to avoid crash with the keyword <code>class</code>. But this is very inconvenient. I have seen so many</p>
<pre><code>self.class
</code></pre>
<p>in codes. I propose that there should be an alternative name for this method so that it can be used with an implicit receiver, and the method name <code>class</code> should be gradually depricated.</p>
<p>As for the name, I have no clear idea. I can only think of <code>klass</code>, but perhaps someone else might come up with a better name.</p> Ruby master - Feature #10118 (Closed): Double splat for non-symbol keyshttps://bugs.ruby-lang.org/issues/101182014-08-07T23:45:13Zsawa (Tsuyoshi Sawada)
<p>The double splat operator ** only seems to work with hashes whose keys are symbols. It will not work when a key is a string, for example. This is true for both ways; for construction:</p>
<pre><code>def foo **; end
foo(:a => 3) #=> nil
foo("a" => 3) #=> ArgumentError: wrong number of arguments (1 for 0)
</code></pre>
<p>and destruction:</p>
<pre><code>def bar *; end
bar(**{:a => 3}) #=> nil
bar(**{"a" => 3}) #=> TypeError: wrong argument type String (expected Symbol)
</code></pre>
<p>This is confusing. I propose that the double splat syntax should be extended so that it works even when the keys are not symbols.</p> Ruby master - Feature #9768 (Assigned): Method that is visible only within a certain module/classhttps://bugs.ruby-lang.org/issues/97682014-04-22T09:57:35Zsawa (Tsuyoshi Sawada)
<p>Some frameworks/libraries monkeypatch their own methods on Ruby core classes like <code>String</code>, <code>Hash</code>, <code>Array</code>, etc., and that is often causing problems/concerns of name conflict.</p>
<p>Seeing that these custom methods are used only in the context of a certain module/class, I request for a way to define a method (<code>foo</code>) on a module/class (<code>A</code>) so that it will be visible only from within a specified module/class (<code>B</code>) or its descendants. The following illustrates this situation:</p>
<pre><code>A.new.foo # => undefined
class B
A.new.foo # => defined
def bar
A.new.foo # => defined
end
def self.baz
A.new.foo # => defined
end
end
class C < B
A.new.foo # => defined
def bar
A.new.foo # => defined
end
def self.baz
A.new.foo # => defined
end
end
</code></pre>
<p>I do not have a certain syntax for this in mind, but I think it can be made much simpler, compared to the complicated syntax of refinement.</p>
<p>This is reminiscent of refinement, but they are pretty much different.</p>
<p>Refinement's purpose is to let certain methods be accessible from only a certain file. A typical use case would be a library developer defining their methods to be used from within the library and making such methods inaccessible from the end user.</p>
<p>On the other hand, the idea I am proposing here is for making method accessible from any file, but only within a certain module/class. A typical use case would be defining a method to be used by an end user, but only from within a context of certain module/class.</p> Ruby master - Feature #9667 (Open): Optimization of __FILE__ and __dir__https://bugs.ruby-lang.org/issues/96672014-03-24T09:19:04Zsawa (Tsuyoshi Sawada)
<p>In the same spirit as the string literal followed by <code>freeze</code> is optimized, I think <code>__FILE__</code> and <code>__dir__</code> should be optimized. Currently, they return different object id each time they are called.</p>
<pre><code>__FILE__.object_id # => 70183725179420
__FILE__.object_id # => 70183725129020
...
</code></pre>
<p>I propose them to be optimized so that they are only created once per occurrence.</p>
<pre><code>__FILE__.object_id # => 70183725179420
__FILE__.object_id # => 70183725179420
...
</code></pre> Ruby master - Feature #9557 (Open): Enumerator#next and Enumerator#peek with argumenthttps://bugs.ruby-lang.org/issues/95572014-02-23T09:14:18Zsawa (Tsuyoshi Sawada)
<p>It often happens that I want to move the current index of an enumerator by some arbitrary number <code>n</code>. <code>Enumerator#feed</code> takes the element as the argument, but that cannot be used if the enumerator has duplicate elements, or when I do not have information of a particular element to choose but just want to increment the index by some number. <code>Enumerator#next</code>, on the other hand, has a fixed value <code>1</code> to be incremented. It would be convenient if <code>Enumerator#next</code> takes an optional argument that represents the difference of the index to be incremented. The argument can be understood to be defaulted to <code>1</code> when absent.</p>
<p>Also, I often want to look not necessarily the current position, but some position away. It would be good if <code>Enumerator#peek</code> takes an optional argument that represents the positional difference to be peeked. The argument can be understood to be defaulted to <code>0</code> when absent.</p>
<pre><code>enum = [0, 1, 2, 3, 4, 5, 6, 7, 8].to_enum
enum.peek # => 0
enum.peek(0) # => 0
enum.peek(1) # => 1
enum.peek # => 0
enum.next # => 0
enum.next(1) # => 1
enum.next(2) # => 2
enum.peek # => 4
enum.peek(0) # => 4
enum.peek(1) # => 5
enum.peek # => 4
enum.next # => 4
enum.next(1) # => 5
enum.next(2) # => 6
peek # => 8
</code></pre> Ruby master - Feature #9515 (Open): `IO.each` and `CSV.each`https://bugs.ruby-lang.org/issues/95152014-02-12T16:16:41Zsawa (Tsuyoshi Sawada)
<p>In <code>IO</code> class, there are pairs of a class method and an instance method with related function:</p>
<ul>
<li>
<code>IO.read</code> and <code>IO#read</code>
</li>
<li>
<code>IO.write</code> and <code>IO#write</code>
</li>
<li>
<code>IO.foreach</code> and <code>IO#each</code> (or its alias <code>IO#each_line</code>)</li>
</ul>
<p>For consistency, please make <code>IO.each</code> an alias for <code>IO.foreach</code>.</p>
<p>The same thing can be said for <code>CSV.each</code>.</p> Ruby master - Feature #9111 (Open): Encoding-free String comparisonhttps://bugs.ruby-lang.org/issues/91112013-11-14T22:15:06Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
Currently, strings with the same content but with different encodings count as different strings. This causes strange behaviour as below (noted in StackOverflow question <a href="http://stackoverflow.com/questions/19977788/strange-behavior-in-packed-ruby-strings#19978206" class="external">http://stackoverflow.com/questions/19977788/strange-behavior-in-packed-ruby-strings#19978206</a>):</p>
<pre><code>[128].pack("C") # => "\x80"
[128].pack("C") == "\x80" # => false
</code></pre>
<p>Since <code>[128].pack("C")</code> has the encoding ASCII-8BIT and <code>"\x80"</code> (by default) has the encoding UTF-8, the two strings are not equal.</p>
<p>Also, comparison of strings with different encodings may end up with a messy, unintended result.</p>
<p>I suggest that the comparison <code>String#<=></code> should not be based on the respective encoding of the strings, but all the strings should be internally converted to UTF-8 for the purpose of comparison.</p>
<p>=end</p> Ruby master - Feature #8970 (Open): Array.zip and Array.producthttps://bugs.ruby-lang.org/issues/89702013-10-01T03:57:09Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
Most of the time when I use <code>Array#zip</code> or <code>Array#product</code>, I feel cumbursome that I have to take out the first array and pass it as a receiver. For example, if I have</p>
<pre><code>a = [[:a, :b, :c], [:d, :e, :f], [:g, :h, :i]]
</code></pre>
<p>I have to do something like this:</p>
<pre><code>a.first.zip(*a.drop(1)){...}
a.first.product(*a.drop(1)){...}
</code></pre>
<p>Sometimes, the receiver (i.e., the first array) has significance, but most other times, that breaks asymmetry, making the code look ugly.</p>
<p>I would be happy if we had <code>Array.zip</code> and <code>Array.product</code> in addition so that we can do it like this:</p>
<pre><code>Array.zip(*a){...}
Array.product(*a){...}
</code></pre>
<p>=end</p> Ruby master - Feature #8948 (Assigned): Frozen regexhttps://bugs.ruby-lang.org/issues/89482013-09-25T04:02:37Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
I see that frozen string was accepted for Ruby 2.1, and frozen array and hash are proposed in <a href="https://bugs.ruby-lang.org/issues/8909" class="external">https://bugs.ruby-lang.org/issues/8909</a>. I feel there is even more use case for a frozen regex, i.e., a regex literal that generates a regex only once. It is frequent to have a regex within a frequently repeated portion of code, and generating the same regex each time is a waste of resource. At the moment, we can have a code like:</p>
<pre><code>class Foo
RE1 = /pattern1/
RE2 = /pattern1/
RE3 = /pattern1/
def classify
case self
when RE1 then 1
when RE2 then 2
when RE3 then 3
else 4
end
end
end
</code></pre>
<p>but suppose we have a frozen <code>Regexp</code> literal <code>//f</code>. Then we can write like:</p>
<pre><code>class Foo
def classify
case self
when /pattern1/f then 1
when /pattern1/f then 2
when /pattern1/f then 3
else 4
end
end
end
</code></pre>
<p>=end</p> Ruby master - Feature #8834 (Open): Kernel#load_relativehttps://bugs.ruby-lang.org/issues/88342013-08-30T10:32:44Zsawa (Tsuyoshi Sawada)
<p>The intended difference between <code>Kernel#require</code> and <code>Kernel#load</code> is that the former is for external libraries and the latter is for Ruby scripts internal to the project. Considering this fact, <code>load</code> should be more likely than <code>require</code> to be used in a situation where you want to call a file through a relative path. Strangely, there is <code>Kernel#require_relative</code>, but no <code>Kernel#load_relative</code>. I request <code>Kernel#load_relative</code>. It is even more necessary than <code>Kernel#require_relative</code>.</p>
<p>It seems to me that people are using <code>Kernel#require_relative</code> when they want to use a relative path, even in the context where they are supposed to use <code>load</code> because of the lack of <code>Kernel#load_relative</code>. I don't think this is a good practice. Furthermore, in cases where you have a file without a <code>.rb</code> or other extention that you want to call via a relative path, there is no good way to do it.</p> Ruby master - Feature #8614 (Open): Object#singleton_class with a blockhttps://bugs.ruby-lang.org/issues/86142013-07-10T01:04:42Zsawa (Tsuyoshi Sawada)
<p>=begin<br>
Most of the time when I use <code>Object#singleton_class</code>, I use it with <code>class_eval</code> following it, like follows:</p>
<pre><code>class Foo
singleton_class.class_eval{attr_accessor :bar}
end
</code></pre>
<p>I think it would be convenient if <code>Object#singleton_class</code> can optionally take a block so that the following will mean the same as above.</p>
<pre><code>class Foo
singleton_class{attr_accessor :bar}
end
</code></pre>
<p>=end</p>