mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge pull request #1009 from skandhas/pr-add-mrb-array-ext
add mrbgem: mruby-array-ext
This commit is contained in:
@@ -29,6 +29,9 @@ MRuby::Build.new do |conf|
|
||||
# Use extensional Numeric class
|
||||
conf.gem "#{root}/mrbgems/mruby-numeric-ext"
|
||||
|
||||
# Use extensional Array class
|
||||
conf.gem "#{root}/mrbgems/mruby-array-ext"
|
||||
|
||||
# Generate binaries
|
||||
# conf.bins = %w(mrbc mruby mirb)
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
MRuby::Gem::Specification.new('mruby-array-ext') do |spec|
|
||||
spec.license = 'MIT'
|
||||
spec.authors = 'mruby developers'
|
||||
end
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
##
|
||||
# Array(Ext) Test
|
||||
|
||||
assert("Array::try_convert") do
|
||||
Array.try_convert([1]) == [1] and
|
||||
Array.try_convert("1").nil?
|
||||
end
|
||||
|
||||
assert("Array#assoc") do
|
||||
s1 = [ "colors", "red", "blue", "green" ]
|
||||
s2 = [ "letters", "a", "b", "c" ]
|
||||
s3 = "foo"
|
||||
a = [ s1, s2, s3 ]
|
||||
|
||||
a.assoc("letters") == [ "letters", "a", "b", "c" ] and
|
||||
a.assoc("foo").nil?
|
||||
end
|
||||
|
||||
assert("Array#at") do
|
||||
a = [ "a", "b", "c", "d", "e" ]
|
||||
a.at(0) == "a" and a.at(-1) == "e"
|
||||
end
|
||||
|
||||
assert("Array#rassoc") do
|
||||
a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
|
||||
|
||||
a.rassoc("two") == [2, "two"] and
|
||||
a.rassoc("four").nil?
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user