Skip to content

Commit 97c2bbe

Browse files
authored
Merge pull request #2767 from ruby/ruby-module
Add `Ruby`, `Array#find`, and `Array#rfind`
2 parents 398b07d + c88354c commit 97c2bbe

File tree

4 files changed

+154
-0
lines changed

4 files changed

+154
-0
lines changed

core/array.rbs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2019,6 +2019,32 @@ class Array[unchecked out Elem] < Object
20192019
def filter!: () { (Elem item) -> boolish } -> self?
20202020
| () -> ::Enumerator[Elem, self?]
20212021

2022+
# <!--
2023+
# rdoc-file=array.c
2024+
# - find(if_none_proc = nil) {|element| ... } -> object or nil
2025+
# - find(if_none_proc = nil) -> enumerator
2026+
# -->
2027+
# Returns the first element for which the block returns a truthy value.
2028+
#
2029+
# With a block given, calls the block with successive elements of the array;
2030+
# returns the first element for which the block returns a truthy value:
2031+
#
2032+
# (0..9).find {|element| element > 2} # => 3
2033+
#
2034+
# If no such element is found, calls `if_none_proc` and returns its return
2035+
# value.
2036+
#
2037+
# (0..9).find(proc {false}) {|element| element > 12} # => false
2038+
# {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1]
2039+
# {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => []
2040+
#
2041+
# With no block given, returns an Enumerator.
2042+
#
2043+
def find: () { (Elem) -> boolish } -> Elem?
2044+
| () -> ::Enumerator[Elem, Elem?]
2045+
| [T] (Enumerable::_NotFound[T] ifnone) { (Elem) -> boolish } -> (Elem | T)
2046+
| [T] (Enumerable::_NotFound[T] ifnone) -> ::Enumerator[Elem, Elem | T]
2047+
20222048
# <!--
20232049
# rdoc-file=array.c
20242050
# - find_index(object) -> integer or nil
@@ -2988,6 +3014,33 @@ class Array[unchecked out Elem] < Object
29883014
def reverse_each: () { (Elem item) -> void } -> self
29893015
| () -> ::Enumerator[Elem, self]
29903016

3017+
# <!--
3018+
# rdoc-file=array.c
3019+
# - rfind(if_none_proc = nil) {|element| ... } -> object or nil
3020+
# - rfind(if_none_proc = nil) -> enumerator
3021+
# -->
3022+
# Returns the last element for which the block returns a truthy value.
3023+
#
3024+
# With a block given, calls the block with successive elements of the array in
3025+
# reverse order; returns the last element for which the block returns a truthy
3026+
# value:
3027+
#
3028+
# (0..9).rfind {|element| element < 5} # => 4
3029+
#
3030+
# If no such element is found, calls `if_none_proc` and returns its return
3031+
# value.
3032+
#
3033+
# (0..9).rfind(proc {false}) {|element| element < -2} # => false
3034+
# {foo: 0, bar: 1, baz: 2}.rfind {|key, value| key.start_with?('b') } # => [:baz, 2]
3035+
# {foo: 0, bar: 1, baz: 2}.rfind(proc {[]}) {|key, value| key.start_with?('c') } # => []
3036+
#
3037+
# With no block given, returns an Enumerator.
3038+
#
3039+
def rfind: () { (Elem) -> boolish } -> Elem?
3040+
| () -> ::Enumerator[Elem, Elem?]
3041+
| [T] (Enumerable::_NotFound[T] ifnone) { (Elem) -> boolish } -> (Elem | T)
3042+
| [T] (Enumerable::_NotFound[T] ifnone) -> ::Enumerator[Elem, Elem | T]
3043+
29913044
# <!--
29923045
# rdoc-file=array.c
29933046
# - rindex(object) -> integer or nil

