Class: String

Inherits:
Object show all
Includes:
Comparable
Defined in:
mruby/mrblib/string.rb,
gems/carbuncle-support/mrblib/string.rb,
mruby/src/string.c,
mruby/mrbgems/mruby-string-ext/mrblib/string.rb,
.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb

Overview

String

ISO 15.2.10

Instance Method Summary collapse

Methods included from Comparable

#<, #<=, #>, #>=, #between?, #clamp

Constructor Details

#new(str = "") ⇒ String

Returns a new string object containing a copy of str.



1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
# File 'mruby/src/string.c', line 1845

static mrb_value
mrb_str_init(mrb_state *mrb, mrb_value self)
{
  mrb_value str2;

  if (mrb_get_args(mrb, "|S", &str2) == 0) {
    struct RString *s = str_new(mrb, 0, 0);
    str2 = mrb_obj_value(s);
  }
  str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2));
  return self;
}

Instance Method Details

#*(integer) ⇒ String

Copy—Returns a new String containing integer copies of the receiver.

"Ho! " * 3   #=> "Ho! Ho! Ho! "

Returns:



877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
# File 'mruby/src/string.c', line 877

static mrb_value
mrb_str_times(mrb_state *mrb, mrb_value self)
{
  mrb_int n, len, times;
  struct RString *str2;
  char *p;

  mrb_get_args(mrb, "i", &times);
  if (times < 0) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument");
  }
  if (mrb_int_mul_overflow(RSTRING_LEN(self), times, &len)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big");
  }
  str2 = str_new(mrb, 0, len);
  p = RSTR_PTR(str2);
  if (len > 0) {
    n = RSTRING_LEN(self);
    memcpy(p, RSTRING_PTR(self), n);
    while (n <= len/2) {
      memcpy(p + n, p, n);
      n *= 2;
    }
    memcpy(p + n, p, len-n);
  }
  p[RSTR_LEN(str2)] = '\0';
  RSTR_COPY_ASCII_FLAG(str2, mrb_str_ptr(self));

  return mrb_obj_value(str2);
}

#+(other_str) ⇒ String

Concatenation—Returns a new String containing other_str concatenated to str.

"Hello from " + self.to_s   #=> "Hello from main"

Returns:



836
837
838
839
840
841
842
843
# File 'mruby/src/string.c', line 836

static mrb_value
mrb_str_plus_m(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  mrb_get_args(mrb, "S", &str);
  return mrb_str_plus(mrb, self, str);
}

#+self

Returns self if self is not frozen.

Otherwise returns self.dup, which is not frozen.

Returns:

  • (self)


1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1250

static mrb_value
mrb_str_uplus(mrb_state *mrb, mrb_value str)
{
  if (mrb_frozen_p(mrb_obj_ptr(str))) {
    return mrb_str_dup(mrb, str);
  }
  else {
    return str;
  }
}

#-Object

Returns a frozen, possibly pre-existing copy of the string.

The returned String will be deduplicated as long as it does not have any instance variables set on it and is not a String subclass.

String#dedup is an alias for String#-@.



1272
1273
1274
1275
1276
1277
1278
1279
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1272

static mrb_value
mrb_str_uminus(mrb_state *mrb, mrb_value str)
{
  if (mrb_frozen_p(mrb_obj_ptr(str))) {
    return str;
  }
  return mrb_obj_freeze(mrb, mrb_str_dup(mrb, str));
}

#<<(obj) ⇒ String #concat(*obj) ⇒ String

s = ‘foo’

s.concat('bar', 'baz') # => "foobarbaz"
s                      # => "foobarbaz"

For each given object object that is an Integer, the value is considered a codepoint and converted to a character before concatenation:

s = 'foo'
s.concat(32, 'bar', 32, 'baz') # => "foo bar baz"

Overloads:



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 175

static mrb_value
mrb_str_concat_m(mrb_state *mrb, mrb_value self)
{
  if (mrb_get_argc(mrb) == 1) {
    str_concat(mrb, self, mrb_get_arg1(mrb));
    return self;
  }

  mrb_value *args;
  mrb_int alen;

  mrb_get_args(mrb, "*", &args, &alen);
  for (mrb_int i=0; i<alen; i++) {
    str_concat(mrb, self, args[i]);
  }
  return self;
}

#<=>(other_str) ⇒ -1, ...

Comparison—Returns -1 if other_str is less than, 0 if other_str is equal to, and +1 if other_str is greater than str. If the strings are of different lengths, and the strings are equal when compared up to the shortest length, then the longer string is considered greater than the shorter one. If the variable $= is false, the comparison is based on comparing the binary values of each character in the string. In older versions of Ruby, setting $= allowed case-insensitive comparisons; this is now deprecated in favor of using String#casecmp.

<=> is the basis for the methods <, <=, >, >=, and between?, included from module Comparable. The method String#== does not use Comparable#==.

"abcdef" <=> "abcde"     #=> 1
"abcdef" <=> "abcdef"    #=> 0
"abcdef" <=> "abcdefg"   #=> -1
"abcdef" <=> "ABCDEF"    #=> 1

Returns:

  • (-1, 0, +1)


966
967
968
969
970
971
972
973
974
975
976
977
978
979
# File 'mruby/src/string.c', line 966

static mrb_value
mrb_str_cmp_m(mrb_state *mrb, mrb_value str1)
{
  mrb_value str2 = mrb_get_arg1(mrb);
  mrb_int result;

  if (!mrb_string_p(str2)) {
    return mrb_nil_value();
  }
  else {
    result = mrb_str_cmp(mrb, str1, str2);
  }
  return mrb_int_value(mrb, result);
}

#==(obj) ⇒ Boolean

Equality— If obj is not a String, returns false. Otherwise, returns false or true

caution:if <i>str</i> <code><=></code> <i>obj</i> returns zero.

Returns:

  • (Boolean)


1010
1011
1012
1013
1014
1015
1016
# File 'mruby/src/string.c', line 1010

static mrb_value
mrb_str_equal_m(mrb_state *mrb, mrb_value str1)
{
  mrb_value str2 = mrb_get_arg1(mrb);

  return mrb_bool_value(mrb_str_equal(mrb, str1, str2));
}

#=~(a) ⇒ Object



66
67
68
69
70
71
72
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 66

def =~(a)
  begin
    (a.class.to_s == 'String' ? Regexp.new(a.to_s) : a) =~ self
  rescue
    false
  end
end

#[](int) ⇒ Integer? #[](int, int) ⇒ String? #[](range) ⇒ String? #[](other_str) ⇒ String? #slice(int) ⇒ Integer? #slice(int, int) ⇒ String? #slice(range) ⇒ String? #slice(other_str) ⇒ String? Also known as: slice

Element Reference—If passed a single Integer, returns the code of the character at that position. If passed two Integer objects, returns a substring starting at the offset given by the first, and a length given by the second. If given a range, a substring containing characters at offsets given by the range is returned. In all three cases, if an offset is negative, it is counted from the end of str. Returns nil if the initial offset falls outside the string, the length is negative, or the beginning of the range is greater than the end.

If a String is given, that string is returned if it occurs in str. In both cases, nil is returned if there is no match.

a = "hello there"
a[1]                   #=> 101(1.8.7) "e"(1.9.2)
a[1.1]                 #=>            "e"(1.9.2)
a[1,3]                 #=> "ell"
a[1..3]                #=> "ell"
a[-3,2]                #=> "er"
a[-4..-2]              #=> "her"
a[12..-1]              #=> nil
a[-2..-4]              #=> ""
a["lo"]                #=> "lo"
a["bye"]               #=> nil

Overloads:



1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
# File 'mruby/src/string.c', line 1144

static mrb_value
mrb_str_aref_m(mrb_state *mrb, mrb_value str)
{
  mrb_value a1, a2;

  if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) {
    a2 = mrb_undef_value();
  }

  return mrb_str_aref(mrb, str, a1, a2);
}

#[]=(*args) ⇒ Object

XXX: Need pull-request to github.com/mruby/mruby mrbgems/mruby-string-ext



1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
# File 'mruby/src/string.c', line 1320

static mrb_value
mrb_str_aset_m(mrb_state *mrb, mrb_value str)
{
  mrb_value indx, alen, replace;

  switch (mrb_get_args(mrb, "oo|S!", &indx, &alen, &replace)) {
    case 2:
      replace = alen;
      alen = mrb_undef_value();
      break;
    case 3:
      break;
  }
  mrb_str_aset(mrb, str, indx, alen, replace);
  return str;
}

#__linesObject



1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1218

static mrb_value
mrb_str_lines(mrb_state *mrb, mrb_value self)
{
  mrb_value result;
  int ai;
  mrb_int len;
  char *b = RSTRING_PTR(self);
  char *p = b, *t;
  char *e = b + RSTRING_LEN(self);

  mrb->c->ci->mid = 0;
  result = mrb_ary_new(mrb);
  ai = mrb_gc_arena_save(mrb);
  while (p < e) {
    t = p;
    while (p < e && *p != '\n') p++;
    if (*p == '\n') p++;
    len = (mrb_int) (p - t);
    mrb_ary_push(mrb, result, mrb_str_new(mrb, t, len));
    mrb_gc_arena_restore(mrb, ai);
  }
  return result;
}

#__sub_replaceObject

internal



2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
# File 'mruby/src/string.c', line 2903

static mrb_value
sub_replace(mrb_state *mrb, mrb_value self)
{
  char *p, *match;
  mrb_int plen, mlen;
  mrb_int found, offset;
  mrb_value result;

  mrb_get_args(mrb, "ssi", &p, &plen, &match, &mlen, &found);
  result = mrb_str_new(mrb, 0, 0);
  for (mrb_int i=0; i<plen; i++) {
    if (p[i] != '\\' || i+1==plen) {
      mrb_str_cat(mrb, result, p+i, 1);
      continue;
    }
    i++;
    switch (p[i]) {
    case '\\':
      mrb_str_cat(mrb, result, "\\", 1);
      break;
    case '`':
      mrb_str_cat(mrb, result, RSTRING_PTR(self), found);
      break;
    case '&': case '0':
      mrb_str_cat(mrb, result, match, mlen);
      break;
    case '\'':
      offset = found + mlen;
      if (RSTRING_LEN(self) > offset) {
        mrb_str_cat(mrb, result, RSTRING_PTR(self)+offset, RSTRING_LEN(self)-offset);
      }
      break;
    case '1': case '2': case '3':
    case '4': case '5': case '6':
    case '7': case '8': case '9':
      /* ignore sub-group match (no Regexp supported) */
      break;
    default:
      mrb_str_cat(mrb, result, &p[i-1], 2);
      break;
    }
  }
  return result;
}

#__upto_endless(&block) ⇒ Object



441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 441

def __upto_endless(&block)
  len = self.length
  # both edges are all digits
  bi = self.to_i(10)
  if bi > 0 or bi == "0"*len
    while true
      s = bi.to_s
      s = s.rjust(len, "0") if s.length < len
      yield s
      bi += 1
    end
    return self
  end
  bs = self
  while true
    yield bs
    bs = bs.succ
  end
  self
end

#_replace_back_reference(match) ⇒ Object

private



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 196

def _replace_back_reference(match)
  result = ""
  index = 0
  while index < self.length
    current = index
    while current < self.length && self[current] != '\\'
      current += 1
    end
    result += self[index, (current - index)]
    break if current == self.length

    if current == self.length - 1
      result += '\\'
      break
    end
    index = current + 1

    cap = self[index]

    case cap
    when "&"
      result += match[0]
    when "`"
      result += match.pre_match
    when "'"
      result += match.post_match
    when "+"
      result += match.captures.compact[-1].to_s
    when /[0-9]/
      result += match[cap.to_i].to_s
    when '\\'
      result += '\\'
    else
      result += '\\' + cap
    end
    index += 1
  end
  result
end

#byteindex(substring, offset = 0) ⇒ Integer?

Returns the Integer byte-based index of the first occurrence of the given substring, or nil if none found:

'foo'.byteindex('f') # => 0
'foo'.byteindex('oo') # => 1
'foo'.byteindex('ooo') # => nil

Returns:



1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
# File 'mruby/src/string.c', line 1754

