Feature #15588 ยป patch.diff
string.c | ||
---|---|---|
return rb_str_enumerate_chars(str, 0);
|
||
}
|
||
static long
|
||
each_chunk_size(VALUE str, VALUE rb_len)
|
||
{
|
||
long len, str_len, size;
|
||
len = NUM2LONG(rb_len);
|
||
if (len <= 0) {
|
||
return 0;
|
||
}
|
||
str_len = rb_str_strlen(str);
|
||
size = (str_len + (len - 1)) / len; /* ceil */
|
||
return size;
|
||
}
|
||
static VALUE
|
||
rb_str_each_chunk_size(VALUE str, VALUE args, VALUE eobj)
|
||
{
|
||
VALUE rb_len = RARRAY_AREF(args, 0);
|
||
long size = each_chunk_size(str, rb_len);
|
||
if (size > 0) {
|
||
return LONG2NUM(size);
|
||
} else {
|
||
return Qnil;
|
||
}
|
||
}
|
||
static VALUE rb_str_strip(VALUE str);
|
||
static VALUE
|
||
rb_str_enumerate_chunk(int argc, VALUE *argv, VALUE str, VALUE ary)
|
||
{
|
||
VALUE rb_len, opts, substr, strip = Qfalse, orig = str;
|
||
long i, len, str_len;
|
||
rb_scan_args(argc, argv, "1:", &rb_len, &opts);
|
||
len = NUM2LONG(rb_len);
|
||
if (len <= 0) {
|
||
rb_raise(rb_eArgError, "length of chunk should be a positive number");
|
||
}
|
||
if (!NIL_P(opts)) {
|
||
static ID keywords[1];
|
||
if (!keywords[0]) {
|
||
keywords[0] = rb_intern_const("strip");
|
||
}
|
||
rb_get_kwargs(opts, keywords, 0, 1, &strip);
|
||
strip = (strip!= Qundef && RTEST(strip));
|
||
}
|
||
str = rb_str_new_frozen(str);
|
||
str_len = rb_str_strlen(str);
|
||
for (i = 0; i*len < str_len; i++) {
|
||
substr = rb_str_substr(str, i*len, len);
|
||
if (strip) {
|
||
substr = rb_str_strip(substr);
|
||
}
|
||
ENUM_ELEM(ary, substr);
|
||
}
|
||
RB_GC_GUARD(str);
|
||
if (ary)
|
||
return ary;
|
||
else
|
||
return orig;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* str.each_chunk(length, strip: false) {|chunk| block } -> str
|
||
* str.each_chunk(length, strip: false) -> an_enumerator
|
||
*
|
||
* Passes each chunk size of length in <i>str</i> to the given block,
|
||
* or returns an enumerator if no block is given.
|
||
*
|
||
* "hello hello\nhello".each_chunk(6) {|c| p c }
|
||
* "hello hello\nhello".each_chunk(6, strip: true) {|c| p c }
|
||
*
|
||
* <em>produces:</em>
|
||
*
|
||
* "hello "
|
||
* "hello\n"
|
||
* "hello"
|
||
*
|
||
* "hello"
|
||
* "hello"
|
||
* "hello"
|
||
*/
|
||
static VALUE
|
||
rb_str_each_chunk(int argc, VALUE *argv, VALUE str)
|
||
{
|
||
RETURN_SIZED_ENUMERATOR(str, argc, argv, rb_str_each_chunk_size);
|
||
return rb_str_enumerate_chunk(argc, argv, str, 0);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* str.chunks(length, strip: false) -> an_array
|
||
*
|
||
* Returns an array of chunks size of length in <i>str</i>. This is a
|
||
* shorthand for <code>str.each_chunk(length, strip: bool).to_a</code>.
|
||
*
|
||
* "hello hello\nhello".chunks(6) #=> ["hello ", "hello\n", "hello"]
|
||
* "hello hello\nhello".chunks(6, strip: true) #=> ["hello", "hello", "hello"]
|
||
*
|
||
*/
|
||
static VALUE
|
||
rb_str_chunks(int argc, VALUE *argv, VALUE str)
|
||
{
|
||
VALUE rb_len, opts, ary;
|
||
rb_scan_args(argc, argv, "1:", &rb_len, &opts);
|
||
ary = WANTARRAY("chunks", each_chunk_size(str, rb_len));
|
||
return rb_str_enumerate_chunk(argc, argv, str, ary);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* str.chars -> an_array
|
||
... | ... | |
rb_define_method(rb_cString, "chars", rb_str_chars, 0);
|
||
rb_define_method(rb_cString, "codepoints", rb_str_codepoints, 0);
|
||
rb_define_method(rb_cString, "grapheme_clusters", rb_str_grapheme_clusters, 0);
|
||
rb_define_method(rb_cString, "chunks", rb_str_chunks, -1);
|
||
rb_define_method(rb_cString, "reverse", rb_str_reverse, 0);
|
||
rb_define_method(rb_cString, "reverse!", rb_str_reverse_bang, 0);
|
||
rb_define_method(rb_cString, "concat", rb_str_concat_multi, -1);
|
||
... | ... | |
rb_define_method(rb_cString, "each_char", rb_str_each_char, 0);
|
||
rb_define_method(rb_cString, "each_codepoint", rb_str_each_codepoint, 0);
|
||
rb_define_method(rb_cString, "each_grapheme_cluster", rb_str_each_grapheme_cluster, 0);
|
||
rb_define_method(rb_cString, "each_chunk", rb_str_each_chunk, -1);
|
||
rb_define_method(rb_cString, "sum", rb_str_sum, -1);
|
||
test/ruby/test_string.rb | ||
---|---|---|
end
|
||
end
|
||
def test_each_chunk
|
||
s = S("hello world\nhello")
|
||
res = []
|
||
s.each_chunk(6) {|x| res << x }
|
||
assert_equal([S("hello "), S("world\n"), S("hello")], res)
|
||
res = []
|
||
s.each_chunk(6, strip: true) {|x| res << x }
|
||
assert_equal([S("hello"), S("world"), S("hello")], res)
|
||
assert_equal s.each_chunk(s.size).to_a, [s]
|
||
assert_equal s.each_chunk(65536).to_a, [s]
|
||
assert_equal s.each_chunk(6).size, 3
|
||
assert_equal s.each_chunk(0).size, nil
|
||
assert_equal s.each_chunk(-1).size, nil
|
||
assert_equal s.each_chunk(s.size).size, 1
|
||
assert_equal s.each_chunk(65536).size, 1
|
||
assert_raise(ArgumentError) { s.each_chunk(0).each {} }
|
||
assert_raise(ArgumentError) { s.each_chunk(-1).each {} }
|
||
s = S("\u{3053 3093 306b 3061 306f 0020 3053 3093 306b 3061 306f 000a 3053 3093 306b 3061 306f}")
|
||
res = []
|
||
s.each_chunk(6) {|x| res << x }
|
||
assert_equal([S("\u{3053 3093 306b 3061 306f 0020}"), S("\u{3053 3093 306b 3061 306f 000a}"), S("\u{3053 3093 306b 3061 306f}")], res)
|
||
res = []
|
||
s.each_chunk(6, strip: true) {|x| res << x }
|
||
assert_equal([S("\u{3053 3093 306b 3061 306f}"), S("\u{3053 3093 306b 3061 306f}"), S("\u{3053 3093 306b 3061 306f}")], res)
|
||
assert_equal s.each_chunk(6).size, 3
|
||
assert_equal s.each_chunk(s.size).size, 1
|
||
end
|
||
def test_chunks
|
||
s = S("hello world\nhello")
|
||
assert_equal ["hello ", "world\n", "hello"], s.chunks(6)
|
||
assert_equal ["hello", "world", "hello"], s.chunks(6, strip: true)
|
||
assert_equal s.chunks(1), s.chars
|
||
assert_equal s.chunks(65536), [s]
|
||
s = S("\u{3053 3093 306b 3061 306f 0020 3053 3093 306b 3061 306f 000a 3053 3093 306b 3061 306f}")
|
||
assert_equal [S("\u{3053 3093 306b 3061 306f 0020}"), S("\u{3053 3093 306b 3061 306f 000a}"), S("\u{3053 3093 306b 3061 306f}")], s.chunks(6)
|
||
assert_equal [S("\u{3053 3093 306b 3061 306f}"), S("\u{3053 3093 306b 3061 306f}"), S("\u{3053 3093 306b 3061 306f}")], s.chunks(6, strip: true)
|
||
assert_equal s.chunks(1), s.chars
|
||
s = S("hello world\nhello")
|
||
assert_raise(ArgumentError) { s.chunks(0) }
|
||
assert_raise(ArgumentError) { s.chunks(-1) }
|
||
s = S("")
|
||
assert_equal s.chunks(1), []
|
||
end
|
||
def test_empty?
|
||
assert_empty(S(""))
|
||
assert_not_empty(S("not"))
|