summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/value.h1
-rw-r--r--mrbgems/mruby-hash-ext/mrblib/hash.rb23
-rw-r--r--mrbgems/mruby-hash-ext/test/hash.rb34
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c2
-rw-r--r--src/numeric.c6
5 files changed, 62 insertions, 4 deletions
diff --git a/include/mruby/value.h b/include/mruby/value.h
index 9ba714cae..5c24e8843 100644
--- a/include/mruby/value.h
+++ b/include/mruby/value.h
@@ -60,6 +60,7 @@ typedef short mrb_sym;
# define snprintf _snprintf
# if _MSC_VER < 1800
# include <float.h>
+# define isfinite(n) _finite(n)
# define isnan _isnan
# define isinf(n) (!_finite(n) && !_isnan(n))
# define signbit(n) (_copysign(1.0, (n)) < 0.0)
diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb
index bf3836514..2b089232f 100644
--- a/mrbgems/mruby-hash-ext/mrblib/hash.rb
+++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb
@@ -27,4 +27,27 @@ class Hash
self[key]
end
end
+
+ ##
+ # call-seq:
+ # hsh.delete_if {| key, value | block } -> hsh
+ # hsh.delete_if -> an_enumerator
+ #
+ # Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
+ # evaluates to <code>true</code>.
+ #
+ # If no block is given, an enumerator is returned instead.
+ #
+ # h = { "a" => 100, "b" => 200, "c" => 300 }
+ # h.delete_if {|key, value| key >= "b" } #=> {"a"=>100}
+ #
+
+ def delete_if(&block)
+ return to_enum :delete_if unless block_given?
+
+ self.each do |k, v|
+ self.delete(k) if block.call(k, v)
+ end
+ self
+ end
end
diff --git a/mrbgems/mruby-hash-ext/test/hash.rb b/mrbgems/mruby-hash-ext/test/hash.rb
index 83a064811..4c7dbb217 100644
--- a/mrbgems/mruby-hash-ext/test/hash.rb
+++ b/mrbgems/mruby-hash-ext/test/hash.rb
@@ -39,3 +39,37 @@ assert('Hash#fetch') do
assert_kind_of(StandardError, e);
end
end
+
+assert("Hash#delete_if") do
+ base = { 1 => 'one', 2 => false, true => 'true', 'cat' => 99 }
+ h1 = { 1 => 'one', 2 => false, true => 'true' }
+ h2 = { 2 => false, 'cat' => 99 }
+ h3 = { 2 => false }
+
+ h = base.dup
+ assert_equal(h, h.delete_if { false })
+ assert_equal({}, h.delete_if { true })
+
+ h = base.dup
+ assert_equal(h1, h.delete_if {|k,v| k.instance_of?(String) })
+ assert_equal(h1, h)
+
+ h = base.dup
+ assert_equal(h2, h.delete_if {|k,v| v.instance_of?(String) })
+ assert_equal(h2, h)
+
+ h = base.dup
+ assert_equal(h3, h.delete_if {|k,v| v })
+ assert_equal(h3, h)
+
+ h = base.dup
+ n = 0
+ h.delete_if {|*a|
+ n += 1
+ assert_equal(2, a.size)
+ assert_equal(base[a[0]], a[1])
+ h.shift
+ true
+ }
+ assert_equal(base.size, n)
+end
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index a82a674cf..31f22975d 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -999,7 +999,7 @@ retry:
char fbuf[32];
fval = mrb_float(mrb_Float(mrb, val));
- if (isnan(fval) || isinf(fval)) {
+ if (!isfinite(fval)) {
const char *expr;
const int elen = 3;
diff --git a/src/numeric.c b/src/numeric.c
index 4c955a61e..56835edbf 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -309,7 +309,7 @@ flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *
}
else {
mod = fmod(x, y);
- if (isinf(x) && !isinf(y) && !isnan(y))
+ if (isinf(x) && isfinite(y))
div = x;
else
div = (x - mod) / y;
@@ -495,7 +495,7 @@ flo_finite_p(mrb_state *mrb, mrb_value num)
{
mrb_float value = mrb_float(num);
- return mrb_bool_value(!(isinf(value) || isnan(value)));
+ return mrb_bool_value(isfinite(value));
}
/* 15.2.9.3.10 */
@@ -626,7 +626,7 @@ flo_round(mrb_state *mrb, mrb_value num)
}
if (ndigits > 0) {
- if (isinf(number) || isnan(number)) return num;
+ if (!isfinite(number)) return num;
return mrb_float_value(mrb, number);
}
return mrb_fixnum_value((mrb_int)number);