static mrb_value
mrb_str_byteindex_m(mrb_state *mrb, mrb_value str)
{
  mrb_value sub;
  mrb_int pos;

  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
    pos = 0;
  }
  else if (pos < 0) {
    pos += RSTRING_LEN(str);
    if (pos < 0) {
      return mrb_nil_value();
    }
  }
  pos = str_index_str(mrb, str, sub, pos);

  if (pos == -1) return mrb_nil_value();
  return mrb_int_value(mrb, pos);
}

#byterindex(substring, offset = self.bytesize) ⇒ Integer?

Returns the Integer byte-based index of the last occurrence of the given substring, or nil if none found:

'foo'.byterindex('f') # => 0
'foo'.byterindex('o') # => 2
'foo'.byterindex('oo') # => 1
'foo'.byterindex('ooo') # => nil

Returns:



2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
# File 'mruby/src/string.c', line 2020

static mrb_value
mrb_str_byterindex_m(mrb_state *mrb, mrb_value str)
{
  mrb_value sub;
  mrb_int pos;
  mrb_int len = RSTRING_LEN(str);

  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
    pos = len;
  }
  else {
    if (pos < 0) {
      pos += len;
      if (pos < 0) {
        return mrb_nil_value();
      }
    }
    if (pos > len) pos = len;
  }
  pos = str_rindex(mrb, str, sub, pos);
  if (pos < 0) {
    return mrb_nil_value();
  }
  return mrb_int_value(mrb, pos);
}

#bytesObject

Returns an array of bytes in str.

str = "hello"
str.bytes       #=> [104, 101, 108, 108, 111]


2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
# File 'mruby/src/string.c', line 2782

static mrb_value
mrb_str_bytes(mrb_state *mrb, mrb_value str)
{
  struct RString *s = mrb_str_ptr(str);
  mrb_value a = mrb_ary_new_capa(mrb, RSTR_LEN(s));
  unsigned char *p = (unsigned char *)(RSTR_PTR(s)), *pend = p + RSTR_LEN(s);

  while (p < pend) {
    mrb_ary_push(mrb, a, mrb_fixnum_value(p[0]));
    p++;
  }
  return a;
}

#bytesizeObject



860
861
862
863
864
865
# File 'mruby/src/string.c', line 860

static mrb_value
mrb_str_bytesize(mrb_state *mrb, mrb_value self)
{
  mrb_int len = RSTRING_LEN(self);
  return mrb_int_value(mrb, len);
}

#byteslice(integer) ⇒ String? #byteslice(integer, integer) ⇒ String? #byteslice(range) ⇒ String?

Byte Reference—If passed a single Integer, returns a substring of one byte at that position. If passed two Integer objects, returns a substring starting at the offset given by the first, and a length given by the second. If given a Range, a substring containing bytes at offsets given by the range is returned. In all three cases, if an offset is negative, it is counted from the end of str. Returns nil if the initial offset falls outside the string, the length is negative, or the beginning of the range is greater than the end. The encoding of the resulted string keeps original encoding.

"hello".byteslice(1)     #=> "e"
"hello".byteslice(-1)    #=> "o"
"hello".byteslice(1, 2)  #=> "el"
"\x80\u3042".byteslice(1, 3) #=> "\u3042"
"\x03\u3042\xff".byteslice(1..3) #=> "\u3042"

Overloads:



2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
# File 'mruby/src/string.c', line 2864

static mrb_value
mrb_str_byteslice(mrb_state *mrb, mrb_value str)
{
  mrb_value a1;
  mrb_int str_len, beg, len;
  mrb_bool empty = TRUE;

  len = mrb_get_argc(mrb);
  switch (len) {
  case 2:
    mrb_get_args(mrb, "ii", &beg, &len);
    str_len = RSTRING_LEN(str);
    break;
  case 1:
    a1 = mrb_get_arg1(mrb);
    str_len = RSTRING_LEN(str);
    if (mrb_range_p(a1)) {
      if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) {
        return mrb_nil_value();
      }
    }
    else {
      beg = mrb_as_int(mrb, a1);
      len = 1;
      empty = FALSE;
    }
    break;
  default:
    mrb_argnum_error(mrb, len, 1, 2);
    break;
  }
  if (mrb_str_beg_len(str_len, &beg, &len) && (empty || len != 0)) {
    return mrb_str_byte_subseq(mrb, str, beg, len);
  }
  else {
    return mrb_nil_value();
  }
}

#capitalizeString

Returns a copy of str with the first character converted to uppercase and the remainder to lowercase.

"hello".capitalize    #=> "Hello"
"HELLO".capitalize    #=> "Hello"
"123ABC".capitalize   #=> "123abc"

Returns:



1387
1388
1389
1390
1391
1392
1393
1394
1395
# File 'mruby/src/string.c', line 1387

static mrb_value
mrb_str_capitalize(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_capitalize_bang(mrb, str);
  return str;
}

#capitalize!String?

Modifies str by converting the first character to uppercase and the remainder to lowercase. Returns nil if no changes are made.

a = "hello"
a.capitalize!   #=> "Hello"
a               #=> "Hello"
a.capitalize!   #=> nil

Returns:



1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
# File 'mruby/src/string.c', line 1350

static mrb_value
mrb_str_capitalize_bang(mrb_state *mrb, mrb_value str)
{
  mrb_bool modify = FALSE;
  struct RString *s = mrb_str_ptr(str);
  mrb_int len = RSTR_LEN(s);

  mrb_str_modify_keep_ascii(mrb, s);
  char *p = RSTR_PTR(s);
  char *pend = RSTR_PTR(s) + len;
  if (len == 0 || p == NULL) return mrb_nil_value();
  if (ISLOWER(*p)) {
    *p = TOUPPER(*p);
    modify = TRUE;
  }
  while (++p < pend) {
    if (ISUPPER(*p)) {
      *p = TOLOWER(*p);
      modify = TRUE;
    }
  }
  if (modify) return str;
  return mrb_nil_value();
}

#casecmp(other_str) ⇒ -1, ...

Case-insensitive version of String#<=>.

"abcdef".casecmp("abcde")     #=> 1
"aBcDeF".casecmp("abcdef")    #=> 0
"abcdef".casecmp("abcdefg")   #=> -1
"abcdef".casecmp("ABCDEF")    #=> 0

Returns:

  • (-1, 0, +1, nil)


1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1177

static mrb_value
mrb_str_casecmp(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  mrb_get_args(mrb, "o", &str);
  if (!mrb_string_p(str)) return mrb_nil_value();

  struct RString *s1 = mrb_str_ptr(self);
  struct RString *s2 = mrb_str_ptr(str);
  mrb_int len = lesser(RSTR_LEN(s1), RSTR_LEN(s2));
  char *p1 = RSTR_PTR(s1);
  char *p2 = RSTR_PTR(s2);

  for (mrb_int i=0; i<len; i++) {
    int c1 = p1[i], c2 = p2[i];
    if (ISASCII(c1) && ISUPPER(c1)) c1 = TOLOWER(c1);
    if (ISASCII(c2) && ISUPPER(c2)) c2 = TOLOWER(c2);
    if (c1 > c2) return mrb_fixnum_value(1);
    if (c1 < c2) return mrb_fixnum_value(-1);
  }
  if (RSTR_LEN(s1) == RSTR_LEN(s2)) return mrb_fixnum_value(0);
  if (RSTR_LEN(s1) > RSTR_LEN(s2))  return mrb_fixnum_value(1);
  return mrb_fixnum_value(-1);
}

#casecmp?(other) ⇒ true, ...

Returns true if str and other_str are equal after case folding, false if they are not equal, and nil if other is not a string.

Returns:

  • (true, false, nil)


1210
1211
1212
1213
1214
1215
1216
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1210

static mrb_value
mrb_str_casecmp_p(mrb_state *mrb, mrb_value self)
{
  mrb_value c = mrb_str_casecmp(mrb, self);
  if (mrb_nil_p(c)) return c;
  return mrb_bool_value(mrb_fixnum(c) == 0);
}

#center(width, padstr = ' ') ⇒ Object

call-seq:

   str.center(width, padstr=' ')   -> new_str

Centers +str+ in +width+. If +width+ is greater than the length of +str+,
returns a new String of length +width+ with +str+ centered and padded with
+padstr+; otherwise, returns +str+.

   "hello".center(4)         #=> "hello"
   "hello".center(20)        #=> "       hello        "
   "hello".center(20, '123') #=> "1231231hello12312312"

Raises:



283
284
285
286
287
288
289
290
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 283

def center(width, padstr = ' ')
  raise ArgumentError, 'zero width padding' if padstr == ''
  return self if width <= self.size
  width -= self.size
  pad1 = width / 2
  pad2 = width - pad1
  (padstr*pad1)[0,pad1] + self + (padstr*pad2)[0,pad2]
end

#chars(&block) ⇒ Object



292
293
294
295
296
297
298
299
300
301
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 292

def chars(&block)
  if block_given?
    self.split('').each do |i|
      block.call(i)
    end
    self
  else
    self.split('')
  end
end

#chomp(separator = "\n") ⇒ String

Returns a new String with the given record separator removed from the end of str (if present). chomp also removes carriage return characters (that is it will remove \n, \r, and \r\n).

"hello".chomp            #=> "hello"
"hello\n".chomp          #=> "hello"
"hello\r\n".chomp        #=> "hello"
"hello\n\r".chomp        #=> "hello\n"
"hello\r".chomp          #=> "hello"
"hello \n there".chomp   #=> "hello \n there"
"hello".chomp("llo")     #=> "he"

Returns:



1491
1492
1493
1494
1495
1496
1497
1498
1499
# File 'mruby/src/string.c', line 1491

static mrb_value
mrb_str_chomp(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_chomp_bang(mrb, str);
  return str;
}

#chomp!(separator = "\n") ⇒ String?

Modifies str in place as described for String#chomp, returning str, or nil if no modifications were made.

Returns:



1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
# File 'mruby/src/string.c', line 1405

static mrb_value
mrb_str_chomp_bang(mrb_state *mrb, mrb_value str)
{
  mrb_value rs;
  mrb_int newline;
  char *p, *pp;
  mrb_int rslen;
  mrb_int len;
  mrb_int argc;
  struct RString *s = mrb_str_ptr(str);

  argc = mrb_get_args(mrb, "|S", &rs);
  mrb_str_modify_keep_ascii(mrb, s);
  len = RSTR_LEN(s);
  if (argc == 0) {
    if (len == 0) return mrb_nil_value();
  smart_chomp:
    if (RSTR_PTR(s)[len-1] == '\n') {
      RSTR_SET_LEN(s, RSTR_LEN(s) - 1);
      if (RSTR_LEN(s) > 0 &&
          RSTR_PTR(s)[RSTR_LEN(s)-1] == '\r') {
        RSTR_SET_LEN(s, RSTR_LEN(s) - 1);
      }
    }
    else if (RSTR_PTR(s)[len-1] == '\r') {
      RSTR_SET_LEN(s, RSTR_LEN(s) - 1);
    }
    else {
      return mrb_nil_value();
    }
    RSTR_PTR(s)[RSTR_LEN(s)] = '\0';
    return str;
  }

  if (len == 0 || mrb_nil_p(rs)) return mrb_nil_value();
  p = RSTR_PTR(s);
  rslen = RSTRING_LEN(rs);
  if (rslen == 0) {
    while (len>0 && p[len-1] == '\n') {
      len--;
      if (len>0 && p[len-1] == '\r')
        len--;
    }
    if (len < RSTR_LEN(s)) {
      RSTR_SET_LEN(s, len);
      p[len] = '\0';
      return str;
    }
    return mrb_nil_value();
  }
  if (rslen > len) return mrb_nil_value();
  newline = RSTRING_PTR(rs)[rslen-1];
  if (rslen == 1 && newline == '\n')
    newline = RSTRING_PTR(rs)[rslen-1];
  if (rslen == 1 && newline == '\n')
    goto smart_chomp;

  pp = p + len - rslen;
  if (p[len-1] == newline &&
     (rslen <= 1 ||
     memcmp(RSTRING_PTR(rs), pp, rslen) == 0)) {
    RSTR_SET_LEN(s, len - rslen);
    p[RSTR_LEN(s)] = '\0';
    return str;
  }
  return mrb_nil_value();
}

#chopString

Returns a new String with the last character removed. If the string ends with \r\n, both characters are removed. Applying chop to an empty string returns an empty string. String#chomp is often a safer alternative, as it leaves the string unchanged if it doesn’t end in a record separator.

"string\r\n".chop   #=> "string"
"string\n\r".chop   #=> "string\n"
"string\n".chop     #=> "string"
"string".chop       #=> "strin"
"x".chop            #=> ""

Returns:



1560
1561
1562
1563
1564
1565
1566
1567
# File 'mruby/src/string.c', line 1560

static mrb_value
mrb_str_chop(mrb_state *mrb, mrb_value self)
{
  mrb_value str;
  str = mrb_str_dup(mrb, self);
  mrb_str_chop_bang(mrb, str);
  return str;
}

#chop!String?

Processes str as for String#chop, returning str, or nil if str is the empty string. See also String#chomp!.

Returns:



1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
# File 'mruby/src/string.c', line 1510

static mrb_value
mrb_str_chop_bang(mrb_state *mrb, mrb_value str)
{
  struct RString *s = mrb_str_ptr(str);

  mrb_str_modify_keep_ascii(mrb, s);
  if (RSTR_LEN(s) > 0) {
    mrb_int len;
#ifdef MRB_UTF8_STRING
    const char* t = RSTR_PTR(s), *p = t;
    const char* e = p + RSTR_LEN(s);
    while (p<e) {
      mrb_int clen = mrb_utf8len(p, e);
      if (p + clen>=e) break;
      p += clen;
    }
    len = p - t;
#else
    len = RSTR_LEN(s) - 1;
#endif
    if (RSTR_PTR(s)[len] == '\n') {
      if (len > 0 &&
          RSTR_PTR(s)[len-1] == '\r') {
        len--;
      }
    }
    RSTR_SET_LEN(s, len);
    RSTR_PTR(s)[len] = '\0';
    return str;
  }
  return mrb_nil_value();
}

#chrString

Returns a one-character string at the beginning of the string.

a = "abcde"
a.chr    #=> "a"

Returns:



861
862
863
864
865
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 861

static mrb_value
mrb_str_chr(mrb_state *mrb, mrb_value self)
{
  return mrb_str_substr(mrb, self, 0, 1);
}

#clearObject

call-seq:

string.clear    ->  string

Makes string empty.

a = "abcde"
a.clear    #=> ""


12
13
14
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 12

def clear
  self.replace("")
end

#codepoints(&block) ⇒ Object Also known as: each_codepoint



316
317
318
319
320
321
322
323
324
325
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 316

def codepoints(&block)
  if block_given?
    self.split('').each do|x|
      block.call(x.ord)
    end
    self
  else
    self.split('').map{|x| x.ord}
  end
end

#<<(obj) ⇒ String #concat(*obj) ⇒ String

s = ‘foo’

s.concat('bar', 'baz') # => "foobarbaz"
s                      # => "foobarbaz"

For each given object object that is an Integer, the value is considered a codepoint and converted to a character before concatenation:

s = 'foo'
s.concat(32, 'bar', 32, 'baz') # => "foo bar baz"

Overloads:



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 175

static mrb_value
mrb_str_concat_m(mrb_state *mrb, mrb_value self)
{
  if (mrb_get_argc(mrb) == 1) {
    str_concat(mrb, self, mrb_get_arg1(mrb));
    return self;
  }

  mrb_value *args;
  mrb_int alen;

  mrb_get_args(mrb, "*", &args, &alen);
  for (mrb_int i=0; i<alen; i++) {
    str_concat(mrb, self, args[i]);
  }
  return self;
}

#countObject

call_seq:

str.count([other_str])   -> integer

Each other_str parameter defines a set of characters to count. The intersection of these sets defines the characters to count in str. Any other_str that starts with a caret ^ is negated. The sequence c1-c2 means all characters between c1 and c2. The backslash character \ can be used to escape ^ or - and is otherwise ignored unless it appears at the end of a sequence or the end of a other_str.



816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 816

static mrb_value
mrb_str_count(mrb_state *mrb, mrb_value str)
{
  mrb_value v_pat = mrb_nil_value();
  mrb_int i;
  char *s;
  mrb_int len;
  mrb_int count = 0;
  struct tr_pattern pat = STATIC_TR_PATTERN;
  uint8_t bitmap[32];

  mrb_get_args(mrb, "S", &v_pat);
  tr_parse_pattern(mrb, &pat, v_pat, TRUE, NULL);
  tr_compile_pattern(&pat, v_pat, bitmap);
  tr_free_pattern(mrb, &pat);

  s = RSTRING_PTR(str);
  len = RSTRING_LEN(str);
  for (i = 0; i < len; i++) {
    if (tr_bitmap_detect(bitmap, s[i])) count++;
  }
  return mrb_fixnum_value(count);
}

#cover?(obj) ⇒ Boolean #cover?(range) ⇒ Boolean

Returns true if the given argument is within self, false otherwise.

With non-range argument object, evaluates with <= and <.

For range self with included end value (#exclude_end? == false), evaluates thus:

self.begin <= object <= self.end

 ("a".."z").cover?("c")    #=> true
 ("a".."z").cover?("5")    #=> false
 ("a".."z").cover?("cc")   #=> true

Overloads:

  • #cover?(obj) ⇒ Boolean

    Returns:

    • (Boolean)
  • #cover?(range) ⇒ Boolean

    Returns:

    • (Boolean)


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'mruby/mrbgems/mruby-range-ext/src/range.c', line 37

static mrb_value
range_cover(mrb_state *mrb, mrb_value range)
{
  struct RRange *r = mrb_range_ptr(mrb, range);
  mrb_value val = mrb_get_arg1(mrb);
  mrb_value beg, end;

  beg = RANGE_BEG(r);
  end = RANGE_END(r);

  if (mrb_nil_p(beg) && mrb_nil_p(end)) return mrb_true_value();

  if (mrb_range_p(val)) {
    struct RRange *r2 = mrb_range_ptr(mrb, val);
    mrb_value beg2 = RANGE_BEG(r2);
    mrb_value end2 = RANGE_END(r2);

    /* range.cover?(nil..nil) => true */
    if (mrb_nil_p(beg2) && mrb_nil_p(end2)) return mrb_true_value();

    /* (a..b).cover?(c..d) */
    if (mrb_nil_p(end)) {       /* a.. */
      /* (a..).cover?(c..) => true */
      if (mrb_nil_p(end2)) return mrb_bool_value(mrb_cmp(mrb, beg, beg2) != -2);
      /* (a..).cover?(c..d) where d<a => false */
      if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value();
      return mrb_true_value();
    }
    else if (mrb_nil_p(beg)) {  /* ..b */
      /* (..b).cover?(..d) => true */
      if (mrb_nil_p(beg2)) return mrb_bool_value(mrb_cmp(mrb, end, end2) != -2);
      /* (..b).cover?(c..d) where b<c => false */
      if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value();
      return mrb_true_value();
    }
    else {                      /* a..b */
      /* (a..b).cover?(c..) => (c<b) */
      if (mrb_nil_p(end2))
        return mrb_bool_value(r_less(mrb, beg2, end, RANGE_EXCL(r)));
      /* (a..b).cover?(..d) => (a<d) */
      if (mrb_nil_p(beg2))
        return mrb_bool_value(r_less(mrb, beg, end2, RANGE_EXCL(r2)));
      /* (a..b).cover?(c..d) where (b<c) => false */
      if (r_less(mrb, end, beg2, RANGE_EXCL(r))) return mrb_false_value();
      /* (a..b).cover?(c..d) where (d<a) => false */
      if (r_less(mrb, end2, beg, RANGE_EXCL(r2))) return mrb_false_value();
      return mrb_true_value();
    }
  }

  if (mrb_nil_p(beg) || r_less(mrb, beg, val, FALSE)) {
    if (mrb_nil_p(end)) {
      return mrb_true_value();
    }
    if (r_less(mrb, val, end, RANGE_EXCL(r)))
      return mrb_true_value();
  }
  return mrb_false_value();
}

#deleteObject



781
782
783
784
785
786
787
788
789
790
791
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 781

static mrb_value
mrb_str_delete(mrb_state *mrb, mrb_value str)
{
  mrb_value pat;
  mrb_value dup;

  mrb_get_args(mrb, "S", &pat);
  dup = mrb_str_dup(mrb, str);
  str_delete(mrb, dup, pat);
  return dup;
}

#delete!Object



793
794
795
796
797
798
799
800
801
802
803
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 793

static mrb_value
mrb_str_delete_bang(mrb_state *mrb, mrb_value str)
{
  mrb_value pat;

  mrb_get_args(mrb, "S", &pat);
  if (str_delete(mrb, str, pat)) {
    return str;
  }
  return mrb_nil_value();
}

#delete_prefix(prefix) ⇒ String

Returns a copy of str with leading prefix deleted.

"hello".delete_prefix("hel") #=> "lo"
"hello".delete_prefix("llo") #=> "hello"

Returns:



1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1094

static mrb_value
mrb_str_del_prefix(mrb_state *mrb, mrb_value self)
{
  mrb_int plen, slen;
  const char *ptr;

  mrb_get_args(mrb, "s", &ptr, &plen);
  slen = RSTRING_LEN(self);
  if (plen > slen) return mrb_str_dup(mrb, self);
  if (memcmp(RSTRING_PTR(self), ptr, plen) != 0)
    return mrb_str_dup(mrb, self);
  return mrb_str_substr(mrb, self, plen, slen-plen);
}

#delete_prefix!(prefix) ⇒ self?

Deletes leading prefix from str, returning nil if no change was made.

"hello".delete_prefix!("hel") #=> "lo"
"hello".delete_prefix!("llo") #=> nil

Returns:

  • (self, nil)


1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1060

static mrb_value
mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self)
{
  mrb_int plen, slen;
  const char *ptr;
  char *s;
  struct RString *str = RSTRING(self);

  mrb_get_args(mrb, "s", &ptr, &plen);
  slen = RSTR_LEN(str);
  if (plen > slen) return mrb_nil_value();
  s = RSTR_PTR(str);
  if (memcmp(s, ptr, plen) != 0) return mrb_nil_value();
  if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
    str->as.heap.ptr += plen;
  }
  else {
    mrb_str_modify(mrb, str);
    s = RSTR_PTR(str);
    memmove(s, s+plen, slen-plen);
  }
  RSTR_SET_LEN(str, slen-plen);
  return self;
}

#delete_suffix(suffix) ⇒ String

Returns a copy of str with leading suffix deleted.

"hello".delete_suffix("hel") #=> "lo"
"hello".delete_suffix("llo") #=> "hello"

Returns:



1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1150

static mrb_value
mrb_str_del_suffix(mrb_state *mrb, mrb_value self)
{
  mrb_int plen, slen;
  const char *ptr;

  mrb_get_args(mrb, "s", &ptr, &plen);
  slen = RSTRING_LEN(self);
  if (plen > slen) return mrb_str_dup(mrb, self);
  if (memcmp(RSTRING_PTR(self)+slen-plen, ptr, plen) != 0)
    return mrb_str_dup(mrb, self);
  return mrb_str_substr(mrb, self, 0, slen-plen);
}

#delete_suffix!(suffix) ⇒ self?

Deletes trailing suffix from str, returning nil if no change was made.

"hello".delete_suffix!("llo") #=> "he"
"hello".delete_suffix!("hel") #=> nil

Returns:

  • (self, nil)


1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1118

