summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-array-ext/src/array.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2013-03-15 05:19:06 -0700
committerYukihiro "Matz" Matsumoto <[email protected]>2013-03-15 05:19:06 -0700
commitc5db1397ee4cfe664502eb206ad901945b4ddb20 (patch)
tree7c90620b9ea8210e99beb986f109f766dc2c12c8 /mrbgems/mruby-array-ext/src/array.c
parent75dd4a5aeda402e74ade4b3e74d2ca15eecec009 (diff)
parente6ab9237cc72469dfc6dd3279ce31be4495ac011 (diff)
downloadmruby-c5db1397ee4cfe664502eb206ad901945b4ddb20.tar.gz
mruby-c5db1397ee4cfe664502eb206ad901945b4ddb20.zip
Merge pull request #1009 from skandhas/pr-add-mrb-array-ext
add mrbgem: mruby-array-ext
Diffstat (limited to 'mrbgems/mruby-array-ext/src/array.c')
-rw-r--r--mrbgems/mruby-array-ext/src/array.c140
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..7d7425efd
--- /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_s_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_s_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)
+{
+}