End of Life Ruby 3.1 has reached end of life and gets no more fixes. Switch to Ruby 4.0 →
String.new
static VALUE
rb_str_init(int argc, VALUE *argv, VALUE str)
{
static ID keyword_ids[2];
VALUE orig, opt, venc, vcapa;
VALUE kwargs[2];
rb_encoding *enc = 0;
int n;
if (!keyword_ids[0]) {
keyword_ids[0] = rb_id_encoding();
CONST_ID(keyword_ids[1], "capacity");
}
n = rb_scan_args(argc, argv, "01:", &orig, &opt);
if (!NIL_P(opt)) {
rb_get_kwargs(opt, keyword_ids, 0, 2, kwargs);
venc = kwargs[0];
vcapa = kwargs[1];
if (venc != Qundef && !NIL_P(venc)) {
enc = rb_to_encoding(venc);
}
if (vcapa != Qundef && !NIL_P(vcapa)) {
long capa = NUM2LONG(vcapa);
long len = 0;
int termlen = enc ? rb_enc_mbminlen(enc) : 1;
if (capa < STR_BUF_MIN_SIZE) {
capa = STR_BUF_MIN_SIZE;
}
if (n == 1) {
StringValue(orig);
len = RSTRING_LEN(orig);
if (capa < len) {
capa = len;
}
if (orig == str) n = 0;
}
str_modifiable(str);
if (STR_EMBED_P(str)) { /* make noembed always */
char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
#if USE_RVARGC
assert(RSTRING(str)->as.embed.len + 1 <= str_embed_capa(str));
memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING(str)->as.embed.len + 1);
#else
memcpy(new_ptr, RSTRING(str)->as.embed.ary, RSTRING_EMBED_LEN_MAX + 1);
#endif
RSTRING(str)->as.heap.ptr = new_ptr;
}
else if (FL_TEST(str, STR_SHARED|STR_NOFREE)) {
const size_t size = (size_t)capa + termlen;
const char *const old_ptr = RSTRING_PTR(str);
const size_t osize = RSTRING(str)->as.heap.len + TERM_LEN(str);
char *new_ptr = ALLOC_N(char, (size_t)capa + termlen);
memcpy(new_ptr, old_ptr, osize < size ? osize : size);
FL_UNSET_RAW(str, STR_SHARED|STR_NOFREE);
RSTRING(str)->as.heap.ptr = new_ptr;
}
else if (STR_HEAP_SIZE(str) != (size_t)capa + termlen) {
SIZED_REALLOC_N(RSTRING(str)->as.heap.ptr, char,
(size_t)capa + termlen, STR_HEAP_SIZE(str));
}
RSTRING(str)->as.heap.len = len;
TERM_FILL(&RSTRING(str)->as.heap.ptr[len], termlen);
if (n == 1) {
memcpy(RSTRING(str)->as.heap.ptr, RSTRING_PTR(orig), len);
rb_enc_cr_str_exact_copy(str, orig);
}
FL_SET(str, STR_NOEMBED);
RSTRING(str)->as.heap.aux.capa = capa;
}
else if (n == 1) {
rb_str_replace(str, orig);
}
if (enc) {
rb_enc_associate(str, enc);
ENC_CODERANGE_CLEAR(str);
}
}
else if (n == 1) {
rb_str_replace(str, orig);
}
return str;
}
Returns a new String that is a copy of string.
With no arguments, returns the empty string with the Encoding ASCII-8BIT:
s = String.new s # => "" s.encoding # => #<Encoding:ASCII-8BIT>
With the single String argument string, returns a copy of string with the same encoding as string:
s = String.new("Que veut dire \u{e7}a?") s # => "Que veut dire \u{e7}a?" s.encoding # => #<Encoding:UTF-8>
Literal strings like "" or here-documents always use script encoding, unlike String.new.
With keyword encoding, returns a copy of str with the specified encoding:
s = String.new(encoding: 'ASCII') s.encoding # => #<Encoding:US-ASCII> s = String.new('foo', encoding: 'ASCII') s.encoding # => #<Encoding:US-ASCII>
Note that these are equivalent:
s0 = String.new('foo', encoding: 'ASCII') s1 = 'foo'.force_encoding('ASCII') s0.encoding == s1.encoding # => true
With keyword capacity, returns a copy of str; the given capacity may set the size of the internal buffer, which may affect performance:
String.new(capacity: 1) # => "" String.new(capacity: 4096) # => ""
The string, encoding, and capacity arguments may all be used together:
String.new('hello', encoding: 'UTF-8', capacity: 25)