From: mame@... Date: 2019-06-23T04:47:18+00:00 Subject: [ruby-core:93324] [Ruby trunk Feature#15504] Freeze all Range object 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: