Project

General

Profile

Feature #15504

Freeze all Range objects

Added by ko1 (Koichi Sasada) almost 2 years ago. Updated 26 days ago.

Status:
Closed
Priority:
Normal
Target version:
-
[ruby-core:90881]

Description

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:

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 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


Related issues

Related to Ruby master - Feature #17195: Freeze Enumerator::ArithmeticSequence objectsRejectedActions

Also available in: Atom PDF