[ruby-core:93324] [Ruby trunk Feature#15504] Freeze all Range object
From:
mame@...
Date:
2019-06-23 04:47:18 UTC
List:
ruby-core #93324
Issue #15504 has been updated by mame (Yusuke Endoh).
I guess @eregon came from #15950. Will `ary[-3..]` be as efficient as `ary[-3, 3]` by freezing and deduping a literal `(-3..)`? Looks good if we can confirm it by an experiment.
Some thoughts:
* Even if a range is frozen, `("a".."z")` should not be deduped because of the reason @marcandre said.
* 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.
* It would be the most elegant if the combination of MJIT and escape analysis solves this kind of performance problems.
----------------------------------------
Feature #15504: Freeze all Range object
https://bugs.ruby-lang.org/issues/15504#change-78802
* Author: ko1 (Koichi Sasada)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
* Target version:
----------------------------------------
# Abstrcat
Range is now non-frozen. How about to freeze all of Range objects?
# Background
We freeze some type of objects, Numerics (r47523) and Symbols [Feature #8906].
I believe making objects immutable solves some kind of programming difficulties.
`Range` is mutable, at least it is written in Range literal. So we can write the following weird program.
```
2.times{
r = (1..3)
p r.instance_variable_get(:@foo)
#=> 1st time: nil
#=> 2nd time: :bar
r.instance_variable_set(:@foo, :bar)
}
```
in `range.c`, there is a comment (thanks znz-san):
```
static void
range_modify(VALUE range)
{
rb_check_frozen(range);
/* Ranges are immutable, so that they should be initialized only once. */
if (RANGE_EXCL(range) != Qnil) {
rb_name_err_raise("`initialize' called twice", range, ID2SYM(idInitialize));
}
}
```
# Patch
```
Index: range.c
===================================================================
--- range.c (リビジョン 66699)
+++ range.c (作業コピー)
@@ -45,6 +45,8 @@
RANGE_SET_EXCL(range, exclude_end);
RANGE_SET_BEG(range, beg);
RANGE_SET_END(range, end);
+
+ rb_obj_freeze(range);
}
VALUE
```
# Discussion
There are several usage of mutable Range in tests.
* (1) taint-flag
* (2) add singleton methods.
* (3) subclass with mutable states
Maybe (2) and (3) are points.
Thanks,
Koichi
--
https://bugs.ruby-lang.org/
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>