static mrb_value
mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self)
{
  mrb_int plen, slen;
  const char *ptr;
  char *s;
  struct RString *str = RSTRING(self);

  mrb_get_args(mrb, "s", &ptr, &plen);
  slen = RSTR_LEN(str);
  if (plen > slen) return mrb_nil_value();
  s = RSTR_PTR(str);
  if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value();
  if (!mrb_frozen_p(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
    /* no need to modify string */
  }
  else {
    mrb_str_modify(mrb, str);
  }
  RSTR_SET_LEN(str, slen-plen);
  return self;
}

#downcaseString

Returns a copy of str with all uppercase letters replaced with their lowercase counterparts. The operation is locale insensitive—only characters ‘A’ to ‘Z’ are affected.

"hEllO".downcase   #=> "hello"

Returns:



1610
1611
1612
1613
1614
1615
1616
1617
1618
# File 'mruby/src/string.c', line 1610

static mrb_value
mrb_str_downcase(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_downcase_bang(mrb, str);
  return str;
}

#downcase!String?

Downcases the contents of str, returning nil if no changes were made.

Returns:



1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
# File 'mruby/src/string.c', line 1577

static mrb_value
mrb_str_downcase_bang(mrb_state *mrb, mrb_value str)
{
  char *p, *pend;
  mrb_bool modify = FALSE;
  struct RString *s = mrb_str_ptr(str);

  mrb_str_modify_keep_ascii(mrb, s);
  p = RSTR_PTR(s);
  pend = RSTR_PTR(s) + RSTR_LEN(s);
  while (p < pend) {
    if (ISUPPER(*p)) {
      *p = TOLOWER(*p);
      modify = TRUE;
    }
    p++;
  }

  if (modify) return str;
  return mrb_nil_value();
}

#dumpString

Produces a version of str with all nonprinting characters replaced by \nnn notation and all special characters escaped.

Returns:



2693
2694
2695
2696
2697
# File 'mruby/src/string.c', line 2693

mrb_value
mrb_str_dump(mrb_state *mrb, mrb_value str)
{
  return str_escape(mrb, str, FALSE);
}

#each_byte(&block) ⇒ Object

Call the given block for each byte of self.



151
152
153
154
155
156
157
158
159
# File 'mruby/mrblib/string.rb', line 151

def each_byte(&block)
  return to_enum(:each_byte, &block) unless block
  pos = 0
  while pos < bytesize
    block.call(getbyte(pos))
    pos += 1
  end
  self
end

#each_char(&block) ⇒ Object

Call the given block for each character of self.



306
307
308
309
310
311
312
313
314
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 306

def each_char(&block)
  return to_enum :each_char unless block
  pos = 0
  while pos < self.size
    block.call(self[pos])
    pos += 1
  end
  self
end

#each_line(separator = "\n", &block) ⇒ Object

Calls the given block for each line and pass the respective line.

ISO 15.2.10.5.15

Raises:



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'mruby/mrblib/string.rb', line 14

def each_line(separator = "\n", &block)
  return to_enum(:each_line, separator) unless block

  if separator.nil?
    block.call(self)
    return self
  end
  raise TypeError unless separator.is_a?(String)

  paragraph_mode = false
  if separator.empty?
    paragraph_mode = true
    separator = "\n\n"
  end
  start = 0
  string = dup
  self_len = self.bytesize
  sep_len = separator.bytesize

  while (pointer = string.byteindex(separator, start))
    pointer += sep_len
    pointer += 1 while paragraph_mode && string.getbyte(pointer) == 10 # 10 == \n
    block.call(string.byteslice(start, pointer - start))
    start = pointer
  end
  return self if start == self_len

  block.call(string.byteslice(start, self_len - start))
  self
end

#empty?Boolean

Returns true if str has a length of zero.

"hello".empty?   #=> false
"".empty?        #=> true

Returns:

  • (Boolean)


1630
1631
1632
1633
1634
1635
1636
# File 'mruby/src/string.c', line 1630

static mrb_value
mrb_str_empty_p(mrb_state *mrb, mrb_value self)
{
  struct RString *s = mrb_str_ptr(self);

  return mrb_bool_value(RSTR_LEN(s) == 0);
}

#end_with?([suffixes]) ⇒ Boolean

Returns true if str ends with one of the suffixes given.

Returns:

  • (Boolean)


236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 236

static mrb_value
mrb_str_end_with(mrb_state *mrb, mrb_value self)
{
  const mrb_value *argv;
  mrb_int argc, i;
  mrb_get_args(mrb, "*", &argv, &argc);

  for (i = 0; i < argc; i++) {
    size_t len_l, len_r;
    int ai = mrb_gc_arena_save(mrb);
    mrb_value sub = argv[i];
    mrb_ensure_string_type(mrb, sub);
    mrb_gc_arena_restore(mrb, ai);
    len_l = RSTRING_LEN(self);
    len_r = RSTRING_LEN(sub);
    if (len_l >= len_r) {
      if (memcmp(RSTRING_PTR(self) + (len_l - len_r),
                 RSTRING_PTR(sub),
                 len_r) == 0) {
        return mrb_true_value();
      }
    }
  }
  return mrb_false_value();
}

#eql?(other) ⇒ Boolean

Two strings are equal if the have the same length and content.

Returns:

  • (Boolean)


1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
# File 'mruby/src/string.c', line 1645

static mrb_value
mrb_str_eql(mrb_state *mrb, mrb_value self)
{
  mrb_value str2 = mrb_get_arg1(mrb);
  mrb_bool eql_p;

  eql_p = (mrb_string_p(str2)) && str_eql(mrb, self, str2);

  return mrb_bool_value(eql_p);
}

#getbyte(index) ⇒ 0 .. 255

returns the indexth byte as an integer.

Returns:

  • (0 .. 255)


2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
# File 'mruby/src/string.c', line 2802

static mrb_value
mrb_str_getbyte(mrb_state *mrb, mrb_value str)
{
  mrb_int pos;
  mrb_get_args(mrb, "i", &pos);

  if (pos < 0)
    pos += RSTRING_LEN(str);
  if (pos < 0 ||  RSTRING_LEN(str) <= pos)
    return mrb_nil_value();

  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]);
}

#gsub(*args, &blk) ⇒ Object

Replace all matches of pattern with replacement. Call block (if given) for each match and replace pattern with the value of the block. Return the final value.

ISO 15.2.10.5.18

Raises:



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'mruby/mrblib/string.rb', line 52

def gsub(*args, &block)
  return to_enum(:gsub, *args) if args.length == 1 && !block
  raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1..2)" unless (1..2).include?(args.length)

  pattern, replace = *args
  plen = pattern.length
  if args.length == 2 && block
    block = nil
  end
  offset = 0
  result = []
  while found = self.byteindex(pattern, offset)
    result << self.byteslice(offset, found - offset)
    offset = found + plen
    result << if block
      block.call(pattern).to_s
    else
      self.__sub_replace(replace, pattern, found)
    end
    if plen == 0
      result << self.byteslice(offset, 1)
      offset += 1
    end
  end
  result << self.byteslice(offset..-1) if offset < length
  result.join
end

#gsub!(*args, &block) ⇒ Object

Replace all matches of pattern with replacement. Call block (if given) for each match and replace pattern with the value of the block. Modify self with the final value.

ISO 15.2.10.5.19

Raises:



87
88
89
90
91
92
93
# File 'mruby/mrblib/string.rb', line 87

def gsub!(*args, &block)
  raise FrozenError, "can't modify frozen String" if frozen?
  return to_enum(:gsub!, *args) if args.length == 1 && !block
  str = self.gsub(*args, &block)
  return nil unless self.index(args[0])
  self.replace(str)
end

#hashInteger

Return a hash based on the string’s length and content.

Returns:



1712
1713
1714
1715
1716
1717
# File 'mruby/src/string.c', line 1712

static mrb_value
mrb_str_hash_m(mrb_state *mrb, mrb_value self)
{
  mrb_int key = mrb_str_hash(mrb, self);
  return mrb_int_value(mrb, key);
}

#hexObject



840
841
842
843
844
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 840

static mrb_value
mrb_str_hex(mrb_state *mrb, mrb_value self)
{
  return mrb_str_to_integer(mrb, self, 16, FALSE);
}

#include?(other_str) ⇒ Boolean #include?(int) ⇒ Boolean

Returns true if str contains the given string or character.

"hello".include? "lo"   #=> true
"hello".include? "ol"   #=> false
"hello".include? ?h     #=> true

Overloads:

  • #include?(other_str) ⇒ Boolean

    Returns:

    • (Boolean)
  • #include?(int) ⇒ Boolean

    Returns:

    • (Boolean)


1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
# File 'mruby/src/string.c', line 1732

static mrb_value
mrb_str_include(mrb_state *mrb, mrb_value self)
{
  mrb_value str2;

  mrb_get_args(mrb, "S", &str2);
  if (str_index_str(mrb, self, str2, 0) < 0)
    return mrb_bool_value(FALSE);
  return mrb_bool_value(TRUE);
}

#index(pat, offs = 0) ⇒ Object

15.2.10.5.22



1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
# File 'mruby/src/string.c', line 1791

static mrb_value
mrb_str_index_m(mrb_state *mrb, mrb_value str)
{
  if (RSTR_ASCII_P(mrb_str_ptr(str))) {
    return mrb_str_byteindex_m(mrb, str);
  }

  mrb_value sub;
  mrb_int pos;

  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
    pos = 0;
  }
  else if (pos < 0) {
    mrb_int clen = RSTRING_CHAR_LEN(str);
    pos += clen;
    if (pos < 0) {
      return mrb_nil_value();
    }
  }
  pos = str_index_str_by_char(mrb, str, sub, pos);

  if (pos == -1) return mrb_nil_value();
  return mrb_int_value(mrb, pos);
}

#replace(other_str) ⇒ String

s = “hello” #=> “hello”

s.replace "world"   #=> "world"

Returns:



1829
1830
1831
1832
1833
1834
1835
1836
# File 'mruby/src/string.c', line 1829

static mrb_value
mrb_str_replace(mrb_state *mrb, mrb_value str)
{
  mrb_value str2;

  mrb_get_args(mrb, "S", &str2);
  return str_replace(mrb, mrb_str_ptr(str), mrb_str_ptr(str2));
}

#insert(idx, str) ⇒ Object

call-seq:

   str.insert(index, other_str)   -> str

Inserts <i>other_str</i> before the character at the given
<i>index</i>, modifying <i>str</i>. Negative indices count from the
end of the string, and insert <em>after</em> the given character.
The intent is insert <i>aString</i> so that it starts at the given
<i>index</i>.

   "abcd".insert(0, 'X')    #=> "Xabcd"
   "abcd".insert(3, 'X')    #=> "abcXd"
   "abcd".insert(4, 'X')    #=> "abcdX"
   "abcd".insert(-3, 'X')   #=> "abXcd"
   "abcd".insert(-1, 'X')   #=> "abcdX"


224
225
226
227
228
229
230
231
232
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 224

def insert(idx, str)
  if idx == -1
    return self << str
  elsif idx < 0
    idx += 1
  end
  self[idx, 0] = str
  self
end

#inspectString

Returns a printable version of str, surrounded by quote marks, with special characters escaped.

str = "hello"
str[3] = "\b"
str.inspect       #=> "\"hel\\bo\""

Returns:



2767
2768
2769
2770
2771
# File 'mruby/src/string.c', line 2767

mrb_value
mrb_str_inspect(mrb_state *mrb, mrb_value str)
{
  return str_escape(mrb, str, TRUE);
}

#internObject #to_symObject

Returns the Symbol corresponding to str, creating the symbol if it did not previously exist.

"Koala".intern         #=> :Koala
s = 'cat'.to_sym       #=> :cat
s == :cat              #=> true
s = '@cat'.to_sym      #=> :@cat
s == :@cat             #=> true

This can also be used to create symbols that cannot be represented using the :xxx notation.

'cat and dog'.to_sym   #=> :"cat and dog"


1879
1880
1881
1882
1883
# File 'mruby/src/string.c', line 1879

MRB_API mrb_value
mrb_str_intern(mrb_state *mrb, mrb_value self)
{
  return mrb_symbol_value(mrb_intern_str(mrb, self));
}

#lengthInteger

Same as sym.to_s.length.

Returns:



853
854
855
856
857
858
# File 'mruby/src/string.c', line 853

static mrb_value
mrb_str_size(mrb_state *mrb, mrb_value self)
{
  mrb_int len = RSTRING_CHAR_LEN(self);
  return mrb_int_value(mrb, len);
}

#lines(&blk) ⇒ Object

call-seq:

  string.lines                ->  array of string
  string.lines {|s| block}    ->  array of string

Returns strings per line;

  a = "abc\ndef"
  a.lines    #=> ["abc\n", "def"]

