Commit f18771eb authored by mattn's avatar mattn

Add String#chars, String#each_char, String#codepoints, String#each_codepoint

parent c31c6c08
#include "mruby.h"
#include "mruby/array.h"
#include "mruby/class.h"
#include "mruby/string.h"
#include "mruby/range.h"
#include "mruby/re.h"
......@@ -671,6 +672,66 @@ mrb_str_chr(mrb_state *mrb, mrb_value self)
return str_substr(mrb, self, 0, 1);
}
static mrb_value
mrb_str_chars(mrb_state *mrb, mrb_value self)
{
mrb_value result;
mrb_value blk;
char *p = RSTRING_PTR(self);
char *e = p + RSTRING_LEN(self);
mrb_get_args(mrb, "&", &blk);
result = mrb_ary_new(mrb);
if (!mrb_nil_p(blk)) {
mrb_value arg;
while (p < e) {
mrb_int len = utf8len((unsigned char*) p);
arg = mrb_str_new(mrb, p, len);
mrb_yield_argv(mrb, blk, 1, &arg);
p += len;
}
return self;
}
while (p < e) {
mrb_int len = utf8len((unsigned char*) p);
mrb_ary_push(mrb, result, mrb_str_new(mrb, p, len));
p += len;
}
return result;
}
static mrb_value
mrb_str_codepoints(mrb_state *mrb, mrb_value self)
{
mrb_value result;
mrb_value blk;
char *p = RSTRING_PTR(self);
char *e = p + RSTRING_LEN(self);
mrb_get_args(mrb, "&", &blk);
result = mrb_ary_new(mrb);
if (!mrb_nil_p(blk)) {
mrb_value arg;
while (p < e) {
mrb_int len = utf8len((unsigned char*) p);
arg = mrb_fixnum_value(utf8code((unsigned char*) p));
mrb_yield_argv(mrb, blk, 1, &arg);
p += len;
}
return self;
}
while (p < e) {
mrb_int len = utf8len((unsigned char*) p);
mrb_ary_push(mrb, result, mrb_fixnum_value(utf8code((unsigned char*) p)));
p += len;
}
return result;
}
void
mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
{
......@@ -687,6 +748,10 @@ mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "rindex", mrb_str_rindex_m, MRB_ARGS_ANY());
mrb_define_method(mrb, s, "chr", mrb_str_chr, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "chars", mrb_str_chars, MRB_ARGS_NONE());
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "each_char"), mrb_intern_lit(mrb, "chars"));
mrb_define_method(mrb, s, "codepoints", mrb_str_codepoints, MRB_ARGS_NONE());
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "each_codepoint"), mrb_intern_lit(mrb, "codepoints"));
mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
}
......
......@@ -70,3 +70,40 @@ end
assert('String#chr') do
assert_equal "こ", "こんにちは世界!".chr
end
assert('String#chars') do
expect = ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!']
assert_equal expect, "こんにちは世界!".chars
s = ""
"こんにちは世界!".chars do |x|
s += x
end
assert_equal "こんにちは世界!", s
end
assert('String#each_char') do
expect = ['こ', 'ん', 'に', 'ち', 'は', '世', '界', '!']
s = ""
"こんにちは世界!".each_char do |x|
s += x
end
assert_equal "こんにちは世界!", s
end
assert('String#codepoints') do
expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33]
assert_equal expect, "こんにちは世界!".codepoints
cp = []
"こんにちは世界!".codepoints do |x|
cp << x
end
assert_equal expect, cp
end
assert('String#each_codepoint') do
expect = [12371, 12435, 12395, 12385, 12399, 19990, 30028, 33]
cp = []
"こんにちは世界!".each_codepoint do |x|
cp << x
end
assert_equal expect, cp
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment