diff options
| author | skandhas <[email protected]> | 2013-03-15 11:28:01 +0800 |
|---|---|---|
| committer | skandhas <[email protected]> | 2013-03-15 11:28:01 +0800 |
| commit | 6c284ec31f470681e333bac431d3a074fc1d27fd (patch) | |
| tree | 5fcbdcc74899499464eb0506c440c4c239496b4b /mrbgems/mruby-array-ext/src/array.c | |
| parent | 75dd4a5aeda402e74ade4b3e74d2ca15eecec009 (diff) | |
| download | mruby-6c284ec31f470681e333bac431d3a074fc1d27fd.tar.gz mruby-6c284ec31f470681e333bac431d3a074fc1d27fd.zip | |
add mrbgem: mrb-array-ext
Diffstat (limited to 'mrbgems/mruby-array-ext/src/array.c')
| -rw-r--r-- | mrbgems/mruby-array-ext/src/array.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c new file mode 100644 index 000000000..71516fdf7 --- /dev/null +++ b/mrbgems/mruby-array-ext/src/array.c @@ -0,0 +1,140 @@ +#include "mruby.h" +#include "mruby/value.h" +#include "mruby/array.h" + +/* + * call-seq: + * Array.try_convert(obj) -> array or nil + * + * Try to convert <i>obj</i> into an array, using +to_ary+ method. + * Returns converted array or +nil+ if <i>obj</i> cannot be converted + * for any reason. This method can be used to check if an argument is an + * array. + * + * Array.try_convert([1]) #=> [1] + * Array.try_convert("1") #=> nil + * + * if tmp = Array.try_convert(arg) + * # the argument is an array + * elsif tmp = String.try_convert(arg) + * # the argument is a string + * end + * + */ + +static mrb_value +mrb_ary_try_convert(mrb_state *mrb, mrb_value self) +{ + mrb_value ary; + + mrb_get_args(mrb, "o", &ary); + return mrb_check_array_type(mrb, ary); +} + +/* + * call-seq: + * ary.assoc(obj) -> new_ary or nil + * + * Searches through an array whose elements are also arrays + * comparing _obj_ with the first element of each contained array + * using obj.==. + * Returns the first contained array that matches (that + * is, the first associated array), + * or +nil+ if no match is found. + * See also <code>Array#rassoc</code>. + * + * s1 = [ "colors", "red", "blue", "green" ] + * s2 = [ "letters", "a", "b", "c" ] + * s3 = "foo" + * a = [ s1, s2, s3 ] + * a.assoc("letters") #=> [ "letters", "a", "b", "c" ] + * a.assoc("foo") #=> nil + */ + +static mrb_value +mrb_ary_assoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, k; + + mrb_get_args(mrb, "o", &k); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]); + if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 && + mrb_equal(mrb, RARRAY_PTR(v)[0], k)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.rassoc(obj) -> new_ary or nil + * + * Searches through the array whose elements are also arrays. Compares + * _obj_ with the second element of each contained array using + * <code>==</code>. Returns the first contained array that matches. See + * also <code>Array#assoc</code>. + * + * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + * a.rassoc("two") #=> [2, "two"] + * a.rassoc("four") #=> nil + */ + +static mrb_value +mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, value; + + mrb_get_args(mrb, "o", &value); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = RARRAY_PTR(ary)[i]; + if (mrb_type(v) == MRB_TT_ARRAY && + RARRAY_LEN(v) > 1 && + mrb_equal(mrb, RARRAY_PTR(v)[1], value)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.at(index) -> obj or nil + * + * Returns the element at _index_. A + * negative index counts from the end of +self+. Returns +nil+ + * if the index is out of range. See also <code>Array#[]</code>. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.at(0) #=> "a" + * a.at(-1) #=> "e" + */ + +static mrb_value +mrb_ary_at(mrb_state *mrb, mrb_value ary) +{ + mrb_int pos; + mrb_get_args(mrb, "i", &pos); + + return mrb_ary_entry(ary, pos); +} + +void +mrb_mruby_array_ext_gem_init(mrb_state* mrb) +{ + struct RClass * a = mrb->array_class; + + mrb_define_class_method(mrb, a, "try_convert", mrb_ary_try_convert, ARGS_REQ(1)); + + mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, ARGS_REQ(1)); + mrb_define_method(mrb, a, "at", mrb_ary_at, ARGS_REQ(1)); + mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, ARGS_REQ(1)); +} + +void +mrb_mruby_array_ext_gem_final(mrb_state* mrb) +{ +} |