core/ruby.rbs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# <!-- rdoc-file=version.c -->
2+
# The [Ruby](rdoc-ref:Ruby) module that contains portable information among
3+
# implementations.
4+
#
5+
# The constants defined here are aliased in the toplevel with `RUBY_` prefix.
6+
#
7+
module Ruby
8+
# <!-- rdoc-file=version.c -->
9+
# The copyright string for ruby
10+
#
11+
COPYRIGHT: ::String
12+
13+
# <!-- rdoc-file=version.c -->
14+
# The full ruby version string, like `ruby -v` prints
15+
#
16+
DESCRIPTION: ::String
17+
18+
# <!-- rdoc-file=version.c -->
19+
# The engine or interpreter this ruby uses.
20+
#
21+
ENGINE: ::String
22+
23+
# <!-- rdoc-file=version.c -->
24+
# The version of the engine or interpreter this ruby uses.
25+
#
26+
ENGINE_VERSION: ::String
27+
28+
# <!-- rdoc-file=version.c -->
29+
# The patchlevel for this ruby. If this is a development build of ruby the
30+
# patchlevel will be -1
31+
#
32+
PATCHLEVEL: ::Integer
33+
34+
# <!-- rdoc-file=version.c -->
35+
# The platform for this ruby
36+
#
37+
PLATFORM: ::String
38+
39+
# <!-- rdoc-file=version.c -->
40+
# The date this ruby was released
41+
#
42+
RELEASE_DATE: ::String
43+
44+
# <!-- rdoc-file=version.c -->
45+
# The GIT commit hash for this ruby.
46+
#
47+
REVISION: ::String
48+
49+
# <!-- rdoc-file=version.c -->
50+
# The running version of ruby
51+
#
52+
VERSION: ::String
53+
end

test/stdlib/Array_test.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,20 @@ def test_filter!
411411
[1,2,3], :filter!
412412
end
413413

414+
def test_find
415+
assert_send_type "() { (Integer) -> bool } -> Integer",
416+
[1,2,3], :find, &->(i) { i.odd? }
417+
assert_send_type "() { (Integer) -> bool } -> nil",
418+
[0,2], :find, &->(i) { i.odd? }
419+
assert_send_type "(Enumerable::_NotFound[String]) { (Integer) -> bool } -> String",
420+
[0,2], :find, -> { "" }, &->(i) { i.odd? }
421+
422+
assert_send_type "() -> Enumerator[Integer, Integer?]",
423+
[1,2,3], :find
424+
assert_send_type "(Enumerable::_NotFound[String]) -> Enumerator[Integer, Integer | String | nil]",
425+
[0,2], :find, -> { "" }
426+
end
427+
414428
def test_find_index
415429
assert_send_type "(Integer) -> Integer",
416430
[1,2,3], :find_index, 1
@@ -724,6 +738,20 @@ def test_reverse_each
724738
[2,3,4], :reverse_each
725739
end
726740

741+
def test_rfind
742+
assert_send_type "() { (Integer) -> bool } -> Integer",
743+
[1,2,3], :rfind, &->(i) { i.odd? }
744+
assert_send_type "() { (Integer) -> bool } -> nil",
745+
[0,2], :rfind, &->(i) { i.odd? }
746+
assert_send_type "(Enumerable::_NotFound[String]) { (Integer) -> bool } -> String",
747+
[0,2], :rfind, -> { "" }, &->(i) { i.odd? }
748+
749+
assert_send_type "() -> Enumerator[Integer, Integer?]",
750+
[1,2,3], :rfind
751+
assert_send_type "(Enumerable::_NotFound[String]) -> Enumerator[Integer, Integer | String | nil]",
752+
[0,2], :rfind, -> { "" }
753+
end
754+
727755
def test_rindex
728756
assert_send_type "(Integer) -> Integer",
729757
[1,2,3], :rindex, 1

test/stdlib/Ruby_test.rb

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require_relative "test_helper"
2+
require "resolv"
3+
4+
class RubyTest < Test::Unit::TestCase
5+
include TestHelper
6+
7+
testing "::Ruby"
8+
9+
def test_constants
10+
assert_const_type '::String', 'Ruby::COPYRIGHT'
11+
assert_const_type '::String', 'Ruby::DESCRIPTION'
12+
assert_const_type '::String', 'Ruby::ENGINE'
13+
assert_const_type '::String', 'Ruby::ENGINE_VERSION'
14+
assert_const_type '::Integer', 'Ruby::PATCHLEVEL'
15+
assert_const_type '::String', 'Ruby::PLATFORM'
16+
assert_const_type '::String', 'Ruby::RELEASE_DATE'
17+
assert_const_type '::String', 'Ruby::REVISION'
18+
assert_const_type '::String', 'Ruby::VERSION'
19+
end
20+
end

0 commit comments

Comments
 (0)
SYSTEM_READY >> ...MS