If a block is given, it works the same as <code>each_line</code>.


357
358
359
360
361
362
363
364
365
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 357

def lines(&blk)
  lines = self.__lines
  if blk
    lines.each do |line|
      blk.call(line)
    end
  end
  lines
end

#ljust(idx, padstr = ' ') ⇒ Object

call-seq:

   str.ljust(integer, padstr=' ')   -> new_str

If <i>integer</i> is greater than the length of <i>str</i>, returns a new
<code>String</code> of length <i>integer</i> with <i>str</i> left justified
and padded with <i>padstr</i>; otherwise, returns <i>str</i>.

   "hello".ljust(4)            #=> "hello"
   "hello".ljust(20)           #=> "hello               "
   "hello".ljust(20, '1234')   #=> "hello123412341234123"

Raises:



245
246
247
248
249
250
251
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 245

def ljust(idx, padstr = ' ')
  raise ArgumentError, 'zero width padding' if padstr == ''
  return self if idx <= self.size
  pad_repetitions = idx / padstr.size
  padding = (padstr * pad_repetitions)[0, idx-self.size]
  self + padding
end

#lstripObject

call-seq:

str.lstrip   -> new_str

Returns a copy of str with leading whitespace removed. See also String#rstrip and String#strip.

"  hello  ".lstrip   #=> "hello  "
"hello".lstrip       #=> "hello"


26
27
28
29
30
31
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 26

def lstrip
  a = 0
  z = self.size - 1
  a += 1 while a <= z and " \f\n\r\t\v".include?(self[a])
  (z >= 0) ? self[a..z] : ""
end

#lstrip!Object

call-seq:

str.lstrip!   -> self or nil

Removes leading whitespace from str, returning nil if no change was made. See also String#rstrip! and String#strip!.

"  hello  ".lstrip   #=> "hello  "
"hello".lstrip!      #=> nil

Raises:



78
79
80
81
82
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 78

def lstrip!
  raise FrozenError, "can't modify frozen String" if frozen?
  s = self.lstrip
  (s == self) ? nil : self.replace(s)
end

#match(re, &block) ⇒ Object



74
75
76
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 74

def match(re, &block)
  Regexp.new(re).match(self, &block)
end

#nextObject



992
993
994
995
996
997
998
999
1000
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 992

static mrb_value
mrb_str_succ(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_succ_bang(mrb, str);
  return str;
}

#succString

Returns next sequence of the string;

a = "abc"
a.succ    #=> "abd"

Returns:



914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 914

static mrb_value
mrb_str_succ_bang(mrb_state *mrb, mrb_value self)
{
  mrb_value result;
  unsigned char *p, *e, *b, *t;
  const char *prepend;
  struct RString *s = mrb_str_ptr(self);
  mrb_int l;

  if (RSTRING_LEN(self) == 0)
    return self;

  mrb_str_modify(mrb, s);
  l = RSTRING_LEN(self);
  b = p = (unsigned char*) RSTRING_PTR(self);
  t = e = p + l;
  *(e--) = 0;

  // find trailing ascii/number
  while (e >= b) {
    if (ISALNUM(*e))
      break;
    e--;
  }
  if (e < b) {
    e = p + l - 1;
    result = mrb_str_new_lit(mrb, "");
  }
  else {
    // find leading letter of the ascii/number
    b = e;
    while (b > p) {
      if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z'))
        break;
      b--;
    }
    if (!ISALNUM(*b))
      b++;
    result = mrb_str_new(mrb, (char*) p, b - p);
  }

  while (e >= b) {
    if (!ISALNUM(*e)) {
      if (*e == 0xff) {
        mrb_str_cat_lit(mrb, result, "\x01");
        (*e) = 0;
      }
      else
        (*e)++;
      break;
    }
    prepend = NULL;
    if (*e == '9') {
      if (e == b) prepend = "1";
      *e = '0';
    }
    else if (*e == 'z') {
      if (e == b) prepend = "a";
      *e = 'a';
    }
    else if (*e == 'Z') {
      if (e == b) prepend = "A";
      *e = 'A';
    }
    else {
      (*e)++;
      break;
    }
    if (prepend) mrb_str_cat_cstr(mrb, result, prepend);
    e--;
  }
  result = mrb_str_cat(mrb, result, (char*) b, t - b);
  l = RSTRING_LEN(result);
  mrb_str_resize(mrb, self, l);
  memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l);
  return self;
}

#octObject



846
847
848
849
850
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 846

static mrb_value
mrb_str_oct(mrb_state *mrb, mrb_value self)
{
  return mrb_str_to_integer(mrb, self, 8, FALSE);
}

#old_gsubObject

Replace all matches of pattern with replacement. Call block (if given) for each match and replace pattern with the value of the block. Return the final value.

ISO 15.2.10.5.18

Raises:



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 33

def gsub(*args, &block)
  return to_enum(:gsub, *args) if args.length == 1 && !block
  raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 1..2)" unless (1..2).include?(args.length)

  pattern, replace = *args
  plen = pattern.length
  if args.length == 2 && block
    block = nil
  end
  offset = 0
  result = []
  while found = self.byteindex(pattern, offset)
    result << self.byteslice(offset, found - offset)
    offset = found + plen
    result << if block
      block.call(pattern).to_s
    else
      self.__sub_replace(replace, pattern, found)
    end
    if plen == 0
      result << self.byteslice(offset, 1)
      offset += 1
    end
  end
  result << self.byteslice(offset..-1) if offset < length
  result.join
end

#old_indexObject

15.2.10.5.22



2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 2

static mrb_value
mrb_str_index_m(mrb_state *mrb, mrb_value str)
{
  if (RSTR_ASCII_P(mrb_str_ptr(str))) {
    return mrb_str_byteindex_m(mrb, str);
  }

  mrb_value sub;
  mrb_int pos;

  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
    pos = 0;
  }
  else if (pos < 0) {
    mrb_int clen = RSTRING_CHAR_LEN(str);
    pos += clen;
    if (pos < 0) {
      return mrb_nil_value();
    }
  }
  pos = str_index_str_by_char(mrb, str, sub, pos);

  if (pos == -1) return mrb_nil_value();
  return mrb_int_value(mrb, pos);
}

#old_slice!Object

call-seq:

str.slice!(fixnum)           -> new_str or nil
str.slice!(fixnum, fixnum)   -> new_str or nil
str.slice!(range)            -> new_str or nil
str.slice!(other_str)        -> new_str or nil

Deletes the specified portion from str, and returns the portion deleted.

string = "this is a string"
string.slice!(2)        #=> "i"
string.slice!(3..6)     #=> " is "
string.slice!("r")      #=> "r"
string                  #=> "thsa sting"

Raises:



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 184

def slice!(arg1, arg2=nil)
  raise FrozenError, "can't modify frozen String" if frozen?
  raise ArgumentError, "wrong number of arguments (expected 1..2)" if arg1.nil? && arg2.nil?

  if !arg1.nil? && !arg2.nil?
    idx = arg1
    idx += self.size if arg1 < 0
    if idx >= 0 && idx <= self.size && arg2 > 0
      str = self[idx, arg2]
    else
      return nil
    end
  else
    validated = false
    if arg1.kind_of?(Range)
      beg = arg1.begin
      ed = arg1.end
      beg += self.size if beg < 0
      ed += self.size if ed < 0
      ed -= 1 if arg1.exclude_end?
      validated = true
    elsif arg1.kind_of?(String)
      validated = true
    else
      idx = arg1
      idx += self.size if arg1 < 0
      validated = true if idx >=0 && arg1 < self.size
    end
    if validated
      str = self[arg1]
    else
      return nil
    end
  end
  unless str.nil? || str == ""
    if !arg1.nil? && !arg2.nil?
      idx = arg1 >= 0 ? arg1 : self.size+arg1
      str2 = self[0...idx] + self[idx+arg2..-1].to_s
    else
      if arg1.kind_of?(Range)
        idx = beg >= 0 ? beg : self.size+beg
        idx2 = ed>= 0 ? ed : self.size+ed
        str2 = self[0...idx] + self[idx2+1..-1].to_s
      elsif arg1.kind_of?(String)
        idx = self.index(arg1)
        str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil?
      else
        idx = arg1 >= 0 ? arg1 : self.size+arg1
        str2 = self[0...idx] + self[idx+1..-1].to_s
      end
    end
    self.replace(str2) unless str2.nil?
  end
  str
end

#split(separator = nil, [limit]) ⇒ Array

Divides str into substrings based on a delimiter, returning an array of these substrings.

If separator is a String, then its contents are used as the delimiter when splitting str. If separator is a single space, str is split on whitespace, with leading whitespace and runs of contiguous whitespace characters ignored.

If separator is omitted or nil (which is the default), str is split on whitespace as if ‘ ’ were specified.

If the limit parameter is omitted, trailing null fields are suppressed. If limit is a positive number, at most that number of fields will be returned (if limit is 1, the entire string is returned as the only entry in an array). If negative, there is no limit to the number of fields returned, and trailing null fields are not suppressed.

" now's  the time".split        #=> ["now's", "the", "time"]
" now's  the time".split(' ')   #=> ["now's", "the", "time"]

"mellow yellow".split("ello")   #=> ["m", "w y", "w"]
"1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]
"1,2,,3,4,,".split(',', 4)      #=> ["1", "2", "", "3,4,,"]
"1,2,,3,4,,".split(',', -4)     #=> ["1", "2", "", "3", "4", "", ""]

Returns:



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 78

static mrb_value
mrb_str_split_m(mrb_state *mrb, mrb_value str)
{
  mrb_int argc;
  mrb_value spat = mrb_nil_value();
  enum {awk, string} split_type = string;
  mrb_int i = 0;
  mrb_int beg;
  mrb_int end;
  mrb_int lim = 0;
  mrb_bool lim_p;
  mrb_value result, tmp;

  argc = mrb_get_args(mrb, "|oi", &spat, &lim);
  lim_p = (lim > 0 && argc == 2);
  if (argc == 2) {
    if (lim == 1) {
      if (RSTRING_LEN(str) == 0)
        return mrb_ary_new_capa(mrb, 0);
      return mrb_ary_new_from_values(mrb, 1, &str);
    }
    i = 1;
  }

  if (argc == 0 || mrb_nil_p(spat)) {
    split_type = awk;
  }
  else if (!mrb_string_p(spat)) {
    mrb_raise(mrb, E_TYPE_ERROR, "expected String");
  }
  else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
    split_type = awk;
  }

  result = mrb_ary_new(mrb);
  beg = 0;
  if (split_type == awk) {
    mrb_bool skip = TRUE;
    mrb_int idx = 0;
    mrb_int str_len = RSTRING_LEN(str);
    unsigned int c;
    int ai = mrb_gc_arena_save(mrb);

    idx = end = beg;
    while (idx < str_len) {
      c = (unsigned char)RSTRING_PTR(str)[idx++];
      if (skip) {
        if (ISSPACE(c)) {
          beg = idx;
        }
        else {
          end = idx;
          skip = FALSE;
          if (lim_p && lim <= i) break;
        }
      }
      else if (ISSPACE(c)) {
        mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg));
        mrb_gc_arena_restore(mrb, ai);
        skip = TRUE;
        beg = idx;
        if (lim_p) i++;
      }
      else {
        end = idx;
      }
    }
  }
  else {                        /* split_type == string */
    mrb_int str_len = RSTRING_LEN(str);
    mrb_int pat_len = RSTRING_LEN(spat);
    mrb_int idx = 0;
    int ai = mrb_gc_arena_save(mrb);

    while (idx < str_len) {
      if (pat_len > 0) {
        end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx);
        if (end < 0) break;
      }
      else {
        end = chars2bytes(str, idx, 1);
      }
      mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end));
      mrb_gc_arena_restore(mrb, ai);
      idx += end + pat_len;
      if (lim_p && lim <= ++i) break;
    }
    beg = idx;
  }
  if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
    if (RSTRING_LEN(str) == beg) {
      tmp = mrb_str_new(mrb, 0, 0);
    }
    else {
      tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
    }
    mrb_ary_push(mrb, result, tmp);
  }
  if (!lim_p && lim == 0) {
    mrb_int len;
    while ((len = RARRAY_LEN(result)) > 0 &&
           (tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0))
      mrb_ary_pop(mrb, result);
  }

  return result;
}

