From: alex.wayfer@... Date: 2021-02-06T00:29:40+00:00 Subject: [ruby-core:102405] [Ruby master Feature#15504] Freeze all Range objects Issue #15504 has been updated by AlexWayfer (Alexander Popov). zverok (Victor Shepelev) wrote in #note-15: > @AlexWayfer > > https://github.com/AlexWayfer/gorilla_patch/blob/master/lib/gorilla_patch/cover.rb#L8 -- may be for this particular case it is better to have version guard as an outer check?.. > > ```ruby > if RUBY_VERSION < '2.6' > def cover?(value) > #... > end > end > ``` > ...and have the same guard in specs?.. 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 `have_received` once or never, and for this RSpec should change object (Range), but it's frozen. Do I have other ways to check which implementation of method was used? `value.method(:cover?).source_location` returns `nil` in both cases. ---------------------------------------- Feature #15504: Freeze all Range objects https://bugs.ruby-lang.org/issues/15504#change-90278 * Author: ko1 (Koichi Sasada) * Status: Closed * Priority: Normal * Assignee: matz (Yukihiro Matsumoto) ---------------------------------------- # Abstract Range is currently non-frozen. How about freezing all Range objects? # Background We froze some types of objects: Numerics (r47523) and Symbols [Feature #8906]. I believe that making objects immutable solves some kinds of programming difficulties. `Range` is mutable at least when written as Range literal. So we can write the following weird program: ```ruby 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): ```c 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 usages of mutable Range in the tests. * (1) Taint-flag * (2) Add singleton methods. * (3) Subclass with mutable states Maybe (2) and (3) are crucial. Thanks, Koichi -- https://bugs.ruby-lang.org/ Unsubscribe: