summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2019-09-26 17:27:47 +0200
committerNobuyoshi Nakada <nobu@ruby-lang.org>2019-09-27 13:52:33 +0900
commiteff15a269fdc37d2b09cf1dfe8c1b1bf6e377a32 (patch)
tree893d0292f67673e2425727e2ecd398a89d7043c9
parent2082a26dc75da7cb76150b51cd5b8f7636ad0fa2 (diff)
downloadruby-eff15a269fdc37d2b09cf1dfe8c1b1bf6e377a32.tar.gz
[EXPERIMENTAL] Make NilClass#to_s, TrueClass#to_s and FalseClass#to_s return a frozen String
* Always the same frozen String for each of these values. * Avoids extra allocations whenever calling these 3 methods. * See [Feature #16150]
-rw-r--r--NEWS8
-rw-r--r--object.c16
-rw-r--r--spec/ruby/core/false/to_s_spec.rb10
-rw-r--r--spec/ruby/core/nil/to_s_spec.rb10
-rw-r--r--spec/ruby/core/true/to_s_spec.rb10
5 files changed, 51 insertions, 3 deletions
diff --git a/NEWS b/NEWS
index 1ef70fcb50..2f8b954c57 100644
--- a/NEWS
+++ b/NEWS
@@ -163,6 +163,14 @@ Integer::
0b01001100[2...6] #=> 0b0011
^^^^
+NilClass / TrueClass / FalseClass::
+
+ Modified method::
+
+ * NilClass#to_s, TrueClass#to_s and FalseClass#to_s now always returns a
+ frozen String. The returned String is always the same for each of these
+ values. This change is experimental. [Feature #16150]
+
Module::
New method::
diff --git a/object.c b/object.c
index 9c603a8f10..ab9ff80193 100644
--- a/object.c
+++ b/object.c
@@ -40,6 +40,10 @@ VALUE rb_cNilClass; /*!< NilClass class */
VALUE rb_cTrueClass; /*!< TrueClass class */
VALUE rb_cFalseClass; /*!< FalseClass class */
+static VALUE rb_cNilClass_to_s;
+static VALUE rb_cTrueClass_to_s;
+static VALUE rb_cFalseClass_to_s;
+
/*! \cond INTERNAL_MACRO */
#define id_eq idEq
@@ -1442,7 +1446,7 @@ nil_to_f(VALUE obj)
static VALUE
nil_to_s(VALUE obj)
{
- return rb_usascii_str_new(0, 0);
+ return rb_cNilClass_to_s;
}
/*
@@ -1525,7 +1529,7 @@ nil_match(VALUE obj1, VALUE obj2)
static VALUE
true_to_s(VALUE obj)
{
- return rb_usascii_str_new2("true");
+ return rb_cTrueClass_to_s;
}
@@ -1602,7 +1606,7 @@ true_xor(VALUE obj, VALUE obj2)
static VALUE
false_to_s(VALUE obj)
{
- return rb_usascii_str_new2("false");
+ return rb_cFalseClass_to_s;
}
/*
@@ -4609,6 +4613,8 @@ InitVM_Object(void)
rb_define_global_function("Hash", rb_f_hash, 1);
rb_cNilClass = rb_define_class("NilClass", rb_cObject);
+ rb_cNilClass_to_s = rb_fstring_enc_lit("", rb_usascii_encoding());
+ rb_gc_register_mark_object(rb_cNilClass_to_s);
rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0);
rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
@@ -4703,6 +4709,8 @@ InitVM_Object(void)
rb_deprecate_constant(rb_cObject, "Data");
rb_cTrueClass = rb_define_class("TrueClass", rb_cObject);
+ rb_cTrueClass_to_s = rb_fstring_enc_lit("true", rb_usascii_encoding());
+ rb_gc_register_mark_object(rb_cTrueClass_to_s);
rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0);
rb_define_alias(rb_cTrueClass, "inspect", "to_s");
rb_define_method(rb_cTrueClass, "&", true_and, 1);
@@ -4718,6 +4726,8 @@ InitVM_Object(void)
rb_deprecate_constant(rb_cObject, "TRUE");
rb_cFalseClass = rb_define_class("FalseClass", rb_cObject);
+ rb_cFalseClass_to_s = rb_fstring_enc_lit("false", rb_usascii_encoding());
+ rb_gc_register_mark_object(rb_cFalseClass_to_s);
rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0);
rb_define_alias(rb_cFalseClass, "inspect", "to_s");
rb_define_method(rb_cFalseClass, "&", false_and, 1);
diff --git a/spec/ruby/core/false/to_s_spec.rb b/spec/ruby/core/false/to_s_spec.rb
index 40853da88b..c996d87000 100644
--- a/spec/ruby/core/false/to_s_spec.rb
+++ b/spec/ruby/core/false/to_s_spec.rb
@@ -4,4 +4,14 @@ describe "FalseClass#to_s" do
it "returns the string 'false'" do
false.to_s.should == "false"
end
+
+ ruby_version_is "2.7" do
+ it "returns a frozen string" do
+ false.to_s.frozen?.should == true
+ end
+
+ it "always returns the same string" do
+ false.to_s.should equal(false.to_s)
+ end
+ end
end
diff --git a/spec/ruby/core/nil/to_s_spec.rb b/spec/ruby/core/nil/to_s_spec.rb
index c7a18e2527..4b61f589f7 100644
--- a/spec/ruby/core/nil/to_s_spec.rb
+++ b/spec/ruby/core/nil/to_s_spec.rb
@@ -4,4 +4,14 @@ describe "NilClass#to_s" do
it "returns the string ''" do
nil.to_s.should == ""
end
+
+ ruby_version_is "2.7" do
+ it "returns a frozen string" do
+ nil.to_s.frozen?.should == true
+ end
+
+ it "always returns the same string" do
+ nil.to_s.should equal(nil.to_s)
+ end
+ end
end
diff --git a/spec/ruby/core/true/to_s_spec.rb b/spec/ruby/core/true/to_s_spec.rb
index 30ca354b0c..68b0052c5d 100644
--- a/spec/ruby/core/true/to_s_spec.rb
+++ b/spec/ruby/core/true/to_s_spec.rb
@@ -4,4 +4,14 @@ describe "TrueClass#to_s" do
it "returns the string 'true'" do
true.to_s.should == "true"
end
+
+ ruby_version_is "2.7" do
+ it "returns a frozen string" do
+ true.to_s.frozen?.should == true
+ end
+
+ it "always returns the same string" do
+ true.to_s.should equal(true.to_s)
+ end
+ end
end