#[](int) ⇒ Integer? #[](int, int) ⇒ String? #[](range) ⇒ String? #[](other_str) ⇒ String? #slice(int) ⇒ Integer? #slice(int, int) ⇒ String? #slice(range) ⇒ String? #slice(other_str) ⇒ String?

Element Reference—If passed a single Integer, returns the code of the character at that position. If passed two Integer objects, returns a substring starting at the offset given by the first, and a length given by the second. If given a range, a substring containing characters at offsets given by the range is returned. In all three cases, if an offset is negative, it is counted from the end of str. Returns nil if the initial offset falls outside the string, the length is negative, or the beginning of the range is greater than the end.

If a String is given, that string is returned if it occurs in str. In both cases, nil is returned if there is no match.

a = "hello there"
a[1]                   #=> 101(1.8.7) "e"(1.9.2)
a[1.1]                 #=>            "e"(1.9.2)
a[1,3]                 #=> "ell"
a[1..3]                #=> "ell"
a[-3,2]                #=> "er"
a[-4..-2]              #=> "her"
a[12..-1]              #=> nil
a[-2..-4]              #=> ""
a["lo"]                #=> "lo"
a["bye"]               #=> nil

Overloads:



159
160
161
162
163
164
165
166
167
168
169
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 159

static mrb_value
mrb_str_aref_m(mrb_state *mrb, mrb_value str)
{
  mrb_value a1, a2;

  if (mrb_get_args(mrb, "o|o", &a1, &a2) == 1) {
    a2 = mrb_undef_value();
  }

  return mrb_str_aref(mrb, str, a1, a2);
}

#old_subObject

Replace only the first match of pattern with replacement. Call block (if given) for each match and replace pattern with the value of the block. Return the final value.

ISO 15.2.10.5.36



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 13

def sub(*args, &block)
  unless (1..2).include?(args.length)
    raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)"
  end

  pattern, replace = *args
  if args.length == 2 && block
    block = nil
  end
  result = []
  found = self.index(pattern)
  return self.dup unless found
  result << self.byteslice(0, found)
  offset = found + pattern.length
  result << if block
    block.call(pattern).to_s
  else
    self.__sub_replace(replace, pattern, found)
  end
  result << self.byteslice(offset..-1) if offset < length
  result.join
end

#ordObject



1041
1042
1043
1044
1045
1046
1047
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 1041

static mrb_value
mrb_str_ord(mrb_state* mrb, mrb_value str)
{
  if (RSTRING_LEN(str) == 0)
    mrb_raise(mrb, E_ARGUMENT_ERROR, "empty string");
  return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[0]);
}

#partition(sep) ⇒ Object

Raises:



114
115
116
117
118
119
120
121
122
123
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 114

def partition(sep)
  raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String
  n = index(sep)
  unless n.nil?
    m = n + sep.size
    [ slice(0, n), sep, slice(m, size - m) ]
  else
    [ self[0..-1], "", "" ]
  end
end

#prepend(*args) ⇒ Object

call-seq:

str.prepend(other_str)  -> str

Prepend—Prepend the given string to str.

a = "world"
a.prepend("hello ") #=> "hello world"
a                   #=> "hello world"


337
338
339
340
341
342
343
344
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 337

def prepend(*args)
  len = args.size
  while len > 0
    len -= 1
    self[0, 0] = args[len]
  end
  self
end

#replace(other_str) ⇒ String

s = “hello” #=> “hello”

s.replace "world"   #=> "world"

Returns:



1829
1830
1831
1832
1833
1834
1835
1836
# File 'mruby/src/string.c', line 1829

static mrb_value
mrb_str_replace(mrb_state *mrb, mrb_value str)
{
  mrb_value str2;

  mrb_get_args(mrb, "S", &str2);
  return str_replace(mrb, mrb_str_ptr(str), mrb_str_ptr(str2));
}

#reverseString

Returns a new string with the characters from str in reverse order.

"stressed".reverse   #=> "desserts"

Returns:



2000
2001
2002
2003
2004
2005
2006
# File 'mruby/src/string.c', line 2000

static mrb_value
mrb_str_reverse(mrb_state *mrb, mrb_value str)
{
  mrb_value str2 = mrb_str_dup(mrb, str);
  mrb_str_reverse_bang(mrb, str2);
  return str2;
}

#reverse!String

Reverses str in place.

Returns:



1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
# File 'mruby/src/string.c', line 1953

static mrb_value
mrb_str_reverse_bang(mrb_state *mrb, mrb_value str)
{
  struct RString *s = mrb_str_ptr(str);
  char *p, *e;

#ifdef MRB_UTF8_STRING
  mrb_int utf8_len = RSTRING_CHAR_LEN(str);
  mrb_int len = RSTR_LEN(s);

  if (utf8_len < 2) return str;
  if (utf8_len < len) {
    mrb_str_modify(mrb, s);
    p = RSTR_PTR(s);
    e = p + RSTR_LEN(s);
    while (p<e) {
      mrb_int clen = mrb_utf8len(p, e);
      str_reverse(p, p + clen - 1);
      p += clen;
    }
    goto bytes;
  }
#endif

  if (RSTR_LEN(s) > 1) {
    mrb_str_modify(mrb, s);
    goto bytes;
  }
  return str;

 bytes:
  p = RSTR_PTR(s);
  e = p + RSTR_LEN(s) - 1;
  str_reverse(p, e);
  return str;
}

#rindexObject

15.2.10.5.31



2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
# File 'mruby/src/string.c', line 2062

static mrb_value
mrb_str_rindex_m(mrb_state *mrb, mrb_value str)
{
  if (RSTR_ASCII_P(mrb_str_ptr(str))) {
    return mrb_str_byterindex_m(mrb, str);
  }

  mrb_value sub;
  mrb_int pos;

  if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) {
    pos = RSTRING_CHAR_LEN(str);
    pos = chars2bytes(str, 0, pos);
  }
  else if (pos >= 0) {
    pos = chars2bytes(str, 0, pos);
  }
  else {
    const char *p = RSTRING_PTR(str);
    const char *e = RSTRING_END(str);
    while (pos++ < 0 && p < e) {
      e = char_backtrack(p, e);
    }
    if (p == e) return mrb_nil_value();
    pos = (mrb_int)(e - p);
  }
  pos = str_rindex(mrb, str, sub, pos);
  if (pos >= 0) {
    pos = bytes2chars(RSTRING_PTR(str), RSTRING_LEN(str), pos);
    BYTES_ALIGN_CHECK(pos);
    return mrb_int_value(mrb, pos);
  }
  return mrb_nil_value();
}

#rjust(idx, padstr = ' ') ⇒ Object

call-seq:

   str.rjust(integer, padstr=' ')   -> new_str

If <i>integer</i> is greater than the length of <i>str</i>, returns a new
<code>String</code> of length <i>integer</i> with <i>str</i> right justified
and padded with <i>padstr</i>; otherwise, returns <i>str</i>.

   "hello".rjust(4)            #=> "hello"
   "hello".rjust(20)           #=> "               hello"
   "hello".rjust(20, '1234')   #=> "123412341234123hello"

Raises:



264
265
266
267
268
269
270
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 264

def rjust(idx, padstr = ' ')
  raise ArgumentError, 'zero width padding' if padstr == ''
  return self if idx <= self.size
  pad_repetitions = idx / padstr.size
  padding = (padstr * pad_repetitions)[0, idx-self.size]
  padding + self
end

#rpartition(sep) ⇒ Object

Raises:



125
126
127
128
129
130
131
132
133
134
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 125

def rpartition(sep)
  raise TypeError, "type mismatch: #{sep.class} given" unless sep.is_a? String
  n = rindex(sep)
  unless n.nil?
    m = n + sep.size
    [ slice(0, n), sep, slice(m, size - m) ]
  else
    [ "", "", self ]
  end
end

#rstripObject

call-seq:

str.rstrip   -> new_str

Returns a copy of str with trailing whitespace removed. See also String#lstrip and String#strip.

"  hello  ".rstrip   #=> "  hello"
"hello".rstrip       #=> "hello"


43
44
45
46
47
48
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 43

def rstrip
  a = 0
  z = self.size - 1
  z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z])
  (z >= 0) ? self[a..z] : ""
end

#rstrip!Object

call-seq:

str.rstrip!   -> self or nil

Removes trailing whitespace from str, returning nil if no change was made. See also String#lstrip! and String#strip!.

"  hello  ".rstrip   #=> "  hello"
"hello".rstrip!      #=> nil

Raises:



95
96
97
98
99
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 95

def rstrip!
  raise FrozenError, "can't modify frozen String" if frozen?
  s = self.rstrip
  (s == self) ? nil : self.replace(s)
end

#scan(*args, &blk) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 236

def scan(*args, &blk)
  if args[0].class == String
    # String#scan has never been implemented.
    raise NotImplementedError, "String#scan is not available"
  end

  i = 0
  ret = []
  while m = args[0].match(self, i)
    val = (m.size == 1 ? m[0] : m.captures)
    if m.end(0) > i
      i = m.end(0)
    else
      i += 1
    end

    if blk
      blk.call(val)
    else
      ret << val
    end
  end

  ret
end

#setbyte(index, integer) ⇒ Integer

modifies the indexth byte as integer.

Returns:



2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
# File 'mruby/src/string.c', line 2822

static mrb_value
mrb_str_setbyte(mrb_state *mrb, mrb_value str)
{
  mrb_int pos, byte;
  mrb_int len;

  mrb_get_args(mrb, "ii", &pos, &byte);

  len = RSTRING_LEN(str);
  if (pos < -len || len <= pos)
    mrb_raisef(mrb, E_INDEX_ERROR, "index %i out of string", pos);
  if (pos < 0)
    pos += len;

  mrb_str_modify(mrb, mrb_str_ptr(str));
  byte &= 0xff;
  RSTRING_PTR(str)[pos] = (unsigned char)byte;
  return mrb_fixnum_value((unsigned char)byte);
}

#lengthInteger

Same as sym.to_s.length.

Returns:



853
854
855
856
857
858
# File 'mruby/src/string.c', line 853

static mrb_value
mrb_str_size(mrb_state *mrb, mrb_value self)
{
  mrb_int len = RSTRING_CHAR_LEN(self);
  return mrb_int_value(mrb, len);
}

#slice!(*args) ⇒ Object

call-seq:

str.slice!(fixnum)           -> new_str or nil
str.slice!(fixnum, fixnum)   -> new_str or nil
str.slice!(range)            -> new_str or nil
str.slice!(other_str)        -> new_str or nil

Deletes the specified portion from str, and returns the portion deleted.

string = "this is a string"
string.slice!(2)        #=> "i"
string.slice!(3..6)     #=> " is "
string.slice!("r")      #=> "r"
string                  #=> "thsa sting"

Raises:



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 152

def slice!(arg1, arg2=nil)
  raise FrozenError, "can't modify frozen String" if frozen?
  raise ArgumentError, "wrong number of arguments (expected 1..2)" if arg1.nil? && arg2.nil?

  if !arg1.nil? && !arg2.nil?
    idx = arg1
    idx += self.size if arg1 < 0
    if idx >= 0 && idx <= self.size && arg2 > 0
      str = self[idx, arg2]
    else
      return nil
    end
  else
    validated = false
    if arg1.kind_of?(Range)
      beg = arg1.begin
      ed = arg1.end
      beg += self.size if beg < 0
      ed += self.size if ed < 0
      ed -= 1 if arg1.exclude_end?
      validated = true
    elsif arg1.kind_of?(String)
      validated = true
    else
      idx = arg1
      idx += self.size if arg1 < 0
      validated = true if idx >=0 && arg1 < self.size
    end
    if validated
      str = self[arg1]
    else
      return nil
    end
  end
  unless str.nil? || str == ""
    if !arg1.nil? && !arg2.nil?
      idx = arg1 >= 0 ? arg1 : self.size+arg1
      str2 = self[0...idx] + self[idx+arg2..-1].to_s
    else
      if arg1.kind_of?(Range)
        idx = beg >= 0 ? beg : self.size+beg
        idx2 = ed>= 0 ? ed : self.size+ed
        str2 = self[0...idx] + self[idx2+1..-1].to_s
      elsif arg1.kind_of?(String)
        idx = self.index(arg1)
        str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil?
      else
        idx = arg1 >= 0 ? arg1 : self.size+arg1
        str2 = self[0...idx] + self[idx+1..-1].to_s
      end
    end
    self.replace(str2) unless str2.nil?
  end
  str
end

#splice(start, count, val) ⇒ Object



343
344
345
# File '.doc_tmp/iij/mruby-regexp-pcre/mrblib/string_pcre.rb', line 343

def splice(start , count, val)
  self.replace(self[0...start] + val + self[(start + count)..-1].to_s)
end

#split(separator = nil, [limit]) ⇒ Array

Divides str into substrings based on a delimiter, returning an array of these substrings.

If separator is a String, then its contents are used as the delimiter when splitting str. If separator is a single space, str is split on whitespace, with leading whitespace and runs of contiguous whitespace characters ignored.

If separator is omitted or nil (which is the default), str is split on whitespace as if ‘ ’ were specified.

If the limit parameter is omitted, trailing null fields are suppressed. If limit is a positive number, at most that number of fields will be returned (if limit is 1, the entire string is returned as the only entry in an array). If negative, there is no limit to the number of fields returned, and trailing null fields are not suppressed.

" now's  the time".split        #=> ["now's", "the", "time"]
" now's  the time".split(' ')   #=> ["now's", "the", "time"]

"mellow yellow".split("ello")   #=> ["m", "w y", "w"]
"1,2,,3,4,,".split(',')         #=> ["1", "2", "", "3", "4"]
"1,2,,3,4,,".split(',', 4)      #=> ["1", "2", "", "3,4,,"]
"1,2,,3,4,,".split(',', -4)     #=> ["1", "2", "", "3", "4", "", ""]

Returns:



2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
# File 'mruby/src/string.c', line 2133

static mrb_value
mrb_str_split_m(mrb_state *mrb, mrb_value str)
{
  mrb_int argc;
  mrb_value spat = mrb_nil_value();
  enum {awk, string} split_type = string;
  mrb_int i = 0;
  mrb_int beg;
  mrb_int end;
  mrb_int lim = 0;
  mrb_bool lim_p;
  mrb_value result, tmp;

  argc = mrb_get_args(mrb, "|oi", &spat, &lim);
  lim_p = (lim > 0 && argc == 2);
  if (argc == 2) {
    if (lim == 1) {
      if (RSTRING_LEN(str) == 0)
        return mrb_ary_new_capa(mrb, 0);
      return mrb_ary_new_from_values(mrb, 1, &str);
    }
    i = 1;
  }

  if (argc == 0 || mrb_nil_p(spat)) {
    split_type = awk;
  }
  else if (!mrb_string_p(spat)) {
    mrb_raise(mrb, E_TYPE_ERROR, "expected String");
  }
  else if (RSTRING_LEN(spat) == 1 && RSTRING_PTR(spat)[0] == ' ') {
    split_type = awk;
  }

  result = mrb_ary_new(mrb);
  beg = 0;
  if (split_type == awk) {
    mrb_bool skip = TRUE;
    mrb_int idx = 0;
    mrb_int str_len = RSTRING_LEN(str);
    unsigned int c;
    int ai = mrb_gc_arena_save(mrb);

    idx = end = beg;
    while (idx < str_len) {
      c = (unsigned char)RSTRING_PTR(str)[idx++];
      if (skip) {
        if (ISSPACE(c)) {
          beg = idx;
        }
        else {
          end = idx;
          skip = FALSE;
          if (lim_p && lim <= i) break;
        }
      }
      else if (ISSPACE(c)) {
        mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, beg, end-beg));
        mrb_gc_arena_restore(mrb, ai);
        skip = TRUE;
        beg = idx;
        if (lim_p) i++;
      }
      else {
        end = idx;
      }
    }
  }
  else {                        /* split_type == string */
    mrb_int str_len = RSTRING_LEN(str);
    mrb_int pat_len = RSTRING_LEN(spat);
    mrb_int idx = 0;
    int ai = mrb_gc_arena_save(mrb);

    while (idx < str_len) {
      if (pat_len > 0) {
        end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx);
        if (end < 0) break;
      }
      else {
        end = chars2bytes(str, idx, 1);
      }
      mrb_ary_push(mrb, result, mrb_str_byte_subseq(mrb, str, idx, end));
      mrb_gc_arena_restore(mrb, ai);
      idx += end + pat_len;
      if (lim_p && lim <= ++i) break;
    }
    beg = idx;
  }
  if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) {
    if (RSTRING_LEN(str) == beg) {
      tmp = mrb_str_new(mrb, 0, 0);
    }
    else {
      tmp = mrb_str_byte_subseq(mrb, str, beg, RSTRING_LEN(str)-beg);
    }
    mrb_ary_push(mrb, result, tmp);
  }
  if (!lim_p && lim == 0) {
    mrb_int len;
    while ((len = RARRAY_LEN(result)) > 0 &&
           (tmp = RARRAY_PTR(result)[len-1], RSTRING_LEN(tmp) == 0))
      mrb_ary_pop(mrb, result);
  }

  return result;
}

#squeeze([other_str]) ⇒ String

Builds a set of characters from the other_str parameter(s) using the procedure described for String#count. Returns a new string where runs of the same character that occur in this set are replaced by a single character. If no arguments are given, all runs of identical characters are replaced by a single character.

"yellow moon".squeeze                  #=> "yelow mon"
"  now   is  the".squeeze(" ")         #=> " now is the"
"putters shoot balls".squeeze("m-z")   #=> "puters shot balls"

Returns:



718
719
720
721
722
723
724
725
726
727
728
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 718

static mrb_value
mrb_str_squeeze(mrb_state *mrb, mrb_value str)
{
  mrb_value pat = mrb_nil_value();
  mrb_value dup;

  mrb_get_args(mrb, "|S", &pat);
  dup = mrb_str_dup(mrb, str);
  str_squeeze(mrb, dup, pat);
  return dup;
}

#squeeze!([other_str]) ⇒ String?

Squeezes str in place, returning either str, or nil if no changes were made.

Returns:



737
738
739
740
741
742
743
744
745
746
747
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 737

static mrb_value
mrb_str_squeeze_bang(mrb_state *mrb, mrb_value str)
{
  mrb_value pat = mrb_nil_value();

  mrb_get_args(mrb, "|S", &pat);
  if (str_squeeze(mrb, str, pat)) {
    return str;
  }
  return mrb_nil_value();
}

#start_with?([prefixes]) ⇒ Boolean

Returns true if str starts with one of the prefixes given.

"hello".start_with?("hell")               #=> true

# returns true if one of the prefixes matches.
"hello".start_with?("heaven", "hell")     #=> true
"hello".start_with?("heaven", "paradise") #=> false
"h".start_with?("heaven", "hell")         #=> false

Returns:

  • (Boolean)


206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 206

static mrb_value
mrb_str_start_with(mrb_state *mrb, mrb_value self)
{
  const mrb_value *argv;
  mrb_int argc, i;
  mrb_get_args(mrb, "*", &argv, &argc);

  for (i = 0; i < argc; i++) {
    size_t len_l, len_r;
    int ai = mrb_gc_arena_save(mrb);
    mrb_value sub = argv[i];
    mrb_ensure_string_type(mrb, sub);
    mrb_gc_arena_restore(mrb, ai);
    len_l = RSTRING_LEN(self);
    len_r = RSTRING_LEN(sub);
    if (len_l >= len_r) {
      if (memcmp(RSTRING_PTR(self), RSTRING_PTR(sub), len_r) == 0) {
        return mrb_true_value();
      }
    }
  }
  return mrb_false_value();
}

#stripObject

call-seq:

str.strip   -> new_str

Returns a copy of str with leading and trailing whitespace removed.

"    hello    ".strip   #=> "hello"
"\tgoodbye\r\n".strip   #=> "goodbye"


59
60
61
62
63
64
65
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 59

def strip
  a = 0
  z = self.size - 1
  a += 1 while a <= z and " \f\n\r\t\v".include?(self[a])
  z -= 1 while a <= z and " \f\n\r\t\v\0".include?(self[z])
  (z >= 0) ? self[a..z] : ""
end

#strip!Object

call-seq:

   str.strip!   -> str or nil

Removes leading and trailing whitespace from <i>str</i>. Returns
<code>nil</code> if <i>str</i> was not altered.

Raises:



108
109
110
111
112
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 108

def strip!
  raise FrozenError, "can't modify frozen String" if frozen?
  s = self.strip
  (s == self) ? nil : self.replace(s)
end

#strip_heredocObject



11
12
13
# File 'gems/carbuncle-support/mrblib/string.rb', line 11

def strip_heredoc
  gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
end

#sub(*args, &blk) ⇒ Object

Replace only the first match of pattern with replacement. Call block (if given) for each match and replace pattern with the value of the block. Return the final value.

ISO 15.2.10.5.36



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'mruby/mrblib/string.rb', line 112

def sub(*args, &block)
  unless (1..2).include?(args.length)
    raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2)"
  end

  pattern, replace = *args
  if args.length == 2 && block
    block = nil
  end
  result = []
  found = self.index(pattern)
  return self.dup unless found
  result << self.byteslice(0, found)
  offset = found + pattern.length
  result << if block
    block.call(pattern).to_s
  else
    self.__sub_replace(replace, pattern, found)
  end
  result << self.byteslice(offset..-1) if offset < length
  result.join
end

#sub!(*args, &block) ⇒ Object

Replace only the first match of pattern with replacement. Call block (if given) for each match and replace pattern with the value of the block. Modify self with the final value.

ISO 15.2.10.5.37

Raises:



142
143
144
145
146
147
# File 'mruby/mrblib/string.rb', line 142

def sub!(*args, &block)
  raise FrozenError, "can't modify frozen String" if frozen?
  str = self.sub(*args, &block)
  return nil unless self.index(args[0])
  self.replace(str)
end

#succObject



992
993
994
995
996
997
998
999
1000
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 992

static mrb_value
mrb_str_succ(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_succ_bang(mrb, str);
  return str;
}

#succString

Returns next sequence of the string;

a = "abc"
a.succ    #=> "abd"

Returns:



914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 914

static mrb_value
mrb_str_succ_bang(mrb_state *mrb, mrb_value self)
{
  mrb_value result;
  unsigned char *p, *e, *b, *t;
  const char *prepend;
  struct RString *s = mrb_str_ptr(self);
  mrb_int l;

  if (RSTRING_LEN(self) == 0)
    return self;

  mrb_str_modify(mrb, s);
  l = RSTRING_LEN(self);
  b = p = (unsigned char*) RSTRING_PTR(self);
  t = e = p + l;
  *(e--) = 0;

  // find trailing ascii/number
  while (e >= b) {
    if (ISALNUM(*e))
      break;
    e--;
  }
  if (e < b) {
    e = p + l - 1;
    result = mrb_str_new_lit(mrb, "");
  }
  else {
    // find leading letter of the ascii/number
    b = e;
    while (b > p) {
      if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z'))
        break;
      b--;
    }
    if (!ISALNUM(*b))
      b++;
    result = mrb_str_new(mrb, (char*) p, b - p);
  }

  while (e >= b) {
    if (!ISALNUM(*e)) {
      if (*e == 0xff) {
        mrb_str_cat_lit(mrb, result, "\x01");
        (*e) = 0;
      }
      else
        (*e)++;
      break;
    }
    prepend = NULL;
    if (*e == '9') {
      if (e == b) prepend = "1";
      *e = '0';
    }
    else if (*e == 'z') {
      if (e == b) prepend = "a";
      *e = 'a';
    }
    else if (*e == 'Z') {
      if (e == b) prepend = "A";
      *e = 'A';
    }
    else {
      (*e)++;
      break;
    }
    if (prepend) mrb_str_cat_cstr(mrb, result, prepend);
    e--;
  }
  result = mrb_str_cat(mrb, result, (char*) b, t - b);
  l = RSTRING_LEN(result);
  mrb_str_resize(mrb, self, l);
  memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l);
  return self;
}

