https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112019-01-04T07:29:52ZRuby Issue Tracking SystemRuby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=760732019-01-04T07:29:52Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<ul></ul><p>I think that (2) and (3) are indeed capital points. Freezing range litterals (only) might be a better idea? with an approach like frozen string literals?</p>
<p>Not that even frozen ranges aren't completely immutable:</p>
<pre><code>r = ('a'..'z').freeze
r.end.upcase!
r # => "a".."Z"
</code></pre> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=787932019-06-22T14:38:48ZEregon (Benoit Daloze)
<ul></ul><p>I think it would make sense to freeze Range literals.</p>
<p>Adding methods to Range might be reasonable, but singleton methods, I would think much less so.</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=788022019-06-23T04:47:16Zmame (Yusuke Endoh)mame@ruby-lang.org
<ul></ul><p>I guess <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/772">@Eregon (Benoit Daloze)</a> came from <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Allow negative length in `Array#[]`, `Array#[]=`, `Array#slice`, `Array#slice!`, `String#[]`, `St... (Rejected)" href="https://redmine.ruby-lang.org/issues/15950">#15950</a>. Will <code>ary[-3..]</code> be as efficient as <code>ary[-3, 3]</code> by freezing and deduping a literal <code>(-3..)</code>? Looks good if we can confirm it by an experiment.</p>
<p>Some thoughts:</p>
<ul>
<li>Even if a range is frozen, <code>("a".."z")</code> should not be deduped because of the reason <a class="user active user-mention" href="https://redmine.ruby-lang.org/users/182">@marcandre (Marc-Andre Lafortune)</a> said.</li>
<li>I'm for freezing all Ranges, not only Range literals. I hate the idea of freezing only literals because casually mixing frozen and unfrozen objects leads to hard-to-debug bugs that depend upon data flow.</li>
<li>It would be the most elegant if the combination of MJIT and escape analysis solves this kind of performance problems.</li>
</ul> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=869642020-08-07T06:12:49Zko1 (Koichi Sasada)
<ul></ul><p>I got an issue on Ractor.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">test</span>
<span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">2</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">r1</span> <span class="o">=</span> <span class="nb">test</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="k">do</span>
<span class="n">r2</span> <span class="o">=</span> <span class="nb">test</span>
<span class="k">end</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<ul>
<li>compiler cached Range <code>(1..2)</code> because they begin and end are frozen literals. The test method returns a cached same range object.</li>
<li>it means <code>test</code> returns not-immutable but same object. It violate the Ractor's memory model.</li>
</ul>
<p>To solve it, there are two options.</p>
<p>(1) avoid cache at compile time.<br>
(2) freeze Range objects which will be cached by th compiler.</p>
<p>For performance reason, I want to choose (2).</p>
<p>After that, could you please discuss all Range objects should be frozen or not.</p>
<p>Thanks,<br>
Koichi</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=869662020-08-07T10:02:19Zsawa (Tsuyoshi Sawada)
<ul><li><strong>Subject</strong> changed from <i>Freeze all Range object</i> to <i>Freeze all Range objects</i></li><li><strong>Description</strong> updated (<a title="View differences" href="/journals/86966/diff?detail_id=57692">diff</a>)</li></ul> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=869692020-08-07T11:21:01ZEregon (Benoit Daloze)
<ul></ul><p>Right, every object cached at parse time must be deeply immutable, I would think that was an oversight.</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877002020-09-25T08:49:04Zmatz (Yukihiro Matsumoto)matz@ruby.or.jp
<ul></ul><p>I agree with making ranges frozen. I don't see any particular case that could be broken by frozen ranges.<br>
Since there's possiblity of breakage, I'd like to experiment it.</p>
<p>Matz.</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877162020-09-25T11:53:17Zko1 (Koichi Sasada)
<ul></ul><p>Ok, I freeze all Ranges except sub-classes.<br>
<a href="https://github.com/ruby/ruby/pull/3583" class="external">https://github.com/ruby/ruby/pull/3583</a></p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877192020-09-25T13:17:15Zko1 (Koichi Sasada)
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Closed</i></li></ul><p>Applied in changeset <a class="changeset" title="freeze all Range objects. Matz want to try to freeze all Range objects. [Feature #15504]" href="https://redmine.ruby-lang.org/projects/ruby-master/repository/git/revisions/0096d2b895395df5ab8696d3b6d444dc1b7730b6">git|0096d2b895395df5ab8696d3b6d444dc1b7730b6</a>.</p>
<hr>
<p>freeze all Range objects.</p>
<p>Matz want to try to freeze all Range objects.<br>
[Feature <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Freeze all Range objects (Closed)" href="https://redmine.ruby-lang.org/issues/15504">#15504</a>]</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877212020-09-25T13:58:08ZEregon (Benoit Daloze)
<ul></ul><p>Great!</p>
<p>Related, should Enumerator::ArithmeticSequence be frozen too?</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877232020-09-25T15:09:25Zko1 (Koichi Sasada)
<ul></ul><p>Eregon (Benoit Daloze) wrote in <a href="#note-10">#note-10</a>:</p>
<blockquote>
<p>Related, should Enumerator::ArithmeticSequence be frozen too?</p>
</blockquote>
<p>new ticket?</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877462020-09-26T13:20:43ZEregon (Benoit Daloze)
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-6 priority-4 priority-default closed" href="/issues/17195">Feature #17195</a>: Freeze Enumerator::ArithmeticSequence objects</i> added</li></ul> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=877482020-09-26T13:21:00ZEregon (Benoit Daloze)
<ul></ul><p>ko1 (Koichi Sasada) wrote in <a href="#note-11">#note-11</a>:</p>
<blockquote>
<p>Eregon (Benoit Daloze) wrote in <a href="#note-10">#note-10</a>:</p>
<blockquote>
<p>Related, should Enumerator::ArithmeticSequence be frozen too?</p>
</blockquote>
<p>new ticket?</p>
</blockquote>
<p>I filed <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Freeze Enumerator::ArithmeticSequence objects (Rejected)" href="https://redmine.ruby-lang.org/issues/17195">#17195</a></p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=901112021-01-26T20:52:33ZAlexWayfer (Alexander Popov)alex.wayfer@gmail.com
<ul></ul><p>I can't now mock Range objects with RSpec (<code>gorilla_patch</code> gem). What should I do? I see no work-around, like <code>+'foo'</code> for strings. <code>Range.new</code> gives frozen objects too.</p>
<p>I found a work-around: <code>(5..7).dup</code>, but it's weird anyway.</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=901132021-01-26T21:04:53Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/12118">@AlexWayfer (Alexander Popov)</a></p>
<p><a href="https://github.com/AlexWayfer/gorilla_patch/blob/master/lib/gorilla_patch/cover.rb#L8" class="external">https://github.com/AlexWayfer/gorilla_patch/blob/master/lib/gorilla_patch/cover.rb#L8</a> -- may be for this particular case it is better to have version guard as an outer check?..</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="no">RUBY_VERSION</span> <span class="o"><</span> <span class="s1">'2.6'</span>
<span class="k">def</span> <span class="nf">cover?</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="c1">#...</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>...and have the same guard in specs?..</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=902782021-02-06T00:29:40ZAlexWayfer (Alexander Popov)alex.wayfer@gmail.com
<ul></ul><p>zverok (Victor Shepelev) wrote in <a href="#note-15">#note-15</a>:</p>
<blockquote>
<p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/12118">@AlexWayfer (Alexander Popov)</a></p>
<p><a href="https://github.com/AlexWayfer/gorilla_patch/blob/master/lib/gorilla_patch/cover.rb#L8" class="external">https://github.com/AlexWayfer/gorilla_patch/blob/master/lib/gorilla_patch/cover.rb#L8</a> -- may be for this particular case it is better to have version guard as an outer check?..</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="no">RUBY_VERSION</span> <span class="o"><</span> <span class="s1">'2.6'</span>
<span class="k">def</span> <span class="nf">cover?</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="c1">#...</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>...and have the same guard in specs?..</p>
</blockquote>
<p>Thank you, I agree, it's better. But… if I want to check was called refined method or core? Right now I'm doing it via <code>have_received</code> once or never (depending on Ruby version), and for this RSpec should change the object (Range), but it's frozen since Ruby 3. Do I have other ways to check which implementation of method was used? <code>value.method(:cover?).source_location</code> returns <code>nil</code> in both cases.</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=902832021-02-06T10:47:18Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><blockquote>
<p>if I want to check was called refined method or core?</p>
</blockquote>
<p>It actually might be a good feature proposal for Ruby. Because currently, you can tell whether the method is defined by this class, by its parent, by included module, by singleton class... via <code>Method#owner</code>. But as far as I can recall, there is no way to ask "whether the method is defined by refinement".</p>
<p>But this whole discussion is unrelated to Range frozenness, honestly :)</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=907762021-03-06T21:16:52ZAlexWayfer (Alexander Popov)alex.wayfer@gmail.com
<ul></ul><p>zverok (Victor Shepelev) wrote in <a href="#note-17">#note-17</a>:</p>
<blockquote>
<blockquote>
<p>if I want to check was called refined method or core?</p>
</blockquote>
<p>It actually might be a good feature proposal for Ruby. Because currently, you can tell whether the method is defined by this class, by its parent, by included module, by singleton class... via <code>Method#owner</code>. But as far as I can recall, there is no way to ask "whether the method is defined by refinement".</p>
</blockquote>
<p>I'm too lazy for such proposals, especially well formatted, but I can try. UPD: Created <a href="https://bugs.ruby-lang.org/issues/17674" class="external">https://bugs.ruby-lang.org/issues/17674</a></p>
<p>zverok (Victor Shepelev) wrote in <a href="#note-17">#note-17</a>:</p>
<blockquote>
<p>But this whole discussion is unrelated to Range frozenness, honestly :)</p>
</blockquote>
<p>No, I disagree! My issue was raised by resolving this issue, even without changes mention in the article about Ruby 3: <a href="https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/" class="external">https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/</a></p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=942582021-10-22T14:31:52ZEregon (Benoit Daloze)
<ul></ul><p><a class="user active user-mention" href="https://redmine.ruby-lang.org/users/17">@ko1 (Koichi Sasada)</a> Do you know why only Range instances and not Range subclass instances were frozen? (<a href="https://bugs.ruby-lang.org/issues/15504#note-8" class="external">https://bugs.ruby-lang.org/issues/15504#note-8</a>)</p>
<p>This issue title is a bit confusing, also <a href="https://bugs.ruby-lang.org/issues/15504#note-9" class="external">https://bugs.ruby-lang.org/issues/15504#note-9</a>.<br>
Probably <a href="https://bugs.ruby-lang.org/issues/15504#note-9" class="external">https://bugs.ruby-lang.org/issues/15504#note-9</a> was reverted?</p>
<p>I guess "Freeze all Range objects" means all Range instances, literal or not, but still not subclass instances, that confused me.</p> Ruby master - Feature #15504: Freeze all Range objectshttps://redmine.ruby-lang.org/issues/15504?journal_id=950772021-12-03T03:28:35Zko1 (Koichi Sasada)
<ul></ul><p>Eregon (Benoit Daloze) wrote in <a href="#note-19">#note-19</a>:</p>
<blockquote>
<p>This issue title is a bit confusing, also <a href="https://bugs.ruby-lang.org/issues/15504#note-9" class="external">https://bugs.ruby-lang.org/issues/15504#note-9</a>.<br>
Probably <a href="https://bugs.ruby-lang.org/issues/15504#note-9" class="external">https://bugs.ruby-lang.org/issues/15504#note-9</a> was reverted?</p>
<p>I guess "Freeze all Range objects" means all Range instances, literal or not, but still not subclass instances, that confused me.</p>
</blockquote>
<p>I see. Not sure but maybe it is only implementation issue.</p>