Only define String.json_create & al when json/add is required

All the `json/add` related methods for string were
always defined unconditionally from the generators.

It's preferable to only define them if `json/add` is actually used.
This commit is contained in:
Jean Boussier 2025-08-03 10:33:30 +02:00 committed by Hiroshi SHIBATA
parent 65612dbb38
commit 1c6b36af18
No known key found for this signature in database
GPG Key ID: F9CF13417264FAC2
3 changed files with 37 additions and 64 deletions

View File

@ -31,7 +31,7 @@ typedef struct JSON_Generator_StateStruct {
#define RB_UNLIKELY(cond) (cond)
#endif
static VALUE mJSON, cState, cFragment, mString_Extend, eGeneratorError, eNestingError, Encoding_UTF_8;
static VALUE mJSON, cState, cFragment, eGeneratorError, eNestingError, Encoding_UTF_8;
static ID i_to_s, i_to_json, i_new, i_pack, i_unpack, i_create_id, i_extend, i_encode;
static VALUE sym_indent, sym_space, sym_space_before, sym_object_nl, sym_array_nl, sym_max_nesting, sym_allow_nan,
@ -835,18 +835,6 @@ static VALUE mFloat_to_json(int argc, VALUE *argv, VALUE self)
return cState_partial_generate(Vstate, self, generate_json_float, Qfalse);
}
/*
* call-seq: String.included(modul)
*
* Extends _modul_ with the String::Extend module.
*/
static VALUE mString_included_s(VALUE self, VALUE modul)
{
VALUE result = rb_funcall(modul, i_extend, 1, mString_Extend);
rb_call_super(1, &modul);
return result;
}
/*
* call-seq: to_json(*)
*
@ -861,51 +849,6 @@ static VALUE mString_to_json(int argc, VALUE *argv, VALUE self)
return cState_partial_generate(Vstate, self, generate_json_string, Qfalse);
}
/*
* call-seq: to_json_raw_object()
*
* This method creates a raw object hash, that can be nested into
* other data structures and will be generated as a raw string. This
* method should be used, if you want to convert raw strings to JSON
* instead of UTF-8 strings, e. g. binary data.
*/
static VALUE mString_to_json_raw_object(VALUE self)
{
VALUE ary;
VALUE result = rb_hash_new();
rb_hash_aset(result, rb_funcall(mJSON, i_create_id, 0), rb_class_name(rb_obj_class(self)));
ary = rb_funcall(self, i_unpack, 1, rb_str_new2("C*"));
rb_hash_aset(result, rb_utf8_str_new_lit("raw"), ary);
return result;
}
/*
* call-seq: to_json_raw(*args)
*
* This method creates a JSON text from the result of a call to
* to_json_raw_object of this String.
*/
static VALUE mString_to_json_raw(int argc, VALUE *argv, VALUE self)
{
VALUE obj = mString_to_json_raw_object(self);
Check_Type(obj, T_HASH);
return mHash_to_json(argc, argv, obj);
}
/*
* call-seq: json_create(o)
*
* Raw Strings are JSON Objects (the raw bytes are stored in an array for the
* key "raw"). The Ruby String can be created by this module method.
*/
static VALUE mString_Extend_json_create(VALUE self, VALUE o)
{
VALUE ary;
Check_Type(o, T_HASH);
ary = rb_hash_aref(o, rb_str_new2("raw"));
return rb_funcall(ary, i_pack, 1, rb_str_new2("C*"));
}
/*
* call-seq: to_json(*)
*
@ -2091,13 +2034,7 @@ void Init_generator(void)
rb_define_method(mFloat, "to_json", mFloat_to_json, -1);
VALUE mString = rb_define_module_under(mGeneratorMethods, "String");
rb_define_singleton_method(mString, "included", mString_included_s, 1);
rb_define_method(mString, "to_json", mString_to_json, -1);
rb_define_method(mString, "to_json_raw", mString_to_json_raw, -1);
rb_define_method(mString, "to_json_raw_object", mString_to_json_raw_object, 0);
mString_Extend = rb_define_module_under(mString, "Extend");
rb_define_method(mString_Extend, "json_create", mString_Extend_json_create, 1);
VALUE mTrueClass = rb_define_module_under(mGeneratorMethods, "TrueClass");
rb_define_method(mTrueClass, "to_json", mTrueClass_to_json, -1);

View File

@ -7,6 +7,7 @@ require 'json/add/date_time'
require 'json/add/exception'
require 'json/add/range'
require 'json/add/regexp'
require 'json/add/string'
require 'json/add/struct'
require 'json/add/symbol'
require 'json/add/time'

View File

@ -0,0 +1,35 @@
# frozen_string_literal: true
unless defined?(::JSON::JSON_LOADED) and ::JSON::JSON_LOADED
require 'json'
end
class String
# call-seq: json_create(o)
#
# Raw Strings are JSON Objects (the raw bytes are stored in an array for the
# key "raw"). The Ruby String can be created by this class method.
def self.json_create(object)
object["raw"].pack("C*")
end
# call-seq: to_json_raw_object()
#
# This method creates a raw object hash, that can be nested into
# other data structures and will be generated as a raw string. This
# method should be used, if you want to convert raw strings to JSON
# instead of UTF-8 strings, e. g. binary data.
def to_json_raw_object
{
JSON.create_id => self.class.name,
"raw" => unpack("C*"),
}
end
# call-seq: to_json_raw(*args)
#
# This method creates a JSON text from the result of a call to
# to_json_raw_object of this String.
def to_json_raw(...)
to_json_raw_object.to_json(...)
end
end