#swapcaseString

Returns a copy of str with uppercase alphabetic characters converted to lowercase and lowercase characters converted to uppercase. Note: case conversion is effective only in ASCII region.

"Hello".swapcase          #=> "hELLO"
"cYbEr_PuNk11".swapcase   #=> "CyBeR_pUnK11"

Returns:



135
136
137
138
139
140
141
142
143
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 135

static mrb_value
mrb_str_swapcase(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_swapcase_bang(mrb, str);
  return str;
}

#swapcase!String?

Equivalent to String#swapcase, but modifies the receiver in place, returning str, or nil if no changes were made. Note: case conversion is effective only in ASCII region.

Returns:



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 98

static mrb_value
mrb_str_swapcase_bang(mrb_state *mrb, mrb_value str)
{
  char *p, *pend;
  int modify = 0;
  struct RString *s = mrb_str_ptr(str);

  mrb_str_modify(mrb, s);
  p = RSTRING_PTR(str);
  pend = p + RSTRING_LEN(str);
  while (p < pend) {
    if (ISUPPER(*p)) {
      *p = TOLOWER(*p);
      modify = 1;
    }
    else if (ISLOWER(*p)) {
      *p = TOUPPER(*p);
      modify = 1;
    }
    p++;
  }

  if (modify) return str;
  return mrb_nil_value();
}

#to_fFloat

Returns the result of interpreting leading characters in str as a floating-point number. Extraneous characters past the end of a valid number are ignored. If there is not a valid number at the start of str, 0.0 is returned. This method never raises an exception.

"123.45e1".to_f        #=> 1234.5
"45.67 degrees".to_f   #=> 45.67
"thx1138".to_f         #=> 0.0

Returns:



2612
2613
2614
2615
2616
# File 'mruby/src/string.c', line 2612

static mrb_value
mrb_str_to_f(mrb_state *mrb, mrb_value self)
{
  return mrb_float_value(mrb, mrb_str_to_dbl(mrb, self, FALSE));
}

#to_i(base = 10) ⇒ Integer

Returns the result of interpreting leading characters in str as an integer base base (between 2 and 36). Extraneous characters past the end of a valid number are ignored. If there is not a valid number at the start of str, 0 is returned. This method never raises an exception.

"12345".to_i             #=> 12345
"99 red balloons".to_i   #=> 99
"0a".to_i                #=> 0
"0a".to_i(16)            #=> 10
"hello".to_i             #=> 0
"1100101".to_i(2)        #=> 101
"1100101".to_i(8)        #=> 294977
"1100101".to_i(10)       #=> 1100101
"1100101".to_i(16)       #=> 17826049

Returns:



2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
# File 'mruby/src/string.c', line 2491

static mrb_value
mrb_str_to_i(mrb_state *mrb, mrb_value self)
{
  mrb_int base = 10;

  mrb_get_args(mrb, "|i", &base);
  if (base < 0 || 36 < base) {
    mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %i", base);
  }
  return mrb_str_to_integer(mrb, self, base, FALSE);
}

#to_sString

Returns the receiver.

Returns:



2626
2627
2628
2629
2630
2631
2632
2633
# File 'mruby/src/string.c', line 2626

static mrb_value
mrb_str_to_s(mrb_state *mrb, mrb_value self)
{
  if (mrb_obj_class(mrb, self) != mrb->string_class) {
    return mrb_str_dup(mrb, self);
  }
  return self;
}

#to_sString

Returns the receiver.

Returns:



2626
2627
2628
2629
2630
2631
2632
2633
# File 'mruby/src/string.c', line 2626

static mrb_value
mrb_str_to_s(mrb_state *mrb, mrb_value self)
{
  if (mrb_obj_class(mrb, self) != mrb->string_class) {
    return mrb_str_dup(mrb, self);
  }
  return self;
}

#internObject #to_symObject

Returns the Symbol corresponding to str, creating the symbol if it did not previously exist.

"Koala".intern         #=> :Koala
s = 'cat'.to_sym       #=> :cat
s == :cat              #=> true
s = '@cat'.to_sym      #=> :@cat
s == :@cat             #=> true

This can also be used to create symbols that cannot be represented using the :xxx notation.

'cat and dog'.to_sym   #=> :"cat and dog"


1879
1880
1881
1882
1883
# File 'mruby/src/string.c', line 1879

MRB_API mrb_value
mrb_str_intern(mrb_state *mrb, mrb_value self)
{
  return mrb_symbol_value(mrb_intern_str(mrb, self));
}

#tr(from_str, to_str) ⇒ String

Returns a copy of str with the characters in from_str replaced by the corresponding characters in to_str. If to_str is shorter than from_str, it is padded with its last character in order to maintain the correspondence.

"hello".tr('el', 'ip')      #=> "hippo"
"hello".tr('aeiou', '*')    #=> "h*ll*"
"hello".tr('aeiou', 'AA*')  #=> "hAll*"

Both strings may use the c1-c2 notation to denote ranges of characters, and from_str may start with a ^, which denotes all characters except those listed.

"hello".tr('a-y', 'b-z')    #=> "ifmmp"
"hello".tr('^aeiou', '*')   #=> "*e**o"

The backslash character \ can be used to escape ^ or - and is otherwise ignored unless it appears at the end of a range or the end of the from_str or to_str:

"hello^world".tr("\\^aeiou", "*") #=> "h*ll**w*rld"
"hello-world".tr("a\\-eo", "*")   #=> "h*ll**w*rld"

"hello\r\nworld".tr("\r", "")   #=> "hello\nworld"
"hello\r\nworld".tr("\\r", "")  #=> "hello\r\nwold"
"hello\r\nworld".tr("\\\r", "") #=> "hello\nworld"

"X['\\b']".tr("X\\", "")   #=> "['b']"
"X['\\b']".tr("X-\\]", "") #=> "'b'"

Note: conversion is effective only in ASCII region.

Returns:



582
583
584
585
586
587
588
589
590
591
592
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 582

static mrb_value
mrb_str_tr(mrb_state *mrb, mrb_value str)
{
  mrb_value dup;
  mrb_value p1, p2;

  mrb_get_args(mrb, "SS", &p1, &p2);
  dup = mrb_str_dup(mrb, str);
  str_tr(mrb, dup, p1, p2, FALSE);
  return dup;
}

#tr!(from_str, to_str) ⇒ String?

Translates str in place, using the same rules as String#tr. Returns str, or nil if no changes were made.

Returns:



601
602
603
604
605
606
607
608
609
610
611
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 601

static mrb_value
mrb_str_tr_bang(mrb_state *mrb, mrb_value str)
{
  mrb_value p1, p2;

  mrb_get_args(mrb, "SS", &p1, &p2);
  if (str_tr(mrb, str, p1, p2, FALSE)) {
    return str;
  }
  return mrb_nil_value();
}

#tr_s(from_str, to_str) ⇒ String

Processes a copy of str as described under String#tr, then removes duplicate characters in regions that were affected by the translation.

"hello".tr_s('l', 'r')     #=> "hero"
"hello".tr_s('el', '*')    #=> "h*o"
"hello".tr_s('el', 'hx')   #=> "hhxo"

Returns:



624
625
626
627
628
629
630
631
632
633
634
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 624

static mrb_value
mrb_str_tr_s(mrb_state *mrb, mrb_value str)
{
  mrb_value dup;
  mrb_value p1, p2;

  mrb_get_args(mrb, "SS", &p1, &p2);
  dup = mrb_str_dup(mrb, str);
  str_tr(mrb, dup, p1, p2, TRUE);
  return dup;
}

#tr_s!(from_str, to_str) ⇒ String?

Performs String#tr_s processing on str in place, returning str, or nil if no changes were made.

Returns:



643
644
645
646
647
648
649
650
651
652
653
# File 'mruby/mrbgems/mruby-string-ext/src/string.c', line 643

static mrb_value
mrb_str_tr_s_bang(mrb_state *mrb, mrb_value str)
{
  mrb_value p1, p2;

  mrb_get_args(mrb, "SS", &p1, &p2);
  if (str_tr(mrb, str, p1, p2, TRUE)) {
    return str;
  }
  return mrb_nil_value();
}

#underscoreObject



2
3
4
5
6
7
8
9
# File 'gems/carbuncle-support/mrblib/string.rb', line 2

def underscore
  gsub(/::/, '/')
    .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
    .gsub(/([a-z\d])([A-Z])/, '\1_\2')
    .tr('-', '_')
    .tr(' ', '_')
    .downcase
end

#upcaseString

Returns a copy of str with all lowercase letters replaced with their uppercase counterparts. The operation is locale insensitive—only characters ‘a’ to ‘z’ are affected.

"hEllO".upcase   #=> "HELLO"

Returns:



2676
2677
2678
2679
2680
2681
2682
2683
2684
# File 'mruby/src/string.c', line 2676

static mrb_value
mrb_str_upcase(mrb_state *mrb, mrb_value self)
{
  mrb_value str;

  str = mrb_str_dup(mrb, self);
  mrb_str_upcase_bang(mrb, str);
  return str;
}

#upcase!String?

Upcases the contents of str, returning nil if no changes were made.

Returns:



2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
# File 'mruby/src/string.c', line 2643

static mrb_value
mrb_str_upcase_bang(mrb_state *mrb, mrb_value str)
{
  struct RString *s = mrb_str_ptr(str);
  char *p, *pend;
  mrb_bool modify = FALSE;

  mrb_str_modify_keep_ascii(mrb, s);
  p = RSTRING_PTR(str);
  pend = RSTRING_END(str);
  while (p < pend) {
    if (ISLOWER(*p)) {
      *p = TOUPPER(*p);
      modify = TRUE;
    }
    p++;
  }

  if (modify) return str;
  return mrb_nil_value();
}

#upto(max, exclusive = false, &block) ⇒ Object

call-seq:

   str.upto(other_str, exclusive=false) {|s| block }   -> str
   str.upto(other_str, exclusive=false)                -> an_enumerator

Iterates through successive values, starting at <i>str</i> and
ending at <i>other_str</i> inclusive, passing each value in turn to
the block. The <code>String#succ</code> method is used to generate
each value. If optional second argument exclusive is omitted or is false,
the last value will be included; otherwise it will be excluded.

If no block is given, an enumerator is returned instead.

   "a8".upto("b6") {|s| print s, ' ' }
   for s in "a8".."b6"
     print s, ' '
   end

<em>produces:</em>

   a8 a9 b0 b1 b2 b3 b4 b5 b6
   a8 a9 b0 b1 b2 b3 b4 b5 b6

If <i>str</i> and <i>other_str</i> contains only ascii numeric characters,
both are recognized as decimal numbers. In addition, the width of
string (e.g. leading zeros) is handled appropriately.

   "9".upto("11").to_a   #=> ["9", "10", "11"]
   "25".upto("5").to_a   #=> []
   "07".upto("11").to_a  #=> ["07", "08", "09", "10", "11"]

Raises:



397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
# File 'mruby/mrbgems/mruby-string-ext/mrblib/string.rb', line 397

def upto(max, exclusive=false, &block)
  return to_enum(:upto, max, exclusive) unless block
  raise TypeError, "no implicit conversion of #{max.class} into String" unless max.kind_of? String

  len = self.length
  maxlen = max.length
  # single character
  if len == 1 and maxlen == 1
    c = self.ord
    e = max.ord
    while c <= e
      break if exclusive and c == e
      yield c.chr(__ENCODING__)
      c += 1
    end
    return self
  end
  # both edges are all digits
  bi = self.to_i(10)
  ei = max.to_i(10)
  if (bi > 0 or bi == "0"*len) and (ei > 0 or ei == "0"*maxlen)
    while bi <= ei
      break if exclusive and bi == ei
      s = bi.to_s
      s = s.rjust(len, "0") if s.length < len
      yield s
      bi += 1
    end
    return self
  end
  bs = self
  while true
    n = (bs <=> max)
    break if n > 0
    break if exclusive and n == 0
    yield bs
    break if n == 0
    bsiz = bs.size
    break if bsiz > max.size || bsiz == 0
    bs = bs.succ
  end
  self
end