diff --git a/enum.c b/enum.c
index 0e4cf33d121e1a..cf1f0b2971326e 100644
--- a/enum.c
+++ b/enum.c
@@ -193,8 +193,10 @@ find_i(VALUE i, VALUE memop, int argc, VALUE *argv)
*
* Passes each entry in enum to block. Returns the
* first for which block is not false. If no
- * object matches, calls ifnone and returns its result when it
- * is specified, or returns nil
otherwise.
+ * object matches, and ifnone is callable, then it is called
+ * and its result is returned. If there are no matches, and
+ * ifnone is not callable, then ifnone is returned.
+ * Returns nil
otherwise.
*
* If no block is given, an enumerator is returned instead.
*
@@ -217,7 +219,9 @@ enum_find(int argc, VALUE *argv, VALUE obj)
return memo->u1.value;
}
if (!NIL_P(if_none)) {
- return rb_funcall(if_none, rb_intern("call"), 0, 0);
+ VALUE result = rb_check_funcall(if_none, rb_intern("call"), 0, 0);
+ if (result != Qundef) return result;
+ return if_none;
}
return Qnil;
}
diff --git a/test/ruby/test_enum.rb b/test/ruby/test_enum.rb
index 65e9135d69006b..aa41e172a873a1 100644
--- a/test/ruby/test_enum.rb
+++ b/test/ruby/test_enum.rb
@@ -81,6 +81,7 @@ def test_find
assert_equal(2, @obj.find {|x| x % 2 == 0 })
assert_equal(nil, @obj.find {|x| false })
assert_equal(:foo, @obj.find(proc { :foo }) {|x| false })
+ assert_equal(:bar, @obj.find(:bar) {|x| false })
end
def test_find_index
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: