rbs 3.6.1 → 3.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/comments.yml +2 -2
- data/.github/workflows/dependabot.yml +1 -1
- data/.github/workflows/ruby.yml +34 -10
- data/.github/workflows/windows.yml +20 -3
- data/.gitignore +1 -0
- data/.rubocop.yml +26 -1
- data/CHANGELOG.md +241 -0
- data/Rakefile +54 -4
- data/config.yml +317 -0
- data/core/array.rbs +1756 -1591
- data/core/basic_object.rbs +38 -35
- data/core/comparable.rbs +1 -1
- data/core/complex.rbs +166 -94
- data/core/data.rbs +2 -2
- data/core/dir.rbs +2 -18
- data/core/encoding.rbs +12 -32
- data/core/enumerable.rbs +270 -266
- data/core/enumerator.rbs +14 -4
- data/core/env.rbs +1 -1
- data/core/errno.rbs +33 -16
- data/core/errors.rbs +6 -2
- data/core/exception.rbs +342 -167
- data/core/fiber.rbs +3 -2
- data/core/file.rbs +26 -75
- data/core/float.rbs +125 -72
- data/core/gc.rbs +158 -42
- data/core/hash.rbs +122 -143
- data/core/integer.rbs +79 -50
- data/core/io/buffer.rbs +49 -43
- data/core/io.rbs +108 -151
- data/core/kernel.rbs +341 -209
- data/core/match_data.rbs +76 -2
- data/core/math.rbs +0 -36
- data/core/method.rbs +2 -2
- data/core/module.rbs +32 -27
- data/core/nil_class.rbs +2 -2
- data/core/numeric.rbs +101 -104
- data/core/object.rbs +1 -5
- data/core/object_space/weak_key_map.rbs +3 -4
- data/core/object_space.rbs +3 -3
- data/core/proc.rbs +82 -14
- data/core/process.rbs +110 -58
- data/core/ractor.rbs +57 -4
- data/core/range.rbs +114 -87
- data/core/rational.rbs +0 -2
- data/core/rbs/unnamed/argf.rbs +237 -36
- data/core/rbs/unnamed/env_class.rbs +35 -53
- data/core/rbs/unnamed/random.rbs +1 -2
- data/core/regexp.rbs +10 -56
- data/core/ruby_vm.rbs +88 -9
- data/core/rubygems/config_file.rbs +3 -0
- data/core/rubygems/errors.rbs +3 -6
- data/core/rubygems/platform.rbs +0 -9
- data/core/rubygems/rubygems.rbs +3 -6
- data/core/rubygems/version.rbs +8 -8
- data/core/set.rbs +4 -16
- data/core/string.rbs +271 -264
- data/core/struct.rbs +6 -18
- data/core/symbol.rbs +14 -21
- data/core/thread.rbs +32 -35
- data/core/time.rbs +131 -50
- data/core/trace_point.rbs +124 -113
- data/core/true_class.rbs +0 -1
- data/core/unbound_method.rbs +1 -1
- data/core/warning.rbs +9 -2
- data/docs/architecture.md +1 -1
- data/docs/syntax.md +17 -10
- data/ext/rbs_extension/extconf.rb +11 -0
- data/ext/rbs_extension/location.c +61 -29
- data/ext/rbs_extension/location.h +4 -3
- data/ext/rbs_extension/main.c +23 -1
- data/ext/rbs_extension/parser.c +506 -517
- data/ext/rbs_extension/parserstate.c +109 -30
- data/ext/rbs_extension/parserstate.h +6 -4
- data/ext/rbs_extension/rbs_extension.h +1 -10
- data/{ext/rbs_extension → include/rbs}/constants.h +21 -19
- data/include/rbs/ruby_objs.h +72 -0
- data/include/rbs/util/rbs_constant_pool.h +219 -0
- data/include/rbs.h +7 -0
- data/lib/rbs/annotate/annotations.rb +3 -3
- data/lib/rbs/annotate/rdoc_source.rb +2 -2
- data/lib/rbs/ast/declarations.rb +9 -4
- data/lib/rbs/ast/directives.rb +10 -0
- data/lib/rbs/ast/members.rb +2 -0
- data/lib/rbs/ast/type_param.rb +2 -12
- data/lib/rbs/cli/diff.rb +3 -3
- data/lib/rbs/cli/validate.rb +2 -1
- data/lib/rbs/cli.rb +16 -16
- data/lib/rbs/collection/config/lockfile_generator.rb +58 -8
- data/lib/rbs/collection/config.rb +5 -3
- data/lib/rbs/collection/sources/rubygems.rb +1 -1
- data/lib/rbs/collection.rb +1 -0
- data/lib/rbs/definition.rb +51 -34
- data/lib/rbs/definition_builder/ancestor_builder.rb +5 -3
- data/lib/rbs/definition_builder.rb +83 -24
- data/lib/rbs/environment.rb +33 -18
- data/lib/rbs/environment_loader.rb +6 -1
- data/lib/rbs/errors.rb +24 -0
- data/lib/rbs/locator.rb +2 -0
- data/lib/rbs/method_type.rb +2 -0
- data/lib/rbs/namespace.rb +1 -0
- data/lib/rbs/parser_aux.rb +40 -3
- data/lib/rbs/prototype/rb.rb +20 -12
- data/lib/rbs/prototype/rbi.rb +11 -6
- data/lib/rbs/prototype/runtime/value_object_generator.rb +7 -5
- data/lib/rbs/prototype/runtime.rb +7 -5
- data/lib/rbs/subtractor.rb +3 -3
- data/lib/rbs/test/hook.rb +47 -42
- data/lib/rbs/test/type_check.rb +7 -5
- data/lib/rbs/type_name.rb +14 -9
- data/lib/rbs/types.rb +63 -14
- data/lib/rbs/unit_test/spy.rb +4 -2
- data/lib/rbs/unit_test/type_assertions.rb +19 -13
- data/lib/rbs/unit_test/with_aliases.rb +3 -1
- data/lib/rbs/validator.rb +7 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +10 -5
- data/lib/rbs.rb +1 -0
- data/lib/rdoc_plugin/parser.rb +2 -2
- data/rbs.gemspec +6 -2
- data/sig/ancestor_graph.rbs +5 -5
- data/sig/annotate/rdoc_source.rbs +2 -0
- data/sig/cli.rbs +2 -0
- data/sig/collection/config/lockfile_generator.rbs +9 -1
- data/sig/declarations.rbs +10 -3
- data/sig/definition.rbs +80 -12
- data/sig/definition_builder.rbs +18 -4
- data/sig/directives.rbs +17 -1
- data/sig/environment.rbs +3 -1
- data/sig/errors.rbs +19 -0
- data/sig/namespace.rbs +2 -3
- data/sig/parser.rbs +5 -1
- data/sig/prototype/rb.rbs +1 -1
- data/sig/resolver/constant_resolver.rbs +2 -2
- data/sig/resolver/context.rbs +1 -1
- data/sig/subtractor.rbs +1 -1
- data/sig/test/type_check.rbs +2 -2
- data/sig/type_alias_dependency.rbs +2 -2
- data/sig/type_alias_regularity.rbs +6 -6
- data/sig/type_param.rbs +4 -4
- data/sig/typename.rbs +8 -5
- data/sig/types.rbs +1 -1
- data/sig/unit_test/spy.rbs +2 -0
- data/sig/unit_test/type_assertions.rbs +2 -0
- data/sig/use_map.rbs +1 -1
- data/sig/validator.rbs +6 -2
- data/sig/vendorer.rbs +1 -1
- data/sig/writer.rbs +1 -1
- data/{ext/rbs_extension → src}/constants.c +35 -36
- data/src/ruby_objs.c +799 -0
- data/src/util/rbs_constant_pool.c +342 -0
- data/stdlib/base64/0/base64.rbs +0 -9
- data/stdlib/benchmark/0/benchmark.rbs +11 -2
- data/stdlib/bigdecimal/0/big_decimal.rbs +26 -182
- data/stdlib/cgi/0/core.rbs +60 -3
- data/stdlib/cgi/0/manifest.yaml +1 -0
- data/stdlib/coverage/0/coverage.rbs +0 -3
- data/stdlib/csv/0/csv.rbs +18 -58
- data/stdlib/csv/0/manifest.yaml +1 -0
- data/stdlib/date/0/date.rbs +27 -42
- data/stdlib/did_you_mean/0/did_you_mean.rbs +1 -6
- data/stdlib/digest/0/digest.rbs +25 -2
- data/stdlib/erb/0/erb.rbs +0 -1
- data/stdlib/etc/0/etc.rbs +51 -34
- data/stdlib/fileutils/0/fileutils.rbs +3 -44
- data/stdlib/io-console/0/io-console.rbs +69 -15
- data/stdlib/ipaddr/0/ipaddr.rbs +16 -4
- data/stdlib/json/0/json.rbs +107 -120
- data/stdlib/logger/0/log_device.rbs +1 -1
- data/stdlib/logger/0/logger.rbs +3 -18
- data/stdlib/minitest/0/kernel.rbs +2 -2
- data/stdlib/minitest/0/minitest/abstract_reporter.rbs +4 -1
- data/stdlib/minitest/0/minitest/assertion.rbs +1 -0
- data/stdlib/minitest/0/minitest/assertions.rbs +58 -13
- data/stdlib/minitest/0/minitest/backtrace_filter.rbs +7 -0
- data/stdlib/minitest/0/minitest/bench_spec.rbs +8 -8
- data/stdlib/minitest/0/minitest/benchmark.rbs +17 -16
- data/stdlib/minitest/0/minitest/compress.rbs +13 -0
- data/stdlib/minitest/0/minitest/error_on_warning.rbs +3 -0
- data/stdlib/minitest/0/minitest/mock.rbs +9 -5
- data/stdlib/minitest/0/minitest/parallel/executor.rbs +4 -0
- data/stdlib/minitest/0/minitest/parallel/test/class_methods.rbs +0 -1
- data/stdlib/minitest/0/minitest/pride_io.rbs +8 -0
- data/stdlib/minitest/0/minitest/pride_lol.rbs +2 -0
- data/stdlib/minitest/0/minitest/progress_reporter.rbs +1 -1
- data/stdlib/minitest/0/minitest/reportable.rbs +2 -0
- data/stdlib/minitest/0/minitest/runnable.rbs +33 -1
- data/stdlib/minitest/0/minitest/spec/dsl/instance_methods.rbs +1 -1
- data/stdlib/minitest/0/minitest/spec/dsl.rbs +10 -6
- data/stdlib/minitest/0/minitest/spec.rbs +1 -1
- data/stdlib/minitest/0/minitest/statistics_reporter.rbs +5 -0
- data/stdlib/minitest/0/minitest/summary_reporter.rbs +0 -7
- data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +1 -1
- data/stdlib/minitest/0/minitest/test.rbs +7 -14
- data/stdlib/minitest/0/minitest/unexpected_error.rbs +2 -0
- data/stdlib/minitest/0/minitest/unexpected_warning.rbs +6 -0
- data/stdlib/minitest/0/minitest/unit.rbs +1 -2
- data/stdlib/minitest/0/minitest.rbs +41 -892
- data/stdlib/monitor/0/monitor.rbs +13 -4
- data/stdlib/net-http/0/net-http.rbs +42 -109
- data/stdlib/nkf/0/nkf.rbs +30 -0
- data/stdlib/objspace/0/objspace.rbs +1 -2
- data/stdlib/observable/0/observable.rbs +1 -1
- data/stdlib/open-uri/0/manifest.yaml +1 -0
- data/stdlib/open-uri/0/open-uri.rbs +52 -0
- data/stdlib/open3/0/open3.rbs +0 -8
- data/stdlib/openssl/0/manifest.yaml +1 -0
- data/stdlib/openssl/0/openssl.rbs +235 -143
- data/stdlib/optparse/0/optparse.rbs +58 -18
- data/stdlib/pathname/0/pathname.rbs +2 -8
- data/stdlib/pp/0/pp.rbs +3 -1
- data/stdlib/prettyprint/0/prettyprint.rbs +0 -4
- data/stdlib/pstore/0/pstore.rbs +0 -6
- data/stdlib/psych/0/core_ext.rbs +12 -0
- data/stdlib/psych/0/psych.rbs +15 -4
- data/stdlib/pty/0/pty.rbs +46 -4
- data/stdlib/rdoc/0/code_object.rbs +0 -4
- data/stdlib/rdoc/0/markup.rbs +10 -12
- data/stdlib/rdoc/0/rdoc.rbs +13 -8
- data/stdlib/resolv/0/resolv.rbs +21 -12
- data/stdlib/ripper/0/ripper.rbs +0 -2
- data/stdlib/securerandom/0/securerandom.rbs +7 -2
- data/stdlib/shellwords/0/shellwords.rbs +11 -12
- data/stdlib/singleton/0/singleton.rbs +0 -1
- data/stdlib/socket/0/addrinfo.rbs +1 -2
- data/stdlib/socket/0/basic_socket.rbs +0 -5
- data/stdlib/socket/0/socket.rbs +32 -27
- data/stdlib/socket/0/tcp_server.rbs +0 -3
- data/stdlib/socket/0/tcp_socket.rbs +36 -3
- data/stdlib/socket/0/udp_socket.rbs +0 -1
- data/stdlib/socket/0/unix_server.rbs +0 -3
- data/stdlib/socket/0/unix_socket.rbs +4 -2
- data/{core/string_io.rbs → stdlib/stringio/0/stringio.rbs} +1 -1
- data/stdlib/strscan/0/string_scanner.rbs +1265 -422
- data/stdlib/tempfile/0/tempfile.rbs +135 -28
- data/stdlib/time/0/time.rbs +48 -35
- data/stdlib/timeout/0/timeout.rbs +11 -8
- data/stdlib/tmpdir/0/tmpdir.rbs +10 -3
- data/stdlib/tsort/0/tsort.rbs +0 -4
- data/stdlib/uri/0/common.rbs +28 -30
- data/stdlib/uri/0/ftp.rbs +1 -1
- data/stdlib/uri/0/generic.rbs +22 -18
- data/stdlib/uri/0/http.rbs +2 -2
- data/stdlib/uri/0/rfc2396_parser.rbs +3 -0
- data/stdlib/zlib/0/buf_error.rbs +1 -70
- data/stdlib/zlib/0/data_error.rbs +1 -70
- data/stdlib/zlib/0/deflate.rbs +8 -72
- data/stdlib/zlib/0/error.rbs +1 -70
- data/stdlib/zlib/0/gzip_file/crc_error.rbs +2 -105
- data/stdlib/zlib/0/gzip_file/error.rbs +2 -105
- data/stdlib/zlib/0/gzip_file/length_error.rbs +2 -105
- data/stdlib/zlib/0/gzip_file/no_footer.rbs +2 -105
- data/stdlib/zlib/0/gzip_file.rbs +1 -71
- data/stdlib/zlib/0/gzip_reader.rbs +3 -74
- data/stdlib/zlib/0/gzip_writer.rbs +1 -70
- data/stdlib/zlib/0/inflate.rbs +4 -71
- data/stdlib/zlib/0/mem_error.rbs +1 -70
- data/stdlib/zlib/0/need_dict.rbs +1 -70
- data/stdlib/zlib/0/stream_end.rbs +1 -70
- data/stdlib/zlib/0/stream_error.rbs +1 -70
- data/stdlib/zlib/0/version_error.rbs +1 -70
- data/stdlib/zlib/0/zlib.rbs +0 -2
- data/stdlib/zlib/0/zstream.rbs +4 -72
- metadata +17 -13
- data/ext/rbs_extension/ruby_objs.c +0 -602
- data/ext/rbs_extension/ruby_objs.h +0 -51
- data/stdlib/minitest/0/manifest.yaml +0 -2
data/core/enumerable.rbs
CHANGED
@@ -11,14 +11,13 @@
|
|
11
11
|
# * [Iterating](rdoc-ref:Enumerable@Methods+for+Iterating)
|
12
12
|
# * [And more....](rdoc-ref:Enumerable@Other+Methods)
|
13
13
|
#
|
14
|
-
#
|
15
14
|
# ### Methods for Querying
|
16
15
|
#
|
17
16
|
# These methods return information about the Enumerable other than the elements
|
18
17
|
# themselves:
|
19
18
|
#
|
20
|
-
# * #
|
21
|
-
# otherwise.
|
19
|
+
# * #member? (aliased as #include?): Returns `true` if `self == object`,
|
20
|
+
# `false` otherwise.
|
22
21
|
# * #all?: Returns `true` if all elements meet a specified criterion; `false`
|
23
22
|
# otherwise.
|
24
23
|
# * #any?: Returns `true` if any element meets a specified criterion; `false`
|
@@ -32,27 +31,25 @@
|
|
32
31
|
# * #tally: Returns a new Hash containing the counts of occurrences of each
|
33
32
|
# element.
|
34
33
|
#
|
35
|
-
#
|
36
34
|
# ### Methods for Fetching
|
37
35
|
#
|
38
36
|
# These methods return entries from the Enumerable, without modifying it:
|
39
37
|
#
|
40
38
|
# *Leading, trailing, or all elements*:
|
41
39
|
#
|
42
|
-
# * #
|
40
|
+
# * #to_a (aliased as #entries): Returns all elements.
|
43
41
|
# * #first: Returns the first element or leading elements.
|
44
42
|
# * #take: Returns a specified number of leading elements.
|
45
43
|
# * #drop: Returns a specified number of trailing elements.
|
46
44
|
# * #take_while: Returns leading elements as specified by the given block.
|
47
45
|
# * #drop_while: Returns trailing elements as specified by the given block.
|
48
46
|
#
|
49
|
-
#
|
50
47
|
# *Minimum and maximum value elements*:
|
51
48
|
#
|
52
49
|
# * #min: Returns the elements whose values are smallest among the elements,
|
53
|
-
# as determined by
|
50
|
+
# as determined by `#<=>` or a given block.
|
54
51
|
# * #max: Returns the elements whose values are largest among the elements, as
|
55
|
-
# determined by
|
52
|
+
# determined by `#<=>` or a given block.
|
56
53
|
# * #minmax: Returns a 2-element Array containing the smallest and largest
|
57
54
|
# elements.
|
58
55
|
# * #min_by: Returns the smallest element, as determined by the given block.
|
@@ -60,7 +57,6 @@
|
|
60
57
|
# * #minmax_by: Returns the smallest and largest elements, as determined by
|
61
58
|
# the given block.
|
62
59
|
#
|
63
|
-
#
|
64
60
|
# *Groups, slices, and partitions*:
|
65
61
|
#
|
66
62
|
# * #group_by: Returns a Hash that partitions the elements into groups.
|
@@ -77,27 +73,25 @@
|
|
77
73
|
# * #chunk_while: Returns elements organized into chunks as specified by the
|
78
74
|
# given block.
|
79
75
|
#
|
80
|
-
#
|
81
76
|
# ### Methods for Searching and Filtering
|
82
77
|
#
|
83
78
|
# These methods return elements that meet a specified criterion:
|
84
79
|
#
|
85
|
-
# * #find
|
86
|
-
# * #find_all
|
80
|
+
# * #find (aliased as #detect): Returns an element selected by the block.
|
81
|
+
# * #find_all (aliased as #filter, #select): Returns elements selected by the
|
82
|
+
# block.
|
87
83
|
# * #find_index: Returns the index of an element selected by a given object or
|
88
84
|
# block.
|
89
85
|
# * #reject: Returns elements not rejected by the block.
|
90
86
|
# * #uniq: Returns elements that are not duplicates.
|
91
87
|
#
|
92
|
-
#
|
93
88
|
# ### Methods for Sorting
|
94
89
|
#
|
95
90
|
# These methods return elements in sorted order:
|
96
91
|
#
|
97
|
-
# * #sort: Returns the elements, sorted by
|
92
|
+
# * #sort: Returns the elements, sorted by `#<=>` or the given block.
|
98
93
|
# * #sort_by: Returns the elements, sorted by the given block.
|
99
94
|
#
|
100
|
-
#
|
101
95
|
# ### Methods for Iterating
|
102
96
|
#
|
103
97
|
# * #each_entry: Calls the block with each successive element (slightly
|
@@ -112,24 +106,23 @@
|
|
112
106
|
# * #reverse_each: Calls the block with each successive element, in reverse
|
113
107
|
# order.
|
114
108
|
#
|
115
|
-
#
|
116
109
|
# ### Other Methods
|
117
110
|
#
|
118
|
-
# * #
|
111
|
+
# * #collect (aliased as #map): Returns objects returned by the block.
|
119
112
|
# * #filter_map: Returns truthy objects returned by the block.
|
120
|
-
# * #flat_map
|
121
|
-
# block.
|
113
|
+
# * #flat_map (aliased as #collect_concat): Returns flattened objects returned
|
114
|
+
# by the block.
|
122
115
|
# * #grep: Returns elements selected by a given object or objects returned by
|
123
116
|
# a given block.
|
124
117
|
# * #grep_v: Returns elements selected by a given object or objects returned
|
125
118
|
# by a given block.
|
126
|
-
# * #
|
119
|
+
# * #inject (aliased as #reduce): Returns the object formed by combining all
|
120
|
+
# elements.
|
127
121
|
# * #sum: Returns the sum of the elements, using method `+`.
|
128
122
|
# * #zip: Combines each element with elements from other enumerables; returns
|
129
123
|
# the n-tuples or calls the block with each.
|
130
124
|
# * #cycle: Calls the block with each element, cycling repeatedly.
|
131
125
|
#
|
132
|
-
#
|
133
126
|
# ## Usage
|
134
127
|
#
|
135
128
|
# To use module Enumerable in a collection class:
|
@@ -141,7 +134,6 @@
|
|
141
134
|
# * Implement method `#each` which must yield successive elements of the
|
142
135
|
# collection. The method will be called by almost any Enumerable method.
|
143
136
|
#
|
144
|
-
#
|
145
137
|
# Example:
|
146
138
|
#
|
147
139
|
# class Foo
|
@@ -174,7 +166,6 @@
|
|
174
166
|
# * Range
|
175
167
|
# * Struct
|
176
168
|
#
|
177
|
-
#
|
178
169
|
# These Ruby standard library classes include Enumerable:
|
179
170
|
#
|
180
171
|
# * CSV
|
@@ -182,7 +173,6 @@
|
|
182
173
|
# * CSV::Row
|
183
174
|
# * Set
|
184
175
|
#
|
185
|
-
#
|
186
176
|
# Virtually all methods in Enumerable call method `#each` in the including
|
187
177
|
# class:
|
188
178
|
#
|
@@ -191,7 +181,6 @@
|
|
191
181
|
# * For the other classes above, `#each` yields the next object from the
|
192
182
|
# collection.
|
193
183
|
#
|
194
|
-
#
|
195
184
|
# ## About the Examples
|
196
185
|
#
|
197
186
|
# The example code snippets for the Enumerable methods:
|
@@ -479,8 +468,8 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
479
468
|
# - each_with_index(*args) {|element, i| ..... } -> self
|
480
469
|
# - each_with_index(*args) -> enumerator
|
481
470
|
# -->
|
482
|
-
# With a block given,
|
483
|
-
# `self`:
|
471
|
+
# Invoke `self.each` with `*args`. With a block given, the block receives each
|
472
|
+
# element and its index; returns `self`:
|
484
473
|
#
|
485
474
|
# h = {}
|
486
475
|
# (1..4).each_with_index {|element, i| h[element] = i } # => 1..4
|
@@ -704,7 +693,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
704
693
|
# * Each value is an array of those elements for which the block returned that
|
705
694
|
# key.
|
706
695
|
#
|
707
|
-
#
|
708
696
|
# Examples:
|
709
697
|
#
|
710
698
|
# g = (1..6).group_by {|i| i%3 }
|
@@ -734,152 +722,155 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
734
722
|
|
735
723
|
# <!--
|
736
724
|
# rdoc-file=enum.c
|
737
|
-
# - inject(symbol)
|
738
|
-
# - inject(
|
739
|
-
# - inject {|memo,
|
740
|
-
# - inject(
|
725
|
+
# - inject(symbol) -> object
|
726
|
+
# - inject(initial_value, symbol) -> object
|
727
|
+
# - inject {|memo, value| ... } -> object
|
728
|
+
# - inject(initial_value) {|memo, value| ... } -> object
|
741
729
|
# -->
|
742
|
-
# Returns an
|
743
|
-
#
|
744
|
-
#
|
745
|
-
#
|
746
|
-
#
|
747
|
-
#
|
748
|
-
# With method-name argument `symbol`, combines operands using the method:
|
749
|
-
#
|
750
|
-
# # Sum, without initial_operand.
|
751
|
-
# (1..4).inject(:+) # => 10
|
752
|
-
# # Sum, with initial_operand.
|
753
|
-
# (1..4).inject(10, :+) # => 20
|
730
|
+
# Returns the result of applying a reducer to an initial value and the first
|
731
|
+
# element of the Enumerable. It then takes the result and applies the function
|
732
|
+
# to it and the second element of the collection, and so on. The return value is
|
733
|
+
# the result returned by the final call to the function.
|
754
734
|
#
|
755
|
-
#
|
735
|
+
# You can think of
|
756
736
|
#
|
757
|
-
#
|
758
|
-
# (1..4).inject {|sum, n| sum + n*n } # => 30
|
759
|
-
# # Sum of squares, with initial_operand.
|
760
|
-
# (1..4).inject(2) {|sum, n| sum + n*n } # => 32
|
737
|
+
# [ a, b, c, d ].inject(i) { |r, v| fn(r, v) }
|
761
738
|
#
|
762
|
-
#
|
739
|
+
# as being
|
763
740
|
#
|
764
|
-
#
|
765
|
-
# simply the elements of `self`. Example calls and their operands:
|
741
|
+
# fn(fn(fn(fn(i, a), b), c), d)
|
766
742
|
#
|
767
|
-
#
|
768
|
-
#
|
743
|
+
# In a way the `inject` function *injects* the function between the elements of
|
744
|
+
# the enumerable.
|
769
745
|
#
|
770
|
-
#
|
771
|
-
#
|
746
|
+
# `inject` is aliased as `reduce`. You use it when you want to *reduce* a
|
747
|
+
# collection to a single value.
|
772
748
|
#
|
773
|
-
#
|
774
|
-
# : `['a', 'b', 'c', 'd']`.
|
775
|
-
#
|
776
|
-
# `('a'...'d').inject(:+)`
|
777
|
-
# : `['a', 'b', 'c']`.
|
749
|
+
# **The Calling Sequences**
|
778
750
|
#
|
751
|
+
# Let's start with the most verbose:
|
779
752
|
#
|
753
|
+
# enum.inject(initial_value) do |result, next_value|
|
754
|
+
# # do something with +result+ and +next_value+
|
755
|
+
# # the value returned by the block becomes the
|
756
|
+
# # value passed in to the next iteration
|
757
|
+
# # as +result+
|
758
|
+
# end
|
780
759
|
#
|
781
|
-
#
|
760
|
+
# For example:
|
782
761
|
#
|
783
|
-
#
|
784
|
-
#
|
785
|
-
#
|
786
|
-
#
|
787
|
-
# # Character.
|
788
|
-
# ('a'..'d').inject(:+) # => "abcd"
|
789
|
-
# # Complex.
|
790
|
-
# [Complex(1, 2), 3, 4].inject(:+) # => (8+2i)
|
762
|
+
# product = [ 2, 3, 4 ].inject(1) do |result, next_value|
|
763
|
+
# result * next_value
|
764
|
+
# end
|
765
|
+
# product #=> 24
|
791
766
|
#
|
792
|
-
#
|
793
|
-
#
|
767
|
+
# When this runs, the block is first called with `1` (the initial value) and `2`
|
768
|
+
# (the first element of the array). The block returns `1*2`, so on the next
|
769
|
+
# iteration the block is called with `2` (the previous result) and `3`. The
|
770
|
+
# block returns `6`, and is called one last time with `6` and `4`. The result of
|
771
|
+
# the block, `24` becomes the value returned by `inject`. This code returns the
|
772
|
+
# product of the elements in the enumerable.
|
794
773
|
#
|
795
|
-
#
|
796
|
-
# : `[10, 1, 2, 3, 4]`.
|
774
|
+
# **First Shortcut: Default Initial value**
|
797
775
|
#
|
798
|
-
#
|
799
|
-
# :
|
776
|
+
# In the case of the previous example, the initial value, `1`, wasn't really
|
777
|
+
# necessary: the calculation of the product of a list of numbers is
|
778
|
+
# self-contained.
|
800
779
|
#
|
801
|
-
#
|
802
|
-
#
|
780
|
+
# In these circumstances, you can omit the `initial_value` parameter. `inject`
|
781
|
+
# will then initially call the block with the first element of the collection as
|
782
|
+
# the `result` parameter and the second element as the `next_value`.
|
803
783
|
#
|
804
|
-
#
|
805
|
-
#
|
784
|
+
# [ 2, 3, 4 ].inject do |result, next_value|
|
785
|
+
# result * next_value
|
786
|
+
# end
|
806
787
|
#
|
788
|
+
# This shortcut is convenient, but can only be used when the block produces a
|
789
|
+
# result which can be passed back to it as a first parameter.
|
807
790
|
#
|
791
|
+
# Here's an example where that's not the case: it returns a hash where the keys
|
792
|
+
# are words and the values are the number of occurrences of that word in the
|
793
|
+
# enumerable.
|
808
794
|
#
|
809
|
-
#
|
795
|
+
# freqs = File.read("README.md")
|
796
|
+
# .scan(/\w{2,}/)
|
797
|
+
# .reduce(Hash.new(0)) do |counts, word|
|
798
|
+
# counts[word] += 1
|
799
|
+
# counts
|
800
|
+
# end
|
801
|
+
# freqs #=> {"Actions"=>4,
|
802
|
+
# "Status"=>5,
|
803
|
+
# "MinGW"=>3,
|
804
|
+
# "https"=>27,
|
805
|
+
# "github"=>10,
|
806
|
+
# "com"=>15, ...
|
810
807
|
#
|
811
|
-
#
|
812
|
-
#
|
813
|
-
# # Float.
|
814
|
-
# (1..4).inject(2.0, :+) # => 12.0
|
815
|
-
# # String.
|
816
|
-
# ('a'..'d').inject('foo', :+) # => "fooabcd"
|
817
|
-
# # Array.
|
818
|
-
# %w[a b c].inject(['x'], :push) # => ["x", "a", "b", "c"]
|
819
|
-
# # Complex.
|
820
|
-
# (1..4).inject(Complex(2, 2), :+) # => (12+2i)
|
808
|
+
# Note that the last line of the block is just the word `counts`. This ensures
|
809
|
+
# the return value of the block is the result that's being calculated.
|
821
810
|
#
|
822
|
-
# **
|
811
|
+
# **Second Shortcut: a Reducer function**
|
823
812
|
#
|
824
|
-
#
|
825
|
-
# that
|
813
|
+
# A *reducer function* is a function that takes a partial result and the next
|
814
|
+
# value, returning the next partial result. The block that is given to `inject`
|
815
|
+
# is a reducer.
|
826
816
|
#
|
827
|
-
#
|
828
|
-
#
|
829
|
-
# * That result is combined with the fourth operand.
|
830
|
-
# * And so on.
|
817
|
+
# You can also write a reducer as a function and pass the name of that function
|
818
|
+
# (as a symbol) to `inject`. However, for this to work, the function
|
831
819
|
#
|
820
|
+
# 1. Must be defined on the type of the result value
|
821
|
+
# 2. Must accept a single parameter, the next value in the collection, and
|
822
|
+
# 3. Must return an updated result which will also implement the function.
|
832
823
|
#
|
833
|
-
#
|
824
|
+
# Here's an example that adds elements to a string. The two calls invoke the
|
825
|
+
# functions String#concat and String#+ on the result so far, passing it the next
|
826
|
+
# value.
|
834
827
|
#
|
835
|
-
#
|
828
|
+
# s = [ "cat", " ", "dog" ].inject("", :concat)
|
829
|
+
# s #=> "cat dog"
|
830
|
+
# s = [ "cat", " ", "dog" ].inject("The result is:", :+)
|
831
|
+
# s #=> "The result is: cat dog"
|
836
832
|
#
|
837
|
-
#
|
833
|
+
# Here's a more complex example when the result object maintains state of a
|
834
|
+
# different type to the enumerable elements.
|
838
835
|
#
|
839
|
-
#
|
836
|
+
# class Turtle
|
840
837
|
#
|
841
|
-
#
|
842
|
-
#
|
843
|
-
#
|
844
|
-
# (1..4).inject(:*) # => 24
|
845
|
-
# # Character range concatenation.
|
846
|
-
# ('a'..'d').inject('', :+) # => "abcd"
|
847
|
-
# # String array concatenation.
|
848
|
-
# %w[foo bar baz].inject('', :+) # => "foobarbaz"
|
849
|
-
# # Hash update.
|
850
|
-
# h = [{foo: 0, bar: 1}, {baz: 2}, {bat: 3}].inject(:update)
|
851
|
-
# h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
|
852
|
-
# # Hash conversion to nested arrays.
|
853
|
-
# h = {foo: 0, bar: 1}.inject([], :push)
|
854
|
-
# h # => [[:foo, 0], [:bar, 1]]
|
838
|
+
# def initialize
|
839
|
+
# @x = @y = 0
|
840
|
+
# end
|
855
841
|
#
|
856
|
-
#
|
842
|
+
# def move(dir)
|
843
|
+
# case dir
|
844
|
+
# when "n" then @y += 1
|
845
|
+
# when "s" then @y -= 1
|
846
|
+
# when "e" then @x += 1
|
847
|
+
# when "w" then @x -= 1
|
848
|
+
# end
|
849
|
+
# self
|
850
|
+
# end
|
851
|
+
# end
|
857
852
|
#
|
858
|
-
#
|
853
|
+
# position = "nnneesw".chars.reduce(Turtle.new, :move)
|
854
|
+
# position #=>> #<Turtle:0x00000001052f4698 @y=2, @x=1>
|
859
855
|
#
|
860
|
-
#
|
861
|
-
# * The second call passes the result of the first call, along with the third
|
862
|
-
# operand.
|
863
|
-
# * The third call passes the result of the second call, along with the fourth
|
864
|
-
# operand.
|
865
|
-
# * And so on.
|
856
|
+
# **Third Shortcut: Reducer With no Initial Value**
|
866
857
|
#
|
858
|
+
# If your reducer returns a value that it can accept as a parameter, then you
|
859
|
+
# don't have to pass in an initial value. Here `:*` is the name of the *times*
|
860
|
+
# function:
|
867
861
|
#
|
868
|
-
#
|
862
|
+
# product = [ 2, 3, 4 ].inject(:*)
|
863
|
+
# product # => 24
|
869
864
|
#
|
870
|
-
#
|
871
|
-
# sums the elements:
|
865
|
+
# String concatenation again:
|
872
866
|
#
|
873
|
-
#
|
874
|
-
#
|
875
|
-
# memo + element
|
876
|
-
# end # => 10
|
867
|
+
# s = [ "cat", " ", "dog" ].inject(:+)
|
868
|
+
# s #=> "cat dog"
|
877
869
|
#
|
878
|
-
#
|
870
|
+
# And an example that converts a hash to an array of two-element subarrays.
|
879
871
|
#
|
880
|
-
#
|
881
|
-
#
|
882
|
-
# "Memo: 6; element: 4"
|
872
|
+
# nested = {foo: 0, bar: 1}.inject([], :push)
|
873
|
+
# nested # => [[:foo, 0], [:bar, 1]]
|
883
874
|
#
|
884
875
|
def inject: (untyped init, Symbol method) -> untyped
|
885
876
|
| (Symbol method) -> untyped
|
@@ -897,7 +888,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
897
888
|
# The ordering of equal elements is indeterminate and may be unstable.
|
898
889
|
#
|
899
890
|
# With no argument and no block, returns the maximum element, using the
|
900
|
-
# elements' own method
|
891
|
+
# elements' own method `#<=>` for comparison:
|
901
892
|
#
|
902
893
|
# (1..4).max # => 4
|
903
894
|
# (-4..-1).max # => -1
|
@@ -921,7 +912,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
921
912
|
# * Zero if `a == b`.
|
922
913
|
# * A positive integer if `a > b`.
|
923
914
|
#
|
924
|
-
#
|
925
915
|
# With a block given and no argument, returns the maximum element as determined
|
926
916
|
# by the block:
|
927
917
|
#
|
@@ -996,7 +986,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
996
986
|
# The ordering of equal elements is indeterminate and may be unstable.
|
997
987
|
#
|
998
988
|
# With no argument and no block, returns the minimum element, using the
|
999
|
-
# elements' own method
|
989
|
+
# elements' own method `#<=>` for comparison:
|
1000
990
|
#
|
1001
991
|
# (1..4).min # => 1
|
1002
992
|
# (-4..-1).min # => -4
|
@@ -1020,7 +1010,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1020
1010
|
# * Zero if `a == b`.
|
1021
1011
|
# * A positive integer if `a > b`.
|
1022
1012
|
#
|
1023
|
-
#
|
1024
1013
|
# With a block given and no argument, returns the minimum element as determined
|
1025
1014
|
# by the block:
|
1026
1015
|
#
|
@@ -1094,7 +1083,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1094
1083
|
# indeterminate and may be unstable.
|
1095
1084
|
#
|
1096
1085
|
# With no argument and no block, returns the minimum and maximum elements, using
|
1097
|
-
# the elements' own method
|
1086
|
+
# the elements' own method `#<=>` for comparison:
|
1098
1087
|
#
|
1099
1088
|
# (1..4).minmax # => [1, 4]
|
1100
1089
|
# (-4..-1).minmax # => [-4, -1]
|
@@ -1234,7 +1223,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1234
1223
|
# value.
|
1235
1224
|
# * The other having all other elements.
|
1236
1225
|
#
|
1237
|
-
#
|
1238
1226
|
# Examples:
|
1239
1227
|
#
|
1240
1228
|
# p = (1..4).partition {|i| i.even? }
|
@@ -1309,7 +1297,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1309
1297
|
# Returns an array containing the sorted elements of `self`. The ordering of
|
1310
1298
|
# equal elements is indeterminate and may be unstable.
|
1311
1299
|
#
|
1312
|
-
# With no block given, the sort compares using the elements' own method
|
1300
|
+
# With no block given, the sort compares using the elements' own method `#<=>`:
|
1313
1301
|
#
|
1314
1302
|
# %w[b c a d].sort # => ["a", "b", "c", "d"]
|
1315
1303
|
# {foo: 0, bar: 1, baz: 2}.sort # => [[:bar, 1], [:baz, 2], [:foo, 0]]
|
@@ -1321,7 +1309,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1321
1309
|
# * Zero if `a == b`.
|
1322
1310
|
# * A positive integer if `a > b`.
|
1323
1311
|
#
|
1324
|
-
#
|
1325
1312
|
# Examples:
|
1326
1313
|
#
|
1327
1314
|
# a = %w[b c a d]
|
@@ -1578,147 +1565,150 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1578
1565
|
def member?: (Elem arg0) -> bool
|
1579
1566
|
|
1580
1567
|
# <!-- rdoc-file=enum.c -->
|
1581
|
-
# Returns an
|
1582
|
-
#
|
1583
|
-
#
|
1584
|
-
#
|
1585
|
-
#
|
1568
|
+
# Returns the result of applying a reducer to an initial value and the first
|
1569
|
+
# element of the Enumerable. It then takes the result and applies the function
|
1570
|
+
# to it and the second element of the collection, and so on. The return value is
|
1571
|
+
# the result returned by the final call to the function.
|
1586
1572
|
#
|
1587
|
-
#
|
1573
|
+
# You can think of
|
1588
1574
|
#
|
1589
|
-
#
|
1590
|
-
# (1..4).inject(:+) # => 10
|
1591
|
-
# # Sum, with initial_operand.
|
1592
|
-
# (1..4).inject(10, :+) # => 20
|
1575
|
+
# [ a, b, c, d ].inject(i) { |r, v| fn(r, v) }
|
1593
1576
|
#
|
1594
|
-
#
|
1577
|
+
# as being
|
1595
1578
|
#
|
1596
|
-
#
|
1597
|
-
# (1..4).inject {|sum, n| sum + n*n } # => 30
|
1598
|
-
# # Sum of squares, with initial_operand.
|
1599
|
-
# (1..4).inject(2) {|sum, n| sum + n*n } # => 32
|
1579
|
+
# fn(fn(fn(fn(i, a), b), c), d)
|
1600
1580
|
#
|
1601
|
-
#
|
1581
|
+
# In a way the `inject` function *injects* the function between the elements of
|
1582
|
+
# the enumerable.
|
1602
1583
|
#
|
1603
|
-
#
|
1604
|
-
#
|
1584
|
+
# `inject` is aliased as `reduce`. You use it when you want to *reduce* a
|
1585
|
+
# collection to a single value.
|
1605
1586
|
#
|
1606
|
-
#
|
1607
|
-
# : `[1, 2, 3, 4]`.
|
1608
|
-
#
|
1609
|
-
# `(1...4).inject(:+)`
|
1610
|
-
# : `[1, 2, 3]`.
|
1611
|
-
#
|
1612
|
-
# `('a'..'d').inject(:+)`
|
1613
|
-
# : `['a', 'b', 'c', 'd']`.
|
1614
|
-
#
|
1615
|
-
# `('a'...'d').inject(:+)`
|
1616
|
-
# : `['a', 'b', 'c']`.
|
1587
|
+
# **The Calling Sequences**
|
1617
1588
|
#
|
1589
|
+
# Let's start with the most verbose:
|
1618
1590
|
#
|
1591
|
+
# enum.inject(initial_value) do |result, next_value|
|
1592
|
+
# # do something with +result+ and +next_value+
|
1593
|
+
# # the value returned by the block becomes the
|
1594
|
+
# # value passed in to the next iteration
|
1595
|
+
# # as +result+
|
1596
|
+
# end
|
1619
1597
|
#
|
1620
|
-
#
|
1598
|
+
# For example:
|
1621
1599
|
#
|
1622
|
-
#
|
1623
|
-
#
|
1624
|
-
#
|
1625
|
-
#
|
1626
|
-
# # Character.
|
1627
|
-
# ('a'..'d').inject(:+) # => "abcd"
|
1628
|
-
# # Complex.
|
1629
|
-
# [Complex(1, 2), 3, 4].inject(:+) # => (8+2i)
|
1600
|
+
# product = [ 2, 3, 4 ].inject(1) do |result, next_value|
|
1601
|
+
# result * next_value
|
1602
|
+
# end
|
1603
|
+
# product #=> 24
|
1630
1604
|
#
|
1631
|
-
#
|
1632
|
-
#
|
1605
|
+
# When this runs, the block is first called with `1` (the initial value) and `2`
|
1606
|
+
# (the first element of the array). The block returns `1*2`, so on the next
|
1607
|
+
# iteration the block is called with `2` (the previous result) and `3`. The
|
1608
|
+
# block returns `6`, and is called one last time with `6` and `4`. The result of
|
1609
|
+
# the block, `24` becomes the value returned by `inject`. This code returns the
|
1610
|
+
# product of the elements in the enumerable.
|
1633
1611
|
#
|
1634
|
-
#
|
1635
|
-
# : `[10, 1, 2, 3, 4]`.
|
1612
|
+
# **First Shortcut: Default Initial value**
|
1636
1613
|
#
|
1637
|
-
#
|
1638
|
-
# :
|
1614
|
+
# In the case of the previous example, the initial value, `1`, wasn't really
|
1615
|
+
# necessary: the calculation of the product of a list of numbers is
|
1616
|
+
# self-contained.
|
1639
1617
|
#
|
1640
|
-
#
|
1641
|
-
#
|
1618
|
+
# In these circumstances, you can omit the `initial_value` parameter. `inject`
|
1619
|
+
# will then initially call the block with the first element of the collection as
|
1620
|
+
# the `result` parameter and the second element as the `next_value`.
|
1642
1621
|
#
|
1643
|
-
#
|
1644
|
-
#
|
1622
|
+
# [ 2, 3, 4 ].inject do |result, next_value|
|
1623
|
+
# result * next_value
|
1624
|
+
# end
|
1645
1625
|
#
|
1626
|
+
# This shortcut is convenient, but can only be used when the block produces a
|
1627
|
+
# result which can be passed back to it as a first parameter.
|
1646
1628
|
#
|
1629
|
+
# Here's an example where that's not the case: it returns a hash where the keys
|
1630
|
+
# are words and the values are the number of occurrences of that word in the
|
1631
|
+
# enumerable.
|
1647
1632
|
#
|
1648
|
-
#
|
1633
|
+
# freqs = File.read("README.md")
|
1634
|
+
# .scan(/\w{2,}/)
|
1635
|
+
# .reduce(Hash.new(0)) do |counts, word|
|
1636
|
+
# counts[word] += 1
|
1637
|
+
# counts
|
1638
|
+
# end
|
1639
|
+
# freqs #=> {"Actions"=>4,
|
1640
|
+
# "Status"=>5,
|
1641
|
+
# "MinGW"=>3,
|
1642
|
+
# "https"=>27,
|
1643
|
+
# "github"=>10,
|
1644
|
+
# "com"=>15, ...
|
1649
1645
|
#
|
1650
|
-
#
|
1651
|
-
#
|
1652
|
-
# # Float.
|
1653
|
-
# (1..4).inject(2.0, :+) # => 12.0
|
1654
|
-
# # String.
|
1655
|
-
# ('a'..'d').inject('foo', :+) # => "fooabcd"
|
1656
|
-
# # Array.
|
1657
|
-
# %w[a b c].inject(['x'], :push) # => ["x", "a", "b", "c"]
|
1658
|
-
# # Complex.
|
1659
|
-
# (1..4).inject(Complex(2, 2), :+) # => (12+2i)
|
1646
|
+
# Note that the last line of the block is just the word `counts`. This ensures
|
1647
|
+
# the return value of the block is the result that's being calculated.
|
1660
1648
|
#
|
1661
|
-
# **
|
1649
|
+
# **Second Shortcut: a Reducer function**
|
1662
1650
|
#
|
1663
|
-
#
|
1664
|
-
# that
|
1651
|
+
# A *reducer function* is a function that takes a partial result and the next
|
1652
|
+
# value, returning the next partial result. The block that is given to `inject`
|
1653
|
+
# is a reducer.
|
1665
1654
|
#
|
1666
|
-
#
|
1667
|
-
#
|
1668
|
-
# * That result is combined with the fourth operand.
|
1669
|
-
# * And so on.
|
1655
|
+
# You can also write a reducer as a function and pass the name of that function
|
1656
|
+
# (as a symbol) to `inject`. However, for this to work, the function
|
1670
1657
|
#
|
1658
|
+
# 1. Must be defined on the type of the result value
|
1659
|
+
# 2. Must accept a single parameter, the next value in the collection, and
|
1660
|
+
# 3. Must return an updated result which will also implement the function.
|
1671
1661
|
#
|
1672
|
-
#
|
1662
|
+
# Here's an example that adds elements to a string. The two calls invoke the
|
1663
|
+
# functions String#concat and String#+ on the result so far, passing it the next
|
1664
|
+
# value.
|
1673
1665
|
#
|
1674
|
-
#
|
1666
|
+
# s = [ "cat", " ", "dog" ].inject("", :concat)
|
1667
|
+
# s #=> "cat dog"
|
1668
|
+
# s = [ "cat", " ", "dog" ].inject("The result is:", :+)
|
1669
|
+
# s #=> "The result is: cat dog"
|
1675
1670
|
#
|
1676
|
-
#
|
1671
|
+
# Here's a more complex example when the result object maintains state of a
|
1672
|
+
# different type to the enumerable elements.
|
1677
1673
|
#
|
1678
|
-
#
|
1674
|
+
# class Turtle
|
1679
1675
|
#
|
1680
|
-
#
|
1681
|
-
#
|
1682
|
-
#
|
1683
|
-
# (1..4).inject(:*) # => 24
|
1684
|
-
# # Character range concatenation.
|
1685
|
-
# ('a'..'d').inject('', :+) # => "abcd"
|
1686
|
-
# # String array concatenation.
|
1687
|
-
# %w[foo bar baz].inject('', :+) # => "foobarbaz"
|
1688
|
-
# # Hash update.
|
1689
|
-
# h = [{foo: 0, bar: 1}, {baz: 2}, {bat: 3}].inject(:update)
|
1690
|
-
# h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3}
|
1691
|
-
# # Hash conversion to nested arrays.
|
1692
|
-
# h = {foo: 0, bar: 1}.inject([], :push)
|
1693
|
-
# h # => [[:foo, 0], [:bar, 1]]
|
1676
|
+
# def initialize
|
1677
|
+
# @x = @y = 0
|
1678
|
+
# end
|
1694
1679
|
#
|
1695
|
-
#
|
1680
|
+
# def move(dir)
|
1681
|
+
# case dir
|
1682
|
+
# when "n" then @y += 1
|
1683
|
+
# when "s" then @y -= 1
|
1684
|
+
# when "e" then @x += 1
|
1685
|
+
# when "w" then @x -= 1
|
1686
|
+
# end
|
1687
|
+
# self
|
1688
|
+
# end
|
1689
|
+
# end
|
1696
1690
|
#
|
1697
|
-
#
|
1691
|
+
# position = "nnneesw".chars.reduce(Turtle.new, :move)
|
1692
|
+
# position #=>> #<Turtle:0x00000001052f4698 @y=2, @x=1>
|
1698
1693
|
#
|
1699
|
-
#
|
1700
|
-
# * The second call passes the result of the first call, along with the third
|
1701
|
-
# operand.
|
1702
|
-
# * The third call passes the result of the second call, along with the fourth
|
1703
|
-
# operand.
|
1704
|
-
# * And so on.
|
1694
|
+
# **Third Shortcut: Reducer With no Initial Value**
|
1705
1695
|
#
|
1696
|
+
# If your reducer returns a value that it can accept as a parameter, then you
|
1697
|
+
# don't have to pass in an initial value. Here `:*` is the name of the *times*
|
1698
|
+
# function:
|
1706
1699
|
#
|
1707
|
-
#
|
1700
|
+
# product = [ 2, 3, 4 ].inject(:*)
|
1701
|
+
# product # => 24
|
1708
1702
|
#
|
1709
|
-
#
|
1710
|
-
# sums the elements:
|
1703
|
+
# String concatenation again:
|
1711
1704
|
#
|
1712
|
-
#
|
1713
|
-
#
|
1714
|
-
# memo + element
|
1715
|
-
# end # => 10
|
1705
|
+
# s = [ "cat", " ", "dog" ].inject(:+)
|
1706
|
+
# s #=> "cat dog"
|
1716
1707
|
#
|
1717
|
-
#
|
1708
|
+
# And an example that converts a hash to an array of two-element subarrays.
|
1718
1709
|
#
|
1719
|
-
#
|
1720
|
-
#
|
1721
|
-
# "Memo: 6; element: 4"
|
1710
|
+
# nested = {foo: 0, bar: 1}.inject([], :push)
|
1711
|
+
# nested # => [[:foo, 0], [:bar, 1]]
|
1722
1712
|
#
|
1723
1713
|
alias reduce inject
|
1724
1714
|
|
@@ -1850,30 +1840,47 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1850
1840
|
|
1851
1841
|
# <!--
|
1852
1842
|
# rdoc-file=enum.c
|
1853
|
-
# - tally ->
|
1854
|
-
# - tally(hash) -> hash
|
1843
|
+
# - tally(hash = {}) -> hash
|
1855
1844
|
# -->
|
1856
|
-
#
|
1845
|
+
# When argument `hash` is not given, returns a new hash whose keys are the
|
1846
|
+
# distinct elements in `self`; each integer value is the count of occurrences of
|
1847
|
+
# each element:
|
1857
1848
|
#
|
1858
|
-
#
|
1859
|
-
# * Each value is the number elements equal to that key.
|
1849
|
+
# %w[a b c b c a c b].tally # => {"a"=>2, "b"=>3, "c"=>3}
|
1860
1850
|
#
|
1851
|
+
# When argument `hash` is given, returns `hash`, possibly augmented; for each
|
1852
|
+
# element `ele` in `self`:
|
1861
1853
|
#
|
1862
|
-
#
|
1854
|
+
# * Adds it as a key with a zero value if that key does not already exist:
|
1863
1855
|
#
|
1864
|
-
#
|
1856
|
+
# hash[ele] = 0 unless hash.include?(ele)
|
1857
|
+
#
|
1858
|
+
# * Increments the value of key `ele`:
|
1859
|
+
#
|
1860
|
+
# hash[ele] += 1
|
1865
1861
|
#
|
1866
|
-
#
|
1867
|
-
# and is returned; this may be useful for accumulating tallies across multiple
|
1868
|
-
# enumerables:
|
1862
|
+
# This is useful for accumulating tallies across multiple enumerables:
|
1869
1863
|
#
|
1870
|
-
#
|
1871
|
-
#
|
1872
|
-
#
|
1873
|
-
#
|
1874
|
-
#
|
1875
|
-
#
|
1876
|
-
#
|
1864
|
+
# h = {} # => {}
|
1865
|
+
# %w[a c d b c a].tally(h) # => {"a"=>2, "c"=>2, "d"=>1, "b"=>1}
|
1866
|
+
# %w[b a z].tally(h) # => {"a"=>3, "c"=>2, "d"=>1, "b"=>2, "z"=>1}
|
1867
|
+
# %w[b a m].tally(h) # => {"a"=>4, "c"=>2, "d"=>1, "b"=>3, "z"=>1, "m"=>1}
|
1868
|
+
#
|
1869
|
+
# The key to be added or found for an element depends on the class of `self`;
|
1870
|
+
# see [Enumerable in Ruby
|
1871
|
+
# Classes](rdoc-ref:Enumerable@Enumerable+in+Ruby+Classes).
|
1872
|
+
#
|
1873
|
+
# Examples:
|
1874
|
+
#
|
1875
|
+
# * Array (and certain array-like classes): the key is the element (as above).
|
1876
|
+
# * Hash (and certain hash-like classes): the key is the 2-element array
|
1877
|
+
# formed from the key-value pair:
|
1878
|
+
#
|
1879
|
+
# h = {} # => {}
|
1880
|
+
# {foo: 'a', bar: 'b'}.tally(h) # => {[:foo, "a"]=>1, [:bar, "b"]=>1}
|
1881
|
+
# {foo: 'c', bar: 'd'}.tally(h) # => {[:foo, "a"]=>1, [:bar, "b"]=>1, [:foo, "c"]=>1, [:bar, "d"]=>1}
|
1882
|
+
# {foo: 'a', bar: 'b'}.tally(h) # => {[:foo, "a"]=>2, [:bar, "b"]=>2, [:foo, "c"]=>1, [:bar, "d"]=>1}
|
1883
|
+
# {foo: 'c', bar: 'd'}.tally(h) # => {[:foo, "a"]=>2, [:bar, "b"]=>2, [:foo, "c"]=>2, [:bar, "d"]=>2}
|
1877
1884
|
#
|
1878
1885
|
def tally: (?Hash[Elem, Integer] hash) -> ::Hash[Elem, Integer]
|
1879
1886
|
|
@@ -1928,7 +1935,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1928
1935
|
# * The `n`-th element of self.
|
1929
1936
|
# * The `n`-th element of each of the `other_enums`.
|
1930
1937
|
#
|
1931
|
-
#
|
1932
1938
|
# If all `other_enums` and self are the same size, all elements are included in
|
1933
1939
|
# the result, and there is no `nil`-filling:
|
1934
1940
|
#
|
@@ -1997,7 +2003,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
1997
2003
|
# returned, and all following elements for which the block returned the same
|
1998
2004
|
# value:
|
1999
2005
|
#
|
2000
|
-
#
|
2001
2006
|
# So that:
|
2002
2007
|
#
|
2003
2008
|
# * Each block return value that is different from its predecessor begins a
|
@@ -2005,7 +2010,6 @@ module Enumerable[unchecked out Elem] : _Each[Elem]
|
|
2005
2010
|
# * Each block return value that is the same as its predecessor continues the
|
2006
2011
|
# same chunk.
|
2007
2012
|
#
|
2008
|
-
#
|
2009
2013
|
# Example:
|
2010
2014
|
#
|
2011
2015
|
# e = (0..10).chunk {|i| (i / 3).floor } # => #<Enumerator: ...>
|