diff options
| -rw-r--r-- | include/mruby/value.h | 3 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/mrblib/array.rb | 30 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/test/array.rb | 14 | ||||
| -rw-r--r-- | mrbgems/mruby-struct/src/struct.c | 15 | ||||
| -rw-r--r-- | mrbgems/mruby-struct/test/struct.rb | 6 |
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 |
