summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/value.h3
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb30
-rw-r--r--mrbgems/mruby-array-ext/test/array.rb14
-rw-r--r--mrbgems/mruby-struct/src/struct.c15
-rw-r--r--mrbgems/mruby-struct/test/struct.rb6
5 files changed, 67 insertions, 1 deletions
diff --git a/include/mruby/value.h b/include/mruby/value.h
index 0bea02706..9ba714cae 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -75,7 +75,8 @@ typedef short mrb_sym;
# define PRIo64 "I64o"
# define PRIx64 "I64x"
# define PRIX64 "I64X"
-# define INFINITY ((float)(DBL_MAX * DBL_MAX))
+static unsigned int IEEE754_INFINITY_BITS_SINGLE = 0x7F800000;
+# define INFINITY (*(float *)&IEEE754_INFINITY_BITS_SINGLE)
# define NAN ((float)(INFINITY - INFINITY))
# else
# include <inttypes.h>
diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb
index 9ef7eb166..bddcd8ab8 100644
--- a/mrbgems/mruby-array-ext/mrblib/array.rb
+++ b/mrbgems/mruby-array-ext/mrblib/array.rb
@@ -657,4 +657,34 @@ class Array
end
self
end
+
+ ##
+ # call-seq:
+ # ary.select! {|item| block } -> ary or nil
+ # ary.select! -> Enumerator
+ #
+ # Invokes the given block passing in successive elements from +self+,
+ # deleting elements for which the block returns a +false+ value.
+ #
+ # If changes were made, it will return +self+, otherwise it returns +nil+.
+ #
+ # See also Array#keep_if
+ #
+ # If no block is given, an Enumerator is returned instead.
+
+ def select!(&block)
+ return to_enum :select! unless block_given?
+
+ idx = 0
+ len = self.size
+ while idx < self.size do
+ if block.call(self[idx])
+ idx += 1
+ else
+ self.delete_at(idx)
+ end
+ end
+ return nil if self.size == len
+ self
+ end
end
diff --git a/mrbgems/mruby-array-ext/test/array.rb b/mrbgems/mruby-array-ext/test/array.rb
index c76423522..f94189356 100644
--- a/mrbgems/mruby-array-ext/test/array.rb
+++ b/mrbgems/mruby-array-ext/test/array.rb
@@ -266,3 +266,17 @@ assert("Array#keep_if") do
assert_equal [4, 5], a.keep_if { |val| val > 3 }
assert_equal [4, 5], a
end
+
+assert("Array#select!") do
+ a = [1, 2, 3, 4, 5]
+ assert_nil a.select! { true }
+ assert_equal [1, 2, 3, 4, 5], a
+
+ a = [1, 2, 3, 4, 5]
+ assert_equal [], a.select! { false }
+ assert_equal [], a
+
+ a = [1, 2, 3, 4, 5]
+ assert_equal [4, 5], a.select! { |val| val > 3 }
+ assert_equal [4, 5], a
+end
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 43cacbc4e..121226717 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -793,6 +793,19 @@ mrb_struct_len(mrb_state *mrb, mrb_value self)
}
/*
+ * call-seq:
+ * struct.to_a -> array
+ * struct.values -> array
+ *
+ * Create an array from struct values.
+ */
+static mrb_value
+mrb_struct_to_a(mrb_state *mrb, mrb_value self)
+{
+ return mrb_ary_new_from_values(mrb, RSTRUCT_LEN(self), RSTRUCT_PTR(self));
+}
+
+/*
* A <code>Struct</code> is a convenient way to bundle a number of
* attributes together, using accessor methods, without having to write
* an explicit class.
@@ -827,6 +840,8 @@ mrb_mruby_struct_gem_init(mrb_state* mrb)
mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE());
mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE());
+ mrb_define_method(mrb, st, "to_a", mrb_struct_to_a, MRB_ARGS_NONE());
+ mrb_define_method(mrb, st, "values", mrb_struct_to_a, MRB_ARGS_NONE());
}
void
diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb
index a250b0ac6..01e3076a5 100644
--- a/mrbgems/mruby-struct/test/struct.rb
+++ b/mrbgems/mruby-struct/test/struct.rb
@@ -112,3 +112,9 @@ assert('Struct#length, Struct#size') do
assert_equal 2, s.size
assert_equal 2, s.length
end
+
+assert('Struct#to_a, Struct#values') do
+ s = Struct.new(:mem1, :mem2).new('a', 'b')
+ assert_equal ['a', 'b'], s.to_a
+ assert_equal ['a', 'b'], s.values
+end