[前][次][番号順一覧][スレッド一覧]

ruby-changes:40838

From: ko1 <ko1@a...>
Date: Tue, 8 Dec 2015 00:10:23 +0900 (JST)
Subject: [ruby-changes:40838] ko1:r52917 (trunk): * string.c: introduce String#+@ and String#-@ to control

ko1	2015-12-08 00:10:00 +0900 (Tue, 08 Dec 2015)

  New Revision: 52917

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52917

  Log:
    * string.c: introduce String#+@ and String#-@ to control
      String mutability.
      [Feature #11782]

  Modified files:
    trunk/ChangeLog
    trunk/string.c
    trunk/test/ruby/test_string.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52916)
+++ ChangeLog	(revision 52917)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Mon Dec  7 23:45:20 2015  Koichi Sasada  <ko1@a...>
+
+	* string.c: introduce String#+@ and String#-@ to control
+	  String mutability.
+	  [Feature #11782]
+
 Mon Dec  7 23:39:49 2015  Ben Miller  <bjmllr@g...>
 
 	* parse.y: add heredoc <<~ syntax.  [Feature #9098]
Index: string.c
===================================================================
--- string.c	(revision 52916)
+++ string.c	(revision 52917)
@@ -2227,6 +2227,46 @@ rb_str_freeze(VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L2227
     return rb_obj_freeze(str);
 }
 
+
+/*
+ * call-seq:
+ *   +str  -> str (mutable)
+ *
+ * If the string is frozen, then return duplicated mutable string.
+ *
+ * If the string is not frozen, then return the string itself.
+ */
+static VALUE
+str_uplus(VALUE str)
+{
+    if (OBJ_FROZEN(str)) {
+	return rb_str_dup(str);
+    }
+    else {
+	return str;
+    }
+}
+
+/*
+ * call-seq:
+ *   -str  -> str (frozen)
+ *
+ * If the string is frozen, then return the string itself.
+ *
+ * If the string is not frozen, then duplicate the string
+ * freeze it and return it.
+ */
+static VALUE
+str_uminus(VALUE str)
+{
+    if (OBJ_FROZEN(str)) {
+	return str;
+    }
+    else {
+	return rb_str_freeze(rb_str_dup(str));
+    }
+}
+
 RUBY_ALIAS_FUNCTION(rb_str_dup_frozen(VALUE str), rb_str_new_frozen, (str))
 #define rb_str_dup_frozen rb_str_new_frozen
 
@@ -9295,6 +9335,8 @@ Init_String(void) https://github.com/ruby/ruby/blob/trunk/string.c#L9335
     rb_define_method(rb_cString, "scrub", str_scrub, -1);
     rb_define_method(rb_cString, "scrub!", str_scrub_bang, -1);
     rb_define_method(rb_cString, "freeze", rb_str_freeze, 0);
+    rb_define_method(rb_cString, "+@", str_uplus, 0);
+    rb_define_method(rb_cString, "-@", str_uminus, 0);
 
     rb_define_method(rb_cString, "to_i", rb_str_to_i, -1);
     rb_define_method(rb_cString, "to_f", rb_str_to_f, 0);
Index: test/ruby/test_string.rb
===================================================================
--- test/ruby/test_string.rb	(revision 52916)
+++ test/ruby/test_string.rb	(revision 52917)
@@ -2252,6 +2252,24 @@ class TestString < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L2252
     end;
   end if [0].pack("l!").bytesize < [nil].pack("p").bytesize
   # enable only when string size range is smaller than memory space
+
+  def test_uplus_minus
+    str = "foo"
+    assert_equal(false, str.frozen?)
+    assert_equal(false, (+str).frozen?)
+    assert_equal(true,  (-str).frozen?)
+
+    assert_equal(str.object_id, (+str).object_id)
+    assert_not_equal(str.object_id, (-str).object_id)
+
+    str = "bar".freeze
+    assert_equal(true,  str.frozen?)
+    assert_equal(false, (+str).frozen?)
+    assert_equal(true,  (-str).frozen?)
+
+    assert_not_equal(str.object_id, (+str).object_id)
+    assert_equal(str.object_id, (-str).object_id)
+  end
 end
 
 class TestString2 < TestString

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]