rbs 3.7.0 → 3.8.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +3 -3
  3. data/.github/workflows/ruby.yml +7 -7
  4. data/CHANGELOG.md +52 -0
  5. data/core/array.rbs +1743 -1580
  6. data/core/basic_object.rbs +38 -35
  7. data/core/comparable.rbs +1 -1
  8. data/core/complex.rbs +165 -93
  9. data/core/data.rbs +1 -1
  10. data/core/dir.rbs +1 -17
  11. data/core/encoding.rbs +12 -6
  12. data/core/enumerable.rbs +270 -266
  13. data/core/enumerator.rbs +0 -2
  14. data/core/env.rbs +1 -1
  15. data/core/errno.rbs +33 -16
  16. data/core/errors.rbs +2 -2
  17. data/core/exception.rbs +236 -170
  18. data/core/fiber.rbs +3 -2
  19. data/core/file.rbs +32 -74
  20. data/core/float.rbs +125 -72
  21. data/core/gc.rbs +138 -40
  22. data/core/hash.rbs +120 -141
  23. data/core/integer.rbs +79 -50
  24. data/core/io/buffer.rbs +49 -43
  25. data/core/io.rbs +97 -144
  26. data/core/kernel.rbs +290 -200
  27. data/core/match_data.rbs +76 -2
  28. data/core/math.rbs +0 -36
  29. data/core/module.rbs +28 -23
  30. data/core/nil_class.rbs +0 -3
  31. data/core/numeric.rbs +100 -103
  32. data/core/object.rbs +0 -4
  33. data/core/object_space/weak_key_map.rbs +3 -4
  34. data/core/object_space.rbs +3 -3
  35. data/core/proc.rbs +0 -2
  36. data/core/process.rbs +109 -57
  37. data/core/ractor.rbs +37 -4
  38. data/core/range.rbs +114 -87
  39. data/core/rational.rbs +0 -2
  40. data/core/rbs/unnamed/argf.rbs +234 -33
  41. data/core/rbs/unnamed/env_class.rbs +35 -53
  42. data/core/rbs/unnamed/random.rbs +1 -2
  43. data/core/regexp.rbs +4 -52
  44. data/core/ruby_vm.rbs +88 -9
  45. data/core/rubygems/config_file.rbs +3 -0
  46. data/core/rubygems/errors.rbs +0 -5
  47. data/core/rubygems/platform.rbs +0 -9
  48. data/core/rubygems/rubygems.rbs +0 -5
  49. data/core/rubygems/version.rbs +6 -6
  50. data/core/set.rbs +3 -15
  51. data/core/string.rbs +130 -136
  52. data/core/struct.rbs +6 -18
  53. data/core/symbol.rbs +14 -21
  54. data/core/thread.rbs +32 -35
  55. data/core/time.rbs +127 -50
  56. data/core/trace_point.rbs +16 -0
  57. data/core/true_class.rbs +0 -1
  58. data/core/warning.rbs +9 -2
  59. data/docs/architecture.md +1 -1
  60. data/docs/syntax.md +1 -1
  61. data/ext/rbs_extension/location.c +29 -19
  62. data/ext/rbs_extension/parser.c +267 -292
  63. data/ext/rbs_extension/parserstate.c +56 -22
  64. data/lib/rbs/annotate/annotations.rb +3 -3
  65. data/lib/rbs/annotate/rdoc_source.rb +2 -2
  66. data/lib/rbs/cli/diff.rb +3 -3
  67. data/lib/rbs/cli/validate.rb +1 -1
  68. data/lib/rbs/cli.rb +13 -13
  69. data/lib/rbs/collection/config.rb +3 -1
  70. data/lib/rbs/definition_builder/ancestor_builder.rb +3 -3
  71. data/lib/rbs/environment_loader.rb +1 -1
  72. data/lib/rbs/namespace.rb +1 -0
  73. data/lib/rbs/parser_aux.rb +2 -2
  74. data/lib/rbs/prototype/rb.rb +11 -8
  75. data/lib/rbs/prototype/rbi.rb +9 -5
  76. data/lib/rbs/prototype/runtime/value_object_generator.rb +7 -5
  77. data/lib/rbs/prototype/runtime.rb +4 -5
  78. data/lib/rbs/type_name.rb +14 -9
  79. data/lib/rbs/unit_test/type_assertions.rb +2 -2
  80. data/lib/rbs/validator.rb +3 -1
  81. data/lib/rbs/version.rb +1 -1
  82. data/lib/rdoc_plugin/parser.rb +2 -2
  83. data/rbs.gemspec +4 -0
  84. data/sig/ancestor_graph.rbs +4 -4
  85. data/sig/namespace.rbs +2 -3
  86. data/sig/resolver/constant_resolver.rbs +2 -2
  87. data/sig/resolver/context.rbs +1 -1
  88. data/sig/type_alias_regularity.rbs +5 -5
  89. data/sig/typename.rbs +8 -5
  90. data/sig/use_map.rbs +1 -1
  91. data/sig/validator.rbs +2 -2
  92. data/stdlib/base64/0/base64.rbs +0 -9
  93. data/stdlib/benchmark/0/benchmark.rbs +11 -2
  94. data/stdlib/bigdecimal/0/big_decimal.rbs +26 -182
  95. data/stdlib/cgi/0/core.rbs +47 -0
  96. data/stdlib/coverage/0/coverage.rbs +0 -3
  97. data/stdlib/csv/0/csv.rbs +18 -58
  98. data/stdlib/date/0/date.rbs +4 -19
  99. data/stdlib/did_you_mean/0/did_you_mean.rbs +0 -5
  100. data/stdlib/digest/0/digest.rbs +25 -2
  101. data/stdlib/erb/0/erb.rbs +0 -1
  102. data/stdlib/etc/0/etc.rbs +51 -34
  103. data/stdlib/fileutils/0/fileutils.rbs +3 -44
  104. data/stdlib/io-console/0/io-console.rbs +69 -15
  105. data/stdlib/ipaddr/0/ipaddr.rbs +8 -4
  106. data/stdlib/json/0/json.rbs +56 -71
  107. data/stdlib/logger/0/log_device.rbs +1 -1
  108. data/stdlib/logger/0/logger.rbs +3 -18
  109. data/stdlib/net-http/0/net-http.rbs +19 -77
  110. data/stdlib/nkf/0/nkf.rbs +30 -0
  111. data/stdlib/objspace/0/objspace.rbs +1 -2
  112. data/stdlib/observable/0/observable.rbs +1 -1
  113. data/stdlib/open-uri/0/open-uri.rbs +52 -0
  114. data/stdlib/open3/0/open3.rbs +0 -8
  115. data/stdlib/openssl/0/openssl.rbs +136 -69
  116. data/stdlib/optparse/0/optparse.rbs +58 -18
  117. data/stdlib/pathname/0/pathname.rbs +2 -8
  118. data/stdlib/pp/0/pp.rbs +3 -1
  119. data/stdlib/prettyprint/0/prettyprint.rbs +0 -4
  120. data/stdlib/pstore/0/pstore.rbs +0 -6
  121. data/stdlib/psych/0/psych.rbs +15 -4
  122. data/stdlib/pty/0/pty.rbs +46 -4
  123. data/stdlib/rdoc/0/code_object.rbs +0 -4
  124. data/stdlib/rdoc/0/markup.rbs +10 -12
  125. data/stdlib/rdoc/0/rdoc.rbs +1 -2
  126. data/stdlib/resolv/0/resolv.rbs +8 -3
  127. data/stdlib/ripper/0/ripper.rbs +0 -2
  128. data/stdlib/securerandom/0/securerandom.rbs +0 -2
  129. data/stdlib/shellwords/0/shellwords.rbs +11 -12
  130. data/stdlib/singleton/0/singleton.rbs +0 -1
  131. data/stdlib/socket/0/addrinfo.rbs +0 -1
  132. data/stdlib/socket/0/basic_socket.rbs +0 -5
  133. data/stdlib/socket/0/socket.rbs +49 -25
  134. data/stdlib/socket/0/tcp_server.rbs +0 -3
  135. data/stdlib/socket/0/tcp_socket.rbs +58 -3
  136. data/stdlib/socket/0/udp_socket.rbs +0 -1
  137. data/stdlib/socket/0/unix_server.rbs +0 -3
  138. data/stdlib/strscan/0/string_scanner.rbs +1265 -422
  139. data/stdlib/tempfile/0/tempfile.rbs +135 -28
  140. data/stdlib/time/0/time.rbs +48 -35
  141. data/stdlib/timeout/0/timeout.rbs +11 -8
  142. data/stdlib/tmpdir/0/tmpdir.rbs +8 -1
  143. data/stdlib/tsort/0/tsort.rbs +0 -4
  144. data/stdlib/uri/0/common.rbs +11 -30
  145. data/stdlib/uri/0/ftp.rbs +1 -1
  146. data/stdlib/uri/0/generic.rbs +22 -18
  147. data/stdlib/uri/0/http.rbs +2 -2
  148. data/stdlib/uri/0/rfc2396_parser.rbs +3 -0
  149. data/stdlib/zlib/0/buf_error.rbs +1 -70
  150. data/stdlib/zlib/0/data_error.rbs +1 -70
  151. data/stdlib/zlib/0/deflate.rbs +8 -72
  152. data/stdlib/zlib/0/error.rbs +1 -70
  153. data/stdlib/zlib/0/gzip_file/crc_error.rbs +2 -105
  154. data/stdlib/zlib/0/gzip_file/error.rbs +2 -105
  155. data/stdlib/zlib/0/gzip_file/length_error.rbs +2 -105
  156. data/stdlib/zlib/0/gzip_file/no_footer.rbs +2 -105
  157. data/stdlib/zlib/0/gzip_file.rbs +1 -71
  158. data/stdlib/zlib/0/gzip_reader.rbs +3 -74
  159. data/stdlib/zlib/0/gzip_writer.rbs +1 -70
  160. data/stdlib/zlib/0/inflate.rbs +4 -71
  161. data/stdlib/zlib/0/mem_error.rbs +1 -70
  162. data/stdlib/zlib/0/need_dict.rbs +1 -70
  163. data/stdlib/zlib/0/stream_end.rbs +1 -70
  164. data/stdlib/zlib/0/stream_error.rbs +1 -70
  165. data/stdlib/zlib/0/version_error.rbs +1 -70
  166. data/stdlib/zlib/0/zlib.rbs +0 -2
  167. data/stdlib/zlib/0/zstream.rbs +4 -72
  168. metadata +4 -6
@@ -1,108 +1,426 @@
1
1
  # <!-- rdoc-file=ext/strscan/strscan.c -->
2
- # StringScanner provides for lexical scanning operations on a String. Here is
3
- # an example of its usage:
4
- #
2
+ # Class `StringScanner` supports processing a stored string as a stream;
3
+ # this code creates a new `StringScanner` object with string `'foobarbaz'`:
5
4
  # require 'strscan'
5
+ # scanner = StringScanner.new('foobarbaz')
6
6
  #
7
- # s = StringScanner.new('This is an example string')
8
- # s.eos? # -> false
9
- #
10
- # p s.scan(/\w+/) # -> "This"
11
- # p s.scan(/\w+/) # -> nil
12
- # p s.scan(/\s+/) # -> " "
13
- # p s.scan(/\s+/) # -> nil
14
- # p s.scan(/\w+/) # -> "is"
15
- # s.eos? # -> false
16
- #
17
- # p s.scan(/\s+/) # -> " "
18
- # p s.scan(/\w+/) # -> "an"
19
- # p s.scan(/\s+/) # -> " "
20
- # p s.scan(/\w+/) # -> "example"
21
- # p s.scan(/\s+/) # -> " "
22
- # p s.scan(/\w+/) # -> "string"
23
- # s.eos? # -> true
24
- #
25
- # p s.scan(/\s+/) # -> nil
26
- # p s.scan(/\w+/) # -> nil
27
- #
28
- # Scanning a string means remembering the position of a *scan pointer*, which is
29
- # just an index. The point of scanning is to move forward a bit at a time, so
30
- # matches are sought after the scan pointer; usually immediately after it.
31
- #
32
- # Given the string "test string", here are the pertinent scan pointer positions:
33
- #
34
- # t e s t s t r i n g
35
- # 0 1 2 ... 1
36
- # 0
37
- #
38
- # When you #scan for a pattern (a regular expression), the match must occur at
39
- # the character after the scan pointer. If you use #scan_until, then the match
40
- # can occur anywhere after the scan pointer. In both cases, the scan pointer
41
- # moves *just beyond* the last character of the match, ready to scan again from
42
- # the next character onwards. This is demonstrated by the example above.
43
- #
44
- # ## Method Categories
45
- #
46
- # There are other methods besides the plain scanners. You can look ahead in the
47
- # string without actually scanning. You can access the most recent match. You
48
- # can modify the string being scanned, reset or terminate the scanner, find out
49
- # or change the position of the scan pointer, skip ahead, and so on.
7
+ # ## About the Examples
8
+ # All examples here assume that `StringScanner` has been required:
9
+ # require 'strscan'
50
10
  #
51
- # ### Advancing the Scan Pointer
11
+ # Some examples here assume that these constants are defined:
12
+ # MULTILINE_TEXT = <<~EOT
13
+ # Go placidly amid the noise and haste,
14
+ # and remember what peace there may be in silence.
15
+ # EOT
52
16
  #
53
- # * #getch
54
- # * #get_byte
55
- # * #scan
56
- # * #scan_until
57
- # * #skip
58
- # * #skip_until
17
+ # HIRAGANA_TEXT = 'こんにちは'
59
18
  #
19
+ # ENGLISH_TEXT = 'Hello'
60
20
  #
61
- # ### Looking Ahead
21
+ # Some examples here assume that certain helper methods are defined:
22
+ # * `put_situation(scanner)`:
23
+ # Displays the values of the scanner's
24
+ # methods #pos, #charpos, #rest, and #rest_size.
25
+ # * `put_match_values(scanner)`:
26
+ # Displays the scanner's [match
27
+ # values](rdoc-ref:StringScanner@Match+Values).
28
+ # * `match_values_cleared?(scanner)`:
29
+ # Returns whether the scanner's [match
30
+ # values](rdoc-ref:StringScanner@Match+Values) are cleared.
31
+ # See examples [[here]](ext/strscan/helper_methods_md.html).
32
+ # ## The `StringScanner` Object
33
+ # This code creates a `StringScanner` object
34
+ # (we'll call it simply a *scanner*),
35
+ # and shows some of its basic properties:
36
+ # scanner = StringScanner.new('foobarbaz')
37
+ # scanner.string # => "foobarbaz"
38
+ # put_situation(scanner)
39
+ # # Situation:
40
+ # # pos: 0
41
+ # # charpos: 0
42
+ # # rest: "foobarbaz"
43
+ # # rest_size: 9
62
44
  #
63
- # * #check
64
- # * #check_until
65
- # * #exist?
66
- # * #match?
67
- # * #peek
45
+ # The scanner has:
46
+ # * A *stored string*, which is:
47
+ # * Initially set by StringScanner.new(string) to the given `string`
48
+ # (`'foobarbaz'` in the example above).
49
+ # * Modifiable by methods #string=(new_string) and #concat(more_string).
50
+ # * Returned by method #string.
51
+ # More at [Stored String](rdoc-ref:StringScanner@Stored+String) below.
52
+ # * A *position*;
53
+ # a zero-based index into the bytes of the stored string (*not* into its
54
+ # characters):
55
+ # * Initially set by StringScanner.new to `0`.
56
+ # * Returned by method #pos.
57
+ # * Modifiable explicitly by methods #reset, #terminate, and
58
+ # #pos=(new_pos).
59
+ # * Modifiable implicitly (various traversing methods, among others).
60
+ # More at [Byte
61
+ # Position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) below.
62
+ # * A *target substring*,
63
+ # which is a trailing substring of the stored string;
64
+ # it extends from the current position to the end of the stored string:
65
+ # * Initially set by StringScanner.new(string) to the given `string`
66
+ # (`'foobarbaz'` in the example above).
67
+ # * Returned by method #rest.
68
+ # * Modified by any modification to either the stored string or the
69
+ # position.
70
+ # **Most importantly**:
71
+ # the searching and traversing methods operate on the target substring,
72
+ # which may be (and often is) less than the entire stored string.
73
+ # More at [Target Substring](rdoc-ref:StringScanner@Target+Substring) below.
74
+ # ## Stored String
75
+ # The *stored string* is the string stored in the `StringScanner` object.
76
+ # Each of these methods sets, modifies, or returns the stored string:
77
+ # Method | Effect
78
+ # --------------------|-----------------------------------------------
79
+ # ::new(string) | Creates a new scanner for the given string.
80
+ # #string=(new_string)| Replaces the existing stored string.
81
+ # #concat(more_string)|Appends a string to the existing stored string.
82
+ # #string | Returns the stored string.
83
+ # ## Positions
84
+ # A `StringScanner` object maintains a zero-based *byte position*
85
+ # and a zero-based *character position*.
86
+ # Each of these methods explicitly sets positions:
87
+ # Method | Effect
88
+ # ------------------------|--------------------------------------------------------
89
+ # #reset |Sets both positions to zero (begining of stored string).
90
+ # #terminate | Sets both positions to the end of the stored string.
91
+ # #pos=(new_byte_position)| Sets byte position; adjusts character position.
92
+ # ### Byte Position (Position)
93
+ # The byte position (or simply *position*)
94
+ # is a zero-based index into the bytes in the scanner's stored string;
95
+ # for a new `StringScanner` object, the byte position is zero.
96
+ # When the byte position is:
97
+ # * Zero (at the beginning), the target substring is the entire stored string.
98
+ # * Equal to the size of the stored string (at the end),
99
+ # the target substring is the empty string `''`.
100
+ # To get or set the byte position:
101
+ # * #pos: returns the byte position.
102
+ # * #pos=(new_pos): sets the byte position.
103
+ # Many methods use the byte position as the basis for finding matches;
104
+ # many others set, increment, or decrement the byte position:
105
+ # scanner = StringScanner.new('foobar')
106
+ # scanner.pos # => 0
107
+ # scanner.scan(/foo/) # => "foo" # Match found.
108
+ # scanner.pos # => 3 # Byte position incremented.
109
+ # scanner.scan(/foo/) # => nil # Match not found.
110
+ # scanner.pos # => 3 # Byte position not changed.
68
111
  #
112
+ # Some methods implicitly modify the byte position;
113
+ # see:
114
+ # * [Setting the Target
115
+ # Substring](rdoc-ref:StringScanner@Setting+the+Target+Substring).
116
+ # * [Traversing the Target
117
+ # Substring](rdoc-ref:StringScanner@Traversing+the+Target+Substring).
118
+ # The values of these methods are derived directly from the values of #pos and
119
+ # #string:
120
+ # * #charpos: the [character
121
+ # position](rdoc-ref:StringScanner@Character+Position).
122
+ # * #rest: the [target substring](rdoc-ref:StringScanner@Target+Substring).
123
+ # * #rest_size: `rest.size`.
124
+ # ### Character Position
125
+ # The character position is a zero-based index into the *characters*
126
+ # in the stored string;
127
+ # for a new `StringScanner` object, the character position is zero.
128
+ # Method #charpos returns the character position;
129
+ # its value may not be reset explicitly.
130
+ # Some methods change (increment or reset) the character position;
131
+ # see:
132
+ # * [Setting the Target
133
+ # Substring](rdoc-ref:StringScanner@Setting+the+Target+Substring).
134
+ # * [Traversing the Target
135
+ # Substring](rdoc-ref:StringScanner@Traversing+the+Target+Substring).
136
+ # Example (string includes multi-byte characters):
137
+ # scanner = StringScanner.new(ENGLISH_TEXT) # Five 1-byte characters.
138
+ # scanner.concat(HIRAGANA_TEXT) # Five 3-byte characters
139
+ # scanner.string # => "Helloこんにちは" # Twenty bytes in all.
140
+ # put_situation(scanner)
141
+ # # Situation:
142
+ # # pos: 0
143
+ # # charpos: 0
144
+ # # rest: "Helloこんにちは"
145
+ # # rest_size: 20
146
+ # scanner.scan(/Hello/) # => "Hello" # Five 1-byte characters.
147
+ # put_situation(scanner)
148
+ # # Situation:
149
+ # # pos: 5
150
+ # # charpos: 5
151
+ # # rest: "こんにちは"
152
+ # # rest_size: 15
153
+ # scanner.getch # => "こ" # One 3-byte character.
154
+ # put_situation(scanner)
155
+ # # Situation:
156
+ # # pos: 8
157
+ # # charpos: 6
158
+ # # rest: "んにちは"
159
+ # # rest_size: 12
69
160
  #
70
- # ### Finding Where we Are
161
+ # ## Target Substring
162
+ # The target substring is the the part of the [stored
163
+ # string](rdoc-ref:StringScanner@Stored+String)
164
+ # that extends from the current [byte
165
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) to the end of
166
+ # the stored string;
167
+ # it is always either:
168
+ # * The entire stored string (byte position is zero).
169
+ # * A trailing substring of the stored string (byte position positive).
170
+ # The target substring is returned by method #rest,
171
+ # and its size is returned by method #rest_size.
172
+ # Examples:
173
+ # scanner = StringScanner.new('foobarbaz')
174
+ # put_situation(scanner)
175
+ # # Situation:
176
+ # # pos: 0
177
+ # # charpos: 0
178
+ # # rest: "foobarbaz"
179
+ # # rest_size: 9
180
+ # scanner.pos = 3
181
+ # put_situation(scanner)
182
+ # # Situation:
183
+ # # pos: 3
184
+ # # charpos: 3
185
+ # # rest: "barbaz"
186
+ # # rest_size: 6
187
+ # scanner.pos = 9
188
+ # put_situation(scanner)
189
+ # # Situation:
190
+ # # pos: 9
191
+ # # charpos: 9
192
+ # # rest: ""
193
+ # # rest_size: 0
71
194
  #
72
- # * #beginning_of_line? (`#bol?`)
73
- # * #eos?
74
- # * #rest?
75
- # * #rest_size
76
- # * #pos
195
+ # ### Setting the Target Substring
196
+ # The target substring is set whenever:
197
+ # * The [stored string](rdoc-ref:StringScanner@Stored+String) is set (position
198
+ # reset to zero; target substring set to stored string).
199
+ # * The [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
200
+ # is set (target substring adjusted accordingly).
201
+ # ### Querying the Target Substring
202
+ # This table summarizes (details and examples at the links):
203
+ # Method | Returns
204
+ # ----------|---------------------------------
205
+ # #rest | Target substring.
206
+ # #rest_size|Size (bytes) of target substring.
207
+ # ### Searching the Target Substring
208
+ # A *search* method examines the target substring,
209
+ # but does not advance the [positions](rdoc-ref:StringScanner@Positions)
210
+ # or (by implication) shorten the target substring.
211
+ # This table summarizes (details and examples at the links):
212
+ # Method | Returns |Sets Match Values?
213
+ # ---------------------|---------------------------------------------|------------------
214
+ # #check(pattern) | Matched leading substring or +nil+. | Yes.
215
+ # #check_until(pattern)| Matched substring (anywhere) or +nil+. | Yes.
216
+ # #exist?(pattern) | Matched substring (anywhere) end index. | Yes.
217
+ # #match?(pattern) | Size of matched leading substring or +nil+. | Yes.
218
+ # #peek(size) | Leading substring of given length (bytes). | No.
219
+ # #peek_byte | Integer leading byte or +nil+. | No.
220
+ # #rest |Target substring (from byte position to end).| No.
221
+ # ### Traversing the Target Substring
222
+ # A *traversal* method examines the target substring,
223
+ # and, if successful:
224
+ # * Advances the [positions](rdoc-ref:StringScanner@Positions).
225
+ # * Shortens the target substring.
226
+ # This table summarizes (details and examples at links):
227
+ # Method | Returns |Sets Match Values?
228
+ # --------------------|----------------------------------------------------|------------------
229
+ # #get_byte | Leading byte or +nil+. | No.
230
+ # #getch | Leading character or +nil+. | No.
231
+ # #scan(pattern) | Matched leading substring or +nil+. | Yes.
232
+ # #scan_byte | Integer leading byte or +nil+. | No.
233
+ # #scan_until(pattern)| Matched substring (anywhere) or +nil+. | Yes.
234
+ # #skip(pattern) | Matched leading substring size or +nil+. | Yes.
235
+ # #skip_until(pattern)|Position delta to end-of-matched-substring or +nil+.| Yes.
236
+ # #unscan | +self+. | No.
237
+ # ## Querying the Scanner
238
+ # Each of these methods queries the scanner object
239
+ # without modifying it (details and examples at links)
240
+ # Method | Returns
241
+ # -------------------|--------------------------------
242
+ # #beginning_of_line?| +true+ or +false+.
243
+ # #charpos | Character position.
244
+ # #eos? | +true+ or +false+.
245
+ # #fixed_anchor? | +true+ or +false+.
246
+ # #inspect |String representation of +self+.
247
+ # #pos | Byte position.
248
+ # #rest | Target substring.
249
+ # #rest_size | Size of target substring.
250
+ # #string | Stored string.
251
+ # ## Matching
252
+ # `StringScanner` implements pattern matching via Ruby class
253
+ # [Regexp](https://docs.ruby-lang.org/en/master/Regexp.html),
254
+ # and its matching behaviors are the same as Ruby's
255
+ # except for the [fixed-anchor
256
+ # property](rdoc-ref:StringScanner@Fixed-Anchor+Property).
257
+ # ### Matcher Methods
258
+ # Each *matcher method* takes a single argument `pattern`,
259
+ # and attempts to find a matching substring in the [target
260
+ # substring](rdoc-ref:StringScanner@Target+Substring).
261
+ # Method | Pattern Type |Matches Target Substring| Success Return |May Update Positions?
262
+ # ------------|-----------------|------------------------|------------------|---------------------
263
+ # #check |Regexp or String.| At beginning. |Matched substring.| No.
264
+ # #check_until|Regexp or String.| Anywhere. | Substring. | No.
265
+ # #match? |Regexp or String.| At beginning. | Match size. | No.
266
+ # #exist? |Regexp or String.| Anywhere. | Substring size. | No.
267
+ # #scan |Regexp or String.| At beginning. |Matched substring.| Yes.
268
+ # #scan_until |Regexp or String.| Anywhere. | Substring. | Yes.
269
+ # #skip |Regexp or String.| At beginning. | Match size. | Yes.
270
+ # #skip_until |Regexp or String.| Anywhere. | Substring size. | Yes.
77
271
  #
272
+ # Which matcher you choose will depend on:
273
+ # * Where you want to find a match:
274
+ # * Only at the beginning of the target substring:
275
+ # #check, #match?, #scan, #skip.
276
+ # * Anywhere in the target substring:
277
+ # #check_until, #exist?, #scan_until, #skip_until.
278
+ # * Whether you want to:
279
+ # * Traverse, by advancing the positions:
280
+ # #scan, #scan_until, #skip, #skip_until.
281
+ # * Keep the positions unchanged:
282
+ # #check, #check_until, #match?, #exist?.
283
+ # * What you want for the return value:
284
+ # * The matched substring: #check, #scan.
285
+ # * The substring: #check_until, #scan_until.
286
+ # * The match size: #match?, #skip.
287
+ # * The substring size: #exist?, #skip_until.
288
+ # ### Match Values
289
+ # The *match values* in a `StringScanner` object
290
+ # generally contain the results of the most recent attempted match.
291
+ # Each match value may be thought of as:
292
+ # * *Clear*: Initially, or after an unsuccessful match attempt:
293
+ # usually, `false`, `nil`, or `{}`.
294
+ # * *Set*: After a successful match attempt:
295
+ # `true`, string, array, or hash.
296
+ # Each of these methods clears match values:
297
+ # * ::new(string).
298
+ # * #reset.
299
+ # * #terminate.
300
+ # Each of these methods attempts a match based on a pattern,
301
+ # and either sets match values (if successful) or clears them (if not);
302
+ # * #check(pattern)
303
+ # * #check_until(pattern)
304
+ # * #exist?(pattern)
305
+ # * #match?(pattern)
306
+ # * #scan(pattern)
307
+ # * #scan_until(pattern)
308
+ # * #skip(pattern)
309
+ # * #skip_until(pattern)
310
+ # #### Basic Match Values
311
+ # Basic match values are those not related to captures.
312
+ # Each of these methods returns a basic match value:
313
+ # Method | Return After Match |Return After No Match
314
+ # -------------|--------------------------------------|---------------------
315
+ # #matched? | +true+. | +false+.
316
+ # #matched_size| Size of matched substring. | +nil+.
317
+ # #matched | Matched substring. | +nil+.
318
+ # #pre_match |Substring preceding matched substring.| +nil+.
319
+ # #post_match |Substring following matched substring.| +nil+.
78
320
  #
79
- # ### Setting Where we Are
321
+ # See examples below.
322
+ # #### Captured Match Values
323
+ # Captured match values are those related to
324
+ # [captures](https://docs.ruby-lang.org/en/master/Regexp.html#class-Regexp-label
325
+ # -Groups+and+Captures).
326
+ # Each of these methods returns a captured match value:
327
+ # Method | Return After Match |Return After No Match
328
+ # ---------------|---------------------------------------|---------------------
329
+ # #size | Count of captured substrings. | +nil+.
330
+ # #[](n) | <tt>n</tt>th captured substring. | +nil+.
331
+ # #captures | Array of all captured substrings. | +nil+.
332
+ # #values_at(*n) |Array of specified captured substrings.| +nil+.
333
+ # #named_captures| Hash of named captures. | <tt>{}</tt>.
80
334
  #
81
- # * #reset
82
- # * #terminate
83
- # * #pos=
335
+ # See examples below.
336
+ # #### Match Values Examples
337
+ # Successful basic match attempt (no captures):
338
+ # scanner = StringScanner.new('foobarbaz')
339
+ # scanner.exist?(/bar/)
340
+ # put_match_values(scanner)
341
+ # # Basic match values:
342
+ # # matched?: true
343
+ # # matched_size: 3
344
+ # # pre_match: "foo"
345
+ # # matched : "bar"
346
+ # # post_match: "baz"
347
+ # # Captured match values:
348
+ # # size: 1
349
+ # # captures: []
350
+ # # named_captures: {}
351
+ # # values_at: ["bar", nil]
352
+ # # []:
353
+ # # [0]: "bar"
354
+ # # [1]: nil
84
355
  #
356
+ # Failed basic match attempt (no captures);
357
+ # scanner = StringScanner.new('foobarbaz')
358
+ # scanner.exist?(/nope/)
359
+ # match_values_cleared?(scanner) # => true
85
360
  #
86
- # ### Match Data
361
+ # Successful unnamed capture match attempt:
362
+ # scanner = StringScanner.new('foobarbazbatbam')
363
+ # scanner.exist?(/(foo)bar(baz)bat(bam)/)
364
+ # put_match_values(scanner)
365
+ # # Basic match values:
366
+ # # matched?: true
367
+ # # matched_size: 15
368
+ # # pre_match: ""
369
+ # # matched : "foobarbazbatbam"
370
+ # # post_match: ""
371
+ # # Captured match values:
372
+ # # size: 4
373
+ # # captures: ["foo", "baz", "bam"]
374
+ # # named_captures: {}
375
+ # # values_at: ["foobarbazbatbam", "foo", "baz", "bam", nil]
376
+ # # []:
377
+ # # [0]: "foobarbazbatbam"
378
+ # # [1]: "foo"
379
+ # # [2]: "baz"
380
+ # # [3]: "bam"
381
+ # # [4]: nil
87
382
  #
88
- # * #matched
89
- # * #matched?
90
- # * #matched_size
91
- # * `#[]`
92
- # * #pre_match
93
- # * #post_match
383
+ # Successful named capture match attempt;
384
+ # same as unnamed above, except for #named_captures:
385
+ # scanner = StringScanner.new('foobarbazbatbam')
386
+ # scanner.exist?(/(?<x>foo)bar(?<y>baz)bat(?<z>bam)/)
387
+ # scanner.named_captures # => {"x"=>"foo", "y"=>"baz", "z"=>"bam"}
94
388
  #
389
+ # Failed unnamed capture match attempt:
390
+ # scanner = StringScanner.new('somestring')
391
+ # scanner.exist?(/(foo)bar(baz)bat(bam)/)
392
+ # match_values_cleared?(scanner) # => true
95
393
  #
96
- # ### Miscellaneous
394
+ # Failed named capture match attempt;
395
+ # same as unnamed above, except for #named_captures:
396
+ # scanner = StringScanner.new('somestring')
397
+ # scanner.exist?(/(?<x>foo)bar(?<y>baz)bat(?<z>bam)/)
398
+ # match_values_cleared?(scanner) # => false
399
+ # scanner.named_captures # => {"x"=>nil, "y"=>nil, "z"=>nil}
97
400
  #
98
- # * `<<`
99
- # * #concat
100
- # * #string
101
- # * #string=
102
- # * #unscan
401
+ # ## Fixed-Anchor Property
402
+ # Pattern matching in `StringScanner` is the same as in Ruby's,
403
+ # except for its fixed-anchor property,
404
+ # which determines the meaning of `'\A'`:
405
+ # * `false` (the default): matches the current byte position.
406
+ # scanner = StringScanner.new('foobar')
407
+ # scanner.scan(/\A./) # => "f"
408
+ # scanner.scan(/\A./) # => "o"
409
+ # scanner.scan(/\A./) # => "o"
410
+ # scanner.scan(/\A./) # => "b"
103
411
  #
412
+ # * `true`: matches the beginning of the target substring;
413
+ # never matches unless the byte position is zero:
414
+ # scanner = StringScanner.new('foobar', fixed_anchor: true)
415
+ # scanner.scan(/\A./) # => "f"
416
+ # scanner.scan(/\A./) # => nil
417
+ # scanner.reset
418
+ # scanner.scan(/\A./) # => "f"
104
419
  #
105
- # There are aliases to several of the methods.
420
+ # The fixed-anchor property is set when the `StringScanner` object is created,
421
+ # and may not be modified
422
+ # (see StringScanner.new);
423
+ # method #fixed_anchor? returns the setting.
106
424
  #
107
425
  class StringScanner
108
426
  # <!--
@@ -114,61 +432,103 @@ class StringScanner
114
432
  def self.must_C_version: () -> self
115
433
 
116
434
  # <!-- rdoc-file=ext/strscan/strscan.c -->
117
- # Appends `str` to the string being scanned. This method does not affect scan
118
- # pointer.
119
- #
120
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
121
- # s.scan(/Fri /)
122
- # s << " +1000 GMT"
123
- # s.string # -> "Fri Dec 12 1975 14:39 +1000 GMT"
124
- # s.scan(/Dec/) # -> "Dec"
435
+ # * Appends the given `more_string`
436
+ # to the [stored string](rdoc-ref:StringScanner@Stored+String).
437
+ # * Returns `self`.
438
+ # * Does not affect the [positions](rdoc-ref:StringScanner@Positions)
439
+ # or [match values](rdoc-ref:StringScanner@Match+Values).
440
+ # scanner = StringScanner.new('foo')
441
+ # scanner.string # => "foo"
442
+ # scanner.terminate
443
+ # scanner.concat('barbaz') # => #<StringScanner 3/9 "foo" @ "barba...">
444
+ # scanner.string # => "foobarbaz"
445
+ # put_situation(scanner)
446
+ # # Situation:
447
+ # # pos: 3
448
+ # # charpos: 3
449
+ # # rest: "barbaz"
450
+ # # rest_size: 6
125
451
  #
126
452
  def <<: (String) -> self
127
453
 
128
454
  # <!--
129
455
  # rdoc-file=ext/strscan/strscan.c
130
- # - [](n)
456
+ # - [](specifier) -> substring or nil
131
457
  # -->
132
- # Returns the n-th subgroup in the most recent match.
133
- #
134
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
135
- # s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
136
- # s[0] # -> "Fri Dec 12 "
137
- # s[1] # -> "Fri"
138
- # s[2] # -> "Dec"
139
- # s[3] # -> "12"
140
- # s.post_match # -> "1975 14:39"
141
- # s.pre_match # -> ""
142
- #
143
- # s.reset
144
- # s.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /) # -> "Fri Dec 12 "
145
- # s[0] # -> "Fri Dec 12 "
146
- # s[1] # -> "Fri"
147
- # s[2] # -> "Dec"
148
- # s[3] # -> "12"
149
- # s[:wday] # -> "Fri"
150
- # s[:month] # -> "Dec"
151
- # s[:day] # -> "12"
152
- # s.post_match # -> "1975 14:39"
153
- # s.pre_match # -> ""
458
+ # Returns a captured substring or `nil`;
459
+ # see [Captured Match Values](rdoc-ref:StringScanner@Captured+Match+Values).
460
+ # When there are captures:
461
+ # scanner = StringScanner.new('Fri Dec 12 1975 14:39')
462
+ # scanner.scan(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /)
463
+ #
464
+ # * `specifier` zero: returns the entire matched substring:
465
+ # scanner[0] # => "Fri Dec 12 "
466
+ # scanner.pre_match # => ""
467
+ # scanner.post_match # => "1975 14:39"
468
+ #
469
+ # * `specifier` positive integer. returns the `n`th capture, or `nil` if out
470
+ # of range:
471
+ # scanner[1] # => "Fri"
472
+ # scanner[2] # => "Dec"
473
+ # scanner[3] # => "12"
474
+ # scanner[4] # => nil
475
+ #
476
+ # * `specifier` negative integer. counts backward from the last subgroup:
477
+ # scanner[-1] # => "12"
478
+ # scanner[-4] # => "Fri Dec 12 "
479
+ # scanner[-5] # => nil
480
+ #
481
+ # * `specifier` symbol or string. returns the named subgroup, or `nil` if no
482
+ # such:
483
+ # scanner[:wday] # => "Fri"
484
+ # scanner['wday'] # => "Fri"
485
+ # scanner[:month] # => "Dec"
486
+ # scanner[:day] # => "12"
487
+ # scanner[:nope] # => nil
488
+ #
489
+ # When there are no captures, only `[0]` returns non-`nil`:
490
+ # scanner = StringScanner.new('foobarbaz')
491
+ # scanner.exist?(/bar/)
492
+ # scanner[0] # => "bar"
493
+ # scanner[1] # => nil
494
+ #
495
+ # For a failed match, even `[0]` returns `nil`:
496
+ # scanner.scan(/nope/) # => nil
497
+ # scanner[0] # => nil
498
+ # scanner[1] # => nil
154
499
  #
155
500
  def []: (Integer) -> String?
156
501
 
157
502
  # <!--
158
503
  # rdoc-file=ext/strscan/strscan.c
159
- # - beginning_of_line?()
504
+ # - beginning_of_line? -> true or false
160
505
  # -->
161
- # Returns `true` if and only if the scan pointer is at the beginning of the
162
- # line.
506
+ # Returns whether the
507
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) is at the
508
+ # beginning of a line;
509
+ # that is, at the beginning of the [stored
510
+ # string](rdoc-ref:StringScanner@Stored+String)
511
+ # or immediately after a newline:
512
+ # scanner = StringScanner.new(MULTILINE_TEXT)
513
+ # scanner.string
514
+ # # => "Go placidly amid the noise and haste,\nand remember what peace there may be in silence.\n"
515
+ # scanner.pos # => 0
516
+ # scanner.beginning_of_line? # => true
517
+ #
518
+ # scanner.scan_until(/,/) # => "Go placidly amid the noise and haste,"
519
+ # scanner.beginning_of_line? # => false
163
520
  #
164
- # s = StringScanner.new("test\ntest\n")
165
- # s.bol? # => true
166
- # s.scan(/te/)
167
- # s.bol? # => false
168
- # s.scan(/st\n/)
169
- # s.bol? # => true
170
- # s.terminate
171
- # s.bol? # => true
521
+ # scanner.scan(/\n/) # => "\n"
522
+ # scanner.beginning_of_line? # => true
523
+ #
524
+ # scanner.terminate
525
+ # scanner.beginning_of_line? # => true
526
+ #
527
+ # scanner.concat('x')
528
+ # scanner.terminate
529
+ # scanner.beginning_of_line? # => false
530
+ #
531
+ # StringScanner#bol? is an alias for StringScanner#beginning_of_line?.
172
532
  #
173
533
  def beginning_of_line?: () -> bool
174
534
 
@@ -176,16 +536,23 @@ class StringScanner
176
536
 
177
537
  # <!--
178
538
  # rdoc-file=ext/strscan/strscan.c
179
- # - captures
539
+ # - captures -> substring_array or nil
180
540
  # -->
181
- # Returns the subgroups in the most recent match (not including the full match).
182
- # If nothing was priorly matched, it returns nil.
541
+ # Returns the array of [captured match
542
+ # values](rdoc-ref:StringScanner@Captured+Match+Values) at indexes `(1..)`
543
+ # if the most recent match attempt succeeded, or `nil` otherwise:
544
+ # scanner = StringScanner.new('Fri Dec 12 1975 14:39')
545
+ # scanner.captures # => nil
546
+ #
547
+ # scanner.exist?(/(?<wday>\w+) (?<month>\w+) (?<day>\d+) /)
548
+ # scanner.captures # => ["Fri", "Dec", "12"]
549
+ # scanner.values_at(*0..4) # => ["Fri Dec 12 ", "Fri", "Dec", "12", nil]
550
+ #
551
+ # scanner.exist?(/Fri/)
552
+ # scanner.captures # => []
183
553
  #
184
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
185
- # s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> "Fri Dec 12 "
186
- # s.captures # -> ["Fri", "Dec", "12", nil]
187
- # s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> nil
188
- # s.captures # -> nil
554
+ # scanner.scan(/nope/)
555
+ # scanner.captures # => nil
189
556
  #
190
557
  def captures: () -> Array[String]?
191
558
 
@@ -193,51 +560,116 @@ class StringScanner
193
560
  # rdoc-file=ext/strscan/strscan.c
194
561
  # - charpos()
195
562
  # -->
196
- # Returns the character position of the scan pointer. In the 'reset' position,
197
- # this value is zero. In the 'terminated' position (i.e. the string is
198
- # exhausted), this value is the size of the string.
199
- #
200
- # In short, it's a 0-based index into the string.
201
- #
202
- # s = StringScanner.new("abc\u00e4def\u00f6ghi")
203
- # s.charpos # -> 0
204
- # s.scan_until(/\u00e4/) # -> "abc\u00E4"
205
- # s.pos # -> 5
206
- # s.charpos # -> 4
563
+ # call-seq:
564
+ # charpos -> character_position
565
+ # Returns the [character position](rdoc-ref:StringScanner@Character+Position)
566
+ # (initially zero),
567
+ # which may be different from the [byte
568
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
569
+ # given by method #pos:
570
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
571
+ # scanner.string # => "こんにちは"
572
+ # scanner.getch # => "こ" # 3-byte character.
573
+ # scanner.getch # => "ん" # 3-byte character.
574
+ # put_situation(scanner)
575
+ # # Situation:
576
+ # # pos: 6
577
+ # # charpos: 2
578
+ # # rest: "にちは"
579
+ # # rest_size: 9
207
580
  #
208
581
  def charpos: () -> Integer
209
582
 
210
583
  # <!--
211
584
  # rdoc-file=ext/strscan/strscan.c
212
- # - check(pattern)
585
+ # - check(pattern) -> matched_substring or nil
213
586
  # -->
214
- # This returns the value that #scan would return, without advancing the scan
215
- # pointer. The match register is affected, though.
216
- #
217
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
218
- # s.check /Fri/ # -> "Fri"
219
- # s.pos # -> 0
220
- # s.matched # -> "Fri"
221
- # s.check /12/ # -> nil
222
- # s.matched # -> nil
223
- #
224
- # Mnemonic: it "checks" to see whether a #scan will return a value.
587
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
588
+ # at the beginning of the [target
589
+ # substring](rdoc-ref:StringScanner@Target+Substring);
590
+ # does not modify the [positions](rdoc-ref:StringScanner@Positions).
591
+ # If the match succeeds:
592
+ # * Returns the matched substring.
593
+ # * Sets all [match values](rdoc-ref:StringScanner@Match+Values).
594
+ # scanner = StringScanner.new('foobarbaz')
595
+ # scanner.pos = 3
596
+ # scanner.check('bar') # => "bar"
597
+ # put_match_values(scanner)
598
+ # # Basic match values:
599
+ # # matched?: true
600
+ # # matched_size: 3
601
+ # # pre_match: "foo"
602
+ # # matched : "bar"
603
+ # # post_match: "baz"
604
+ # # Captured match values:
605
+ # # size: 1
606
+ # # captures: []
607
+ # # named_captures: {}
608
+ # # values_at: ["bar", nil]
609
+ # # []:
610
+ # # [0]: "bar"
611
+ # # [1]: nil
612
+ # # => 0..1
613
+ # put_situation(scanner)
614
+ # # Situation:
615
+ # # pos: 3
616
+ # # charpos: 3
617
+ # # rest: "barbaz"
618
+ # # rest_size: 6
619
+ #
620
+ # If the match fails:
621
+ # * Returns `nil`.
622
+ # * Clears all [match values](rdoc-ref:StringScanner@Match+Values).
623
+ # scanner.check(/nope/) # => nil
624
+ # match_values_cleared?(scanner) # => true
225
625
  #
226
626
  def check: (Regexp) -> String?
227
627
 
228
628
  # <!--
229
629
  # rdoc-file=ext/strscan/strscan.c
230
- # - check_until(pattern)
630
+ # - check_until(pattern) -> substring or nil
231
631
  # -->
232
- # This returns the value that #scan_until would return, without advancing the
233
- # scan pointer. The match register is affected, though.
234
- #
235
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
236
- # s.check_until /12/ # -> "Fri Dec 12"
237
- # s.pos # -> 0
238
- # s.matched # -> 12
239
- #
240
- # Mnemonic: it "checks" to see whether a #scan_until will return a value.
632
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
633
+ # anywhere (at any
634
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29))
635
+ # in the [target substring](rdoc-ref:StringScanner@Target+Substring);
636
+ # does not modify the [positions](rdoc-ref:StringScanner@Positions).
637
+ # If the match succeeds:
638
+ # * Sets all [match values](rdoc-ref:StringScanner@Match+Values).
639
+ # * Returns the matched substring,
640
+ # which extends from the current
641
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
642
+ # to the end of the matched substring.
643
+ # scanner = StringScanner.new('foobarbazbatbam')
644
+ # scanner.pos = 6
645
+ # scanner.check_until(/bat/) # => "bazbat"
646
+ # put_match_values(scanner)
647
+ # # Basic match values:
648
+ # # matched?: true
649
+ # # matched_size: 3
650
+ # # pre_match: "foobarbaz"
651
+ # # matched : "bat"
652
+ # # post_match: "bam"
653
+ # # Captured match values:
654
+ # # size: 1
655
+ # # captures: []
656
+ # # named_captures: {}
657
+ # # values_at: ["bat", nil]
658
+ # # []:
659
+ # # [0]: "bat"
660
+ # # [1]: nil
661
+ # put_situation(scanner)
662
+ # # Situation:
663
+ # # pos: 6
664
+ # # charpos: 6
665
+ # # rest: "bazbatbam"
666
+ # # rest_size: 9
667
+ #
668
+ # If the match fails:
669
+ # * Clears all [match values](rdoc-ref:StringScanner@Match+Values).
670
+ # * Returns `nil`.
671
+ # scanner.check_until(/nope/) # => nil
672
+ # match_values_cleared?(scanner) # => true
241
673
  #
242
674
  def check_until: (Regexp) -> String
243
675
 
@@ -251,17 +683,24 @@ class StringScanner
251
683
 
252
684
  # <!--
253
685
  # rdoc-file=ext/strscan/strscan.c
254
- # - concat(str)
255
- # - <<(str)
686
+ # - concat(more_string) -> self
256
687
  # -->
257
- # Appends `str` to the string being scanned. This method does not affect scan
258
- # pointer.
259
- #
260
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
261
- # s.scan(/Fri /)
262
- # s << " +1000 GMT"
263
- # s.string # -> "Fri Dec 12 1975 14:39 +1000 GMT"
264
- # s.scan(/Dec/) # -> "Dec"
688
+ # * Appends the given `more_string`
689
+ # to the [stored string](rdoc-ref:StringScanner@Stored+String).
690
+ # * Returns `self`.
691
+ # * Does not affect the [positions](rdoc-ref:StringScanner@Positions)
692
+ # or [match values](rdoc-ref:StringScanner@Match+Values).
693
+ # scanner = StringScanner.new('foo')
694
+ # scanner.string # => "foo"
695
+ # scanner.terminate
696
+ # scanner.concat('barbaz') # => #<StringScanner 3/9 "foo" @ "barba...">
697
+ # scanner.string # => "foobarbaz"
698
+ # put_situation(scanner)
699
+ # # Situation:
700
+ # # pos: 3
701
+ # # charpos: 3
702
+ # # rest: "barbaz"
703
+ # # rest_size: 6
265
704
  #
266
705
  alias concat <<
267
706
 
@@ -275,43 +714,74 @@ class StringScanner
275
714
 
276
715
  # <!--
277
716
  # rdoc-file=ext/strscan/strscan.c
278
- # - eos?()
717
+ # - eos? -> true or false
279
718
  # -->
280
- # Returns `true` if the scan pointer is at the end of the string.
281
- #
282
- # s = StringScanner.new('test string')
283
- # p s.eos? # => false
284
- # s.scan(/test/)
285
- # p s.eos? # => false
286
- # s.terminate
287
- # p s.eos? # => true
719
+ # Returns whether the
720
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
721
+ # is at the end of the [stored string](rdoc-ref:StringScanner@Stored+String):
722
+ # scanner = StringScanner.new('foobarbaz')
723
+ # scanner.eos? # => false
724
+ # pos = 3
725
+ # scanner.eos? # => false
726
+ # scanner.terminate
727
+ # scanner.eos? # => true
288
728
  #
289
729
  def eos?: () -> bool
290
730
 
291
731
  # <!--
292
732
  # rdoc-file=ext/strscan/strscan.c
293
- # - exist?(pattern)
733
+ # - exist?(pattern) -> byte_offset or nil
294
734
  # -->
295
- # Looks *ahead* to see if the `pattern` exists *anywhere* in the string, without
296
- # advancing the scan pointer. This predicates whether a #scan_until will return
297
- # a value.
298
- #
299
- # s = StringScanner.new('test string')
300
- # s.exist? /s/ # -> 3
301
- # s.scan /test/ # -> "test"
302
- # s.exist? /s/ # -> 2
303
- # s.exist? /e/ # -> nil
735
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
736
+ # anywhere (at any
737
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29))
738
+ # n the [target substring](rdoc-ref:StringScanner@Target+Substring);
739
+ # does not modify the [positions](rdoc-ref:StringScanner@Positions).
740
+ # If the match succeeds:
741
+ # * Returns a byte offset:
742
+ # the distance in bytes between the current
743
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
744
+ # and the end of the matched substring.
745
+ # * Sets all [match values](rdoc-ref:StringScanner@Match+Values).
746
+ # scanner = StringScanner.new('foobarbazbatbam')
747
+ # scanner.pos = 6
748
+ # scanner.exist?(/bat/) # => 6
749
+ # put_match_values(scanner)
750
+ # # Basic match values:
751
+ # # matched?: true
752
+ # # matched_size: 3
753
+ # # pre_match: "foobarbaz"
754
+ # # matched : "bat"
755
+ # # post_match: "bam"
756
+ # # Captured match values:
757
+ # # size: 1
758
+ # # captures: []
759
+ # # named_captures: {}
760
+ # # values_at: ["bat", nil]
761
+ # # []:
762
+ # # [0]: "bat"
763
+ # # [1]: nil
764
+ # put_situation(scanner)
765
+ # # Situation:
766
+ # # pos: 6
767
+ # # charpos: 6
768
+ # # rest: "bazbatbam"
769
+ # # rest_size: 9
770
+ #
771
+ # If the match fails:
772
+ # * Returns `nil`.
773
+ # * Clears all [match values](rdoc-ref:StringScanner@Match+Values).
774
+ # scanner.exist?(/nope/) # => nil
775
+ # match_values_cleared?(scanner) # => true
304
776
  #
305
777
  def exist?: (Regexp) -> Integer?
306
778
 
307
779
  # <!--
308
780
  # rdoc-file=ext/strscan/strscan.c
309
- # - scanner.fixed_anchor? -> true or false
781
+ # - fixed_anchor? -> true or false
310
782
  # -->
311
- # Whether `scanner` uses fixed anchor mode or not.
312
- #
313
- # If fixed anchor mode is used, `\A` always matches the beginning of the string.
314
- # Otherwise, `\A` always matches the current position.
783
+ # Returns whether the [fixed-anchor
784
+ # property](rdoc-ref:StringScanner@Fixed-Anchor+Property) is set.
315
785
  #
316
786
  def fixed_anchor?: () -> bool
317
787
 
@@ -319,18 +789,30 @@ class StringScanner
319
789
  # rdoc-file=ext/strscan/strscan.c
320
790
  # - get_byte()
321
791
  # -->
322
- # Scans one byte and returns it. This method is not multibyte character
323
- # sensitive. See also: #getch.
324
- #
325
- # s = StringScanner.new('ab')
326
- # s.get_byte # => "a"
327
- # s.get_byte # => "b"
328
- # s.get_byte # => nil
329
- #
330
- # s = StringScanner.new("\244\242".force_encoding("euc-jp"))
331
- # s.get_byte # => "\xA4"
332
- # s.get_byte # => "\xA2"
333
- # s.get_byte # => nil
792
+ # call-seq:
793
+ # get_byte -> byte_as_character or nil
794
+ # Returns the next byte, if available:
795
+ # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
796
+ # is not at the end of the [stored
797
+ # string](rdoc-ref:StringScanner@Stored+String):
798
+ # * Returns the next byte.
799
+ # * Increments the [byte
800
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29).
801
+ # * Adjusts the [character
802
+ # position](rdoc-ref:StringScanner@Character+Position).
803
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
804
+ # # => #<StringScanner 0/15 @ "\xE3\x81\x93\xE3\x82...">
805
+ # scanner.string # => "こんにちは"
806
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\xE3", 1, 1]
807
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x81", 2, 2]
808
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x93", 3, 1]
809
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\xE3", 4, 2]
810
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x82", 5, 3]
811
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x93", 6, 2]
812
+ #
813
+ # * Otherwise, returns `nil`, and does not change the positions.
814
+ # scanner.terminate
815
+ # [scanner.get_byte, scanner.pos, scanner.charpos] # => [nil, 15, 5]
334
816
  #
335
817
  def get_byte: () -> String?
336
818
 
@@ -346,103 +828,185 @@ class StringScanner
346
828
  # rdoc-file=ext/strscan/strscan.c
347
829
  # - getch()
348
830
  # -->
349
- # Scans one character and returns it. This method is multibyte character
350
- # sensitive.
351
- #
352
- # s = StringScanner.new("ab")
353
- # s.getch # => "a"
354
- # s.getch # => "b"
355
- # s.getch # => nil
356
- #
357
- # s = StringScanner.new("\244\242".force_encoding("euc-jp"))
358
- # s.getch # => "\x{A4A2}" # Japanese hira-kana "A" in EUC-JP
359
- # s.getch # => nil
831
+ # call-seq:
832
+ # getch -> character or nil
833
+ # Returns the next (possibly multibyte) character,
834
+ # if available:
835
+ # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
836
+ # is at the beginning of a character:
837
+ # * Returns the character.
838
+ # * Increments the [character
839
+ # position](rdoc-ref:StringScanner@Character+Position) by 1.
840
+ # * Increments the [byte
841
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
842
+ # by the size (in bytes) of the character.
843
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
844
+ # scanner.string # => "こんにちは"
845
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["こ", 3, 1]
846
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["ん", 6, 2]
847
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["に", 9, 3]
848
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["ち", 12, 4]
849
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["は", 15, 5]
850
+ # [scanner.getch, scanner.pos, scanner.charpos] # => [nil, 15, 5]
851
+ #
852
+ # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) is
853
+ # within a multi-byte character
854
+ # (that is, not at its beginning),
855
+ # behaves like #get_byte (returns a 1-byte character):
856
+ # scanner.pos = 1
857
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["\x81", 2, 2]
858
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["\x93", 3, 1]
859
+ # [scanner.getch, scanner.pos, scanner.charpos] # => ["ん", 6, 2]
860
+ #
861
+ # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) is
862
+ # at the end of the [stored string](rdoc-ref:StringScanner@Stored+String),
863
+ # returns `nil` and does not modify the positions:
864
+ # scanner.terminate
865
+ # [scanner.getch, scanner.pos, scanner.charpos] # => [nil, 15, 5]
360
866
  #
361
867
  def getch: () -> String?
362
868
 
363
869
  # <!--
364
870
  # rdoc-file=ext/strscan/strscan.c
365
- # - inspect()
871
+ # - inspect -> string
366
872
  # -->
367
- # Returns a string that represents the StringScanner object, showing:
368
- # * the current position
369
- # * the size of the string
370
- # * the characters surrounding the scan pointer
371
- #
372
- # s = StringScanner.new("Fri Dec 12 1975 14:39") s.inspect # ->
373
- # '#<StringScanner 0/21 @ "Fri D...">' s.scan_until /12/ # -> "Fri Dec
374
- # 12" s.inspect # -> '#<StringScanner 10/21 "...ec 12" @ "
375
- # 1975...">'
873
+ # Returns a string representation of `self` that may show:
874
+ # 1. The current
875
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29).
876
+ # 2. The size (in bytes) of the [stored
877
+ # string](rdoc-ref:StringScanner@Stored+String).
878
+ # 3. The substring preceding the current position.
879
+ # 4. The substring following the current position (which is also the [target
880
+ # substring](rdoc-ref:StringScanner@Target+Substring)).
881
+ # scanner = StringScanner.new("Fri Dec 12 1975 14:39")
882
+ # scanner.pos = 11
883
+ # scanner.inspect # => "#<StringScanner 11/21 \"...c 12 \" @ \"1975 ...\">"
884
+ #
885
+ # If at beginning-of-string, item 4 above (following substring) is omitted:
886
+ # scanner.reset
887
+ # scanner.inspect # => "#<StringScanner 0/21 @ \"Fri D...\">"
888
+ #
889
+ # If at end-of-string, all items above are omitted:
890
+ # scanner.terminate
891
+ # scanner.inspect # => "#<StringScanner fin>"
376
892
  #
377
893
  def inspect: () -> String
378
894
 
379
895
  # <!--
380
896
  # rdoc-file=ext/strscan/strscan.c
381
- # - match?(pattern)
897
+ # - match?(pattern) -> updated_position or nil
382
898
  # -->
383
- # Tests whether the given `pattern` is matched from the current scan pointer.
384
- # Returns the length of the match, or `nil`. The scan pointer is not advanced.
385
- #
386
- # s = StringScanner.new('test string')
387
- # p s.match?(/\w+/) # -> 4
388
- # p s.match?(/\w+/) # -> 4
389
- # p s.match?("test") # -> 4
390
- # p s.match?(/\s+/) # -> nil
899
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
900
+ # at the beginning of the [target
901
+ # substring](rdoc-ref:StringScanner@Target+Substring);
902
+ # does not modify the [positions](rdoc-ref:StringScanner@Positions).
903
+ # If the match succeeds:
904
+ # * Sets [match values](rdoc-ref:StringScanner@Match+Values).
905
+ # * Returns the size in bytes of the matched substring.
906
+ # scanner = StringScanner.new('foobarbaz')
907
+ # scanner.pos = 3
908
+ # scanner.match?(/bar/) => 3
909
+ # put_match_values(scanner)
910
+ # # Basic match values:
911
+ # # matched?: true
912
+ # # matched_size: 3
913
+ # # pre_match: "foo"
914
+ # # matched : "bar"
915
+ # # post_match: "baz"
916
+ # # Captured match values:
917
+ # # size: 1
918
+ # # captures: []
919
+ # # named_captures: {}
920
+ # # values_at: ["bar", nil]
921
+ # # []:
922
+ # # [0]: "bar"
923
+ # # [1]: nil
924
+ # put_situation(scanner)
925
+ # # Situation:
926
+ # # pos: 3
927
+ # # charpos: 3
928
+ # # rest: "barbaz"
929
+ # # rest_size: 6
930
+ #
931
+ # If the match fails:
932
+ # * Clears match values.
933
+ # * Returns `nil`.
934
+ # * Does not increment positions.
935
+ # scanner.match?(/nope/) # => nil
936
+ # match_values_cleared?(scanner) # => true
391
937
  #
392
938
  def match?: (Regexp) -> Integer?
393
939
 
394
940
  # <!--
395
941
  # rdoc-file=ext/strscan/strscan.c
396
- # - matched()
942
+ # - matched -> matched_substring or nil
397
943
  # -->
398
- # Returns the last matched string.
399
- #
400
- # s = StringScanner.new('test string')
401
- # s.match?(/\w+/) # -> 4
402
- # s.matched # -> "test"
944
+ # Returns the matched substring from the most recent
945
+ # [match](rdoc-ref:StringScanner@Matching) attempt
946
+ # if it was successful,
947
+ # or `nil` otherwise;
948
+ # see [Basic Matched Values](rdoc-ref:StringScanner@Basic+Match+Values):
949
+ # scanner = StringScanner.new('foobarbaz')
950
+ # scanner.matched # => nil
951
+ # scanner.pos = 3
952
+ # scanner.match?(/bar/) # => 3
953
+ # scanner.matched # => "bar"
954
+ # scanner.match?(/nope/) # => nil
955
+ # scanner.matched # => nil
403
956
  #
404
957
  def matched: () -> String?
405
958
 
406
959
  # <!--
407
960
  # rdoc-file=ext/strscan/strscan.c
408
- # - matched?()
961
+ # - matched? -> true or false
409
962
  # -->
410
- # Returns `true` if and only if the last match was successful.
411
- #
412
- # s = StringScanner.new('test string')
413
- # s.match?(/\w+/) # => 4
414
- # s.matched? # => true
415
- # s.match?(/\d+/) # => nil
416
- # s.matched? # => false
963
+ # Returns `true` of the most recent [match
964
+ # attempt](rdoc-ref:StringScanner@Matching) was successful,
965
+ # `false` otherwise;
966
+ # see [Basic Matched Values](rdoc-ref:StringScanner@Basic+Match+Values):
967
+ # scanner = StringScanner.new('foobarbaz')
968
+ # scanner.matched? # => false
969
+ # scanner.pos = 3
970
+ # scanner.exist?(/baz/) # => 6
971
+ # scanner.matched? # => true
972
+ # scanner.exist?(/nope/) # => nil
973
+ # scanner.matched? # => false
417
974
  #
418
975
  def matched?: () -> bool
419
976
 
420
977
  # <!--
421
978
  # rdoc-file=ext/strscan/strscan.c
422
- # - matched_size()
979
+ # - matched_size -> substring_size or nil
423
980
  # -->
424
- # Returns the size of the most recent match in bytes, or `nil` if there was no
425
- # recent match. This is different than `matched.size`, which will return the
426
- # size in characters.
981
+ # Returns the size (in bytes) of the matched substring
982
+ # from the most recent match [match attempt](rdoc-ref:StringScanner@Matching) if
983
+ # it was successful,
984
+ # or `nil` otherwise;
985
+ # see [Basic Matched Values](rdoc-ref:StringScanner@Basic+Match+Values):
986
+ # scanner = StringScanner.new('foobarbaz')
987
+ # scanner.matched_size # => nil
427
988
  #
428
- # s = StringScanner.new('test string')
429
- # s.check /\w+/ # -> "test"
430
- # s.matched_size # -> 4
431
- # s.check /\d+/ # -> nil
432
- # s.matched_size # -> nil
989
+ # pos = 3
990
+ # scanner.exist?(/baz/) # => 9
991
+ # scanner.matched_size # => 3
992
+ #
993
+ # scanner.exist?(/nope/) # => nil
994
+ # scanner.matched_size # => nil
433
995
  #
434
996
  def matched_size: () -> Integer?
435
997
 
436
998
  # <!--
437
999
  # rdoc-file=ext/strscan/strscan.c
438
- # - peek(len)
1000
+ # - peek(length) -> substring
439
1001
  # -->
440
- # Extracts a string corresponding to `string[pos,len]`, without advancing the
441
- # scan pointer.
442
- #
443
- # s = StringScanner.new('test string')
444
- # s.peek(7) # => "test st"
445
- # s.peek(7) # => "test st"
1002
+ # Returns the substring `string[pos, length]`;
1003
+ # does not update [match values](rdoc-ref:StringScanner@Match+Values) or
1004
+ # [positions](rdoc-ref:StringScanner@Positions):
1005
+ # scanner = StringScanner.new('foobarbaz')
1006
+ # scanner.pos = 3
1007
+ # scanner.peek(3) # => "bar"
1008
+ # scanner.terminate
1009
+ # scanner.peek(3) # => ""
446
1010
  #
447
1011
  def peek: (Integer) -> String
448
1012
 
@@ -455,27 +1019,42 @@ class StringScanner
455
1019
  def peep: (Integer) -> String
456
1020
 
457
1021
  # <!-- rdoc-file=ext/strscan/strscan.c -->
458
- # Returns the byte position of the scan pointer. In the 'reset' position, this
459
- # value is zero. In the 'terminated' position (i.e. the string is exhausted),
460
- # this value is the bytesize of the string.
461
- #
462
- # In short, it's a 0-based index into bytes of the string.
463
- #
464
- # s = StringScanner.new('test string')
465
- # s.pos # -> 0
466
- # s.scan_until /str/ # -> "test str"
467
- # s.pos # -> 8
468
- # s.terminate # -> #<StringScanner fin>
469
- # s.pos # -> 11
1022
+ # call-seq:
1023
+ # pos -> byte_position
1024
+ # Returns the integer [byte
1025
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29),
1026
+ # which may be different from the [character
1027
+ # position](rdoc-ref:StringScanner@Character+Position):
1028
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1029
+ # scanner.string # => "こんにちは"
1030
+ # scanner.pos # => 0
1031
+ # scanner.getch # => "こ" # 3-byte character.
1032
+ # scanner.charpos # => 1
1033
+ # scanner.pos # => 3
470
1034
  #
471
1035
  def pointer: () -> Integer
472
1036
 
473
1037
  # <!-- rdoc-file=ext/strscan/strscan.c -->
474
- # Sets the byte position of the scan pointer.
475
- #
476
- # s = StringScanner.new('test string')
477
- # s.pos = 7 # -> 7
478
- # s.rest # -> "ring"
1038
+ # call-seq:
1039
+ # pos = n -> n
1040
+ # pointer = n -> n
1041
+ # Sets the [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
1042
+ # and the [character position](rdoc-ref:StringScanner@Positions);
1043
+ # returns `n`.
1044
+ # Does not affect [match values](rdoc-ref:StringScanner@Match+Values).
1045
+ # For non-negative `n`, sets the position to `n`:
1046
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1047
+ # scanner.string # => "こんにちは"
1048
+ # scanner.pos = 3 # => 3
1049
+ # scanner.rest # => "んにちは"
1050
+ # scanner.charpos # => 1
1051
+ #
1052
+ # For negative `n`, counts from the end of the [stored
1053
+ # string](rdoc-ref:StringScanner@Stored+String):
1054
+ # scanner.pos = -9 # => -9
1055
+ # scanner.pos # => 6
1056
+ # scanner.rest # => "にちは"
1057
+ # scanner.charpos # => 2
479
1058
  #
480
1059
  def pointer=: (Integer) -> Integer
481
1060
 
@@ -483,77 +1062,124 @@ class StringScanner
483
1062
  # rdoc-file=ext/strscan/strscan.c
484
1063
  # - pos()
485
1064
  # -->
486
- # Returns the byte position of the scan pointer. In the 'reset' position, this
487
- # value is zero. In the 'terminated' position (i.e. the string is exhausted),
488
- # this value is the bytesize of the string.
489
- #
490
- # In short, it's a 0-based index into bytes of the string.
491
- #
492
- # s = StringScanner.new('test string')
493
- # s.pos # -> 0
494
- # s.scan_until /str/ # -> "test str"
495
- # s.pos # -> 8
496
- # s.terminate # -> #<StringScanner fin>
497
- # s.pos # -> 11
1065
+ # call-seq:
1066
+ # pos -> byte_position
1067
+ # Returns the integer [byte
1068
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29),
1069
+ # which may be different from the [character
1070
+ # position](rdoc-ref:StringScanner@Character+Position):
1071
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1072
+ # scanner.string # => "こんにちは"
1073
+ # scanner.pos # => 0
1074
+ # scanner.getch # => "こ" # 3-byte character.
1075
+ # scanner.charpos # => 1
1076
+ # scanner.pos # => 3
498
1077
  #
499
1078
  def pos: () -> Integer
500
1079
 
501
1080
  # <!--
502
1081
  # rdoc-file=ext/strscan/strscan.c
503
- # - pos=(n)
1082
+ # - pos=(p1)
504
1083
  # -->
505
- # Sets the byte position of the scan pointer.
506
- #
507
- # s = StringScanner.new('test string')
508
- # s.pos = 7 # -> 7
509
- # s.rest # -> "ring"
1084
+ # call-seq:
1085
+ # pos = n -> n
1086
+ # pointer = n -> n
1087
+ # Sets the [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
1088
+ # and the [character position](rdoc-ref:StringScanner@Positions);
1089
+ # returns `n`.
1090
+ # Does not affect [match values](rdoc-ref:StringScanner@Match+Values).
1091
+ # For non-negative `n`, sets the position to `n`:
1092
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1093
+ # scanner.string # => "こんにちは"
1094
+ # scanner.pos = 3 # => 3
1095
+ # scanner.rest # => "んにちは"
1096
+ # scanner.charpos # => 1
1097
+ #
1098
+ # For negative `n`, counts from the end of the [stored
1099
+ # string](rdoc-ref:StringScanner@Stored+String):
1100
+ # scanner.pos = -9 # => -9
1101
+ # scanner.pos # => 6
1102
+ # scanner.rest # => "にちは"
1103
+ # scanner.charpos # => 2
510
1104
  #
511
1105
  def pos=: (Integer) -> Integer
512
1106
 
513
1107
  # <!--
514
1108
  # rdoc-file=ext/strscan/strscan.c
515
- # - post_match()
1109
+ # - post_match -> substring
516
1110
  # -->
517
- # Returns the ***post**-match* (in the regular expression sense) of the last
518
- # scan.
1111
+ # Returns the substring that follows the matched substring
1112
+ # from the most recent match attempt if it was successful,
1113
+ # or `nil` otherwise;
1114
+ # see [Basic Match Values](rdoc-ref:StringScanner@Basic+Match+Values):
1115
+ # scanner = StringScanner.new('foobarbaz')
1116
+ # scanner.post_match # => nil
519
1117
  #
520
- # s = StringScanner.new('test string')
521
- # s.scan(/\w+/) # -> "test"
522
- # s.scan(/\s+/) # -> " "
523
- # s.pre_match # -> "test"
524
- # s.post_match # -> "string"
1118
+ # scanner.pos = 3
1119
+ # scanner.match?(/bar/) # => 3
1120
+ # scanner.post_match # => "baz"
1121
+ #
1122
+ # scanner.match?(/nope/) # => nil
1123
+ # scanner.post_match # => nil
525
1124
  #
526
1125
  def post_match: () -> String
527
1126
 
528
1127
  # <!--
529
1128
  # rdoc-file=ext/strscan/strscan.c
530
- # - pre_match()
1129
+ # - pre_match -> substring
531
1130
  # -->
532
- # Returns the ***pre**-match* (in the regular expression sense) of the last
533
- # scan.
1131
+ # Returns the substring that precedes the matched substring
1132
+ # from the most recent match attempt if it was successful,
1133
+ # or `nil` otherwise;
1134
+ # see [Basic Match Values](rdoc-ref:StringScanner@Basic+Match+Values):
1135
+ # scanner = StringScanner.new('foobarbaz')
1136
+ # scanner.pre_match # => nil
534
1137
  #
535
- # s = StringScanner.new('test string')
536
- # s.scan(/\w+/) # -> "test"
537
- # s.scan(/\s+/) # -> " "
538
- # s.pre_match # -> "test"
539
- # s.post_match # -> "string"
1138
+ # scanner.pos = 3
1139
+ # scanner.exist?(/baz/) # => 6
1140
+ # scanner.pre_match # => "foobar" # Substring of entire string, not just target string.
1141
+ #
1142
+ # scanner.exist?(/nope/) # => nil
1143
+ # scanner.pre_match # => nil
540
1144
  #
541
1145
  def pre_match: () -> String
542
1146
 
543
1147
  # <!--
544
1148
  # rdoc-file=ext/strscan/strscan.c
545
- # - reset()
1149
+ # - reset -> self
546
1150
  # -->
547
- # Reset the scan pointer (index 0) and clear matching data.
1151
+ # Sets both [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)
1152
+ # and [character position](rdoc-ref:StringScanner@Character+Position) to zero,
1153
+ # and clears [match values](rdoc-ref:StringScanner@Match+Values);
1154
+ # returns `self`:
1155
+ # scanner = StringScanner.new('foobarbaz')
1156
+ # scanner.exist?(/bar/) # => 6
1157
+ # scanner.reset # => #<StringScanner 0/9 @ "fooba...">
1158
+ # put_situation(scanner)
1159
+ # # Situation:
1160
+ # # pos: 0
1161
+ # # charpos: 0
1162
+ # # rest: "foobarbaz"
1163
+ # # rest_size: 9
1164
+ # # => nil
1165
+ # match_values_cleared?(scanner) # => true
548
1166
  #
549
1167
  def reset: () -> void
550
1168
 
551
1169
  # <!--
552
1170
  # rdoc-file=ext/strscan/strscan.c
553
- # - rest()
1171
+ # - rest -> target_substring
554
1172
  # -->
555
- # Returns the "rest" of the string (i.e. everything after the scan pointer). If
556
- # there is no more data (eos? = true), it returns `""`.
1173
+ # Returns the 'rest' of the [stored
1174
+ # string](rdoc-ref:StringScanner@Stored+String) (all after the current
1175
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)),
1176
+ # which is the [target substring](rdoc-ref:StringScanner@Target+Substring):
1177
+ # scanner = StringScanner.new('foobarbaz')
1178
+ # scanner.rest # => "foobarbaz"
1179
+ # scanner.pos = 3
1180
+ # scanner.rest # => "barbaz"
1181
+ # scanner.terminate
1182
+ # scanner.rest # => ""
557
1183
  #
558
1184
  def rest: () -> String
559
1185
 
@@ -573,9 +1199,19 @@ class StringScanner
573
1199
 
574
1200
  # <!--
575
1201
  # rdoc-file=ext/strscan/strscan.c
576
- # - rest_size()
1202
+ # - rest_size -> integer
577
1203
  # -->
578
- # `s.rest_size` is equivalent to `s.rest.size`.
1204
+ # Returns the size (in bytes) of the #rest of the [stored
1205
+ # string](rdoc-ref:StringScanner@Stored+String):
1206
+ # scanner = StringScanner.new('foobarbaz')
1207
+ # scanner.rest # => "foobarbaz"
1208
+ # scanner.rest_size # => 9
1209
+ # scanner.pos = 3
1210
+ # scanner.rest # => "barbaz"
1211
+ # scanner.rest_size # => 6
1212
+ # scanner.terminate
1213
+ # scanner.rest # => ""
1214
+ # scanner.rest_size # => 0
579
1215
  #
580
1216
  def rest_size: () -> Integer
581
1217
 
@@ -590,19 +1226,53 @@ class StringScanner
590
1226
 
591
1227
  # <!--
592
1228
  # rdoc-file=ext/strscan/strscan.c
593
- # - scan(pattern) => String
1229
+ # - scan(p1)
594
1230
  # -->
595
- # Tries to match with `pattern` at the current position. If there's a match, the
596
- # scanner advances the "scan pointer" and returns the matched string. Otherwise,
597
- # the scanner returns `nil`.
598
- #
599
- # s = StringScanner.new('test string')
600
- # p s.scan(/\w+/) # -> "test"
601
- # p s.scan(/\w+/) # -> nil
602
- # p s.scan(/\s+/) # -> " "
603
- # p s.scan("str") # -> "str"
604
- # p s.scan(/\w+/) # -> "ing"
605
- # p s.scan(/./) # -> nil
1231
+ # call-seq:
1232
+ # scan(pattern) -> substring or nil
1233
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
1234
+ # at the beginning of the [target
1235
+ # substring](rdoc-ref:StringScanner@Target+Substring).
1236
+ # If the match succeeds:
1237
+ # * Returns the matched substring.
1238
+ # * Increments the [byte
1239
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) by
1240
+ # `substring.bytesize`,
1241
+ # and may increment the [character
1242
+ # position](rdoc-ref:StringScanner@Character+Position).
1243
+ # * Sets [match values](rdoc-ref:StringScanner@Match+Values).
1244
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1245
+ # scanner.string # => "こんにちは"
1246
+ # scanner.pos = 6
1247
+ # scanner.scan(/に/) # => "に"
1248
+ # put_match_values(scanner)
1249
+ # # Basic match values:
1250
+ # # matched?: true
1251
+ # # matched_size: 3
1252
+ # # pre_match: "こん"
1253
+ # # matched : "に"
1254
+ # # post_match: "ちは"
1255
+ # # Captured match values:
1256
+ # # size: 1
1257
+ # # captures: []
1258
+ # # named_captures: {}
1259
+ # # values_at: ["に", nil]
1260
+ # # []:
1261
+ # # [0]: "に"
1262
+ # # [1]: nil
1263
+ # put_situation(scanner)
1264
+ # # Situation:
1265
+ # # pos: 9
1266
+ # # charpos: 3
1267
+ # # rest: "ちは"
1268
+ # # rest_size: 6
1269
+ #
1270
+ # If the match fails:
1271
+ # * Returns `nil`.
1272
+ # * Does not increment byte and character positions.
1273
+ # * Clears match values.
1274
+ # scanner.scan(/nope/) # => nil
1275
+ # match_values_cleared?(scanner) # => true
606
1276
  #
607
1277
  def scan: (Regexp) -> String?
608
1278
 
@@ -620,16 +1290,54 @@ class StringScanner
620
1290
 
621
1291
  # <!--
622
1292
  # rdoc-file=ext/strscan/strscan.c
623
- # - scan_until(pattern)
1293
+ # - scan_until(p1)
624
1294
  # -->
625
- # Scans the string *until* the `pattern` is matched. Returns the substring up
626
- # to and including the end of the match, advancing the scan pointer to that
627
- # location. If there is no match, `nil` is returned.
628
- #
629
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
630
- # s.scan_until(/1/) # -> "Fri Dec 1"
631
- # s.pre_match # -> "Fri Dec "
632
- # s.scan_until(/XYZ/) # -> nil
1295
+ # call-seq:
1296
+ # scan_until(pattern) -> substring or nil
1297
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
1298
+ # anywhere (at any
1299
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)) in the
1300
+ # [target substring](rdoc-ref:StringScanner@Target+Substring).
1301
+ # If the match attempt succeeds:
1302
+ # * Sets [match values](rdoc-ref:StringScanner@Match+Values).
1303
+ # * Sets the [byte
1304
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) to the end
1305
+ # of the matched substring;
1306
+ # may adjust the [character
1307
+ # position](rdoc-ref:StringScanner@Character+Position).
1308
+ # * Returns the matched substring.
1309
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1310
+ # scanner.string # => "こんにちは"
1311
+ # scanner.pos = 6
1312
+ # scanner.scan_until(/ち/) # => "にち"
1313
+ # put_match_values(scanner)
1314
+ # # Basic match values:
1315
+ # # matched?: true
1316
+ # # matched_size: 3
1317
+ # # pre_match: "こんに"
1318
+ # # matched : "ち"
1319
+ # # post_match: "は"
1320
+ # # Captured match values:
1321
+ # # size: 1
1322
+ # # captures: []
1323
+ # # named_captures: {}
1324
+ # # values_at: ["ち", nil]
1325
+ # # []:
1326
+ # # [0]: "ち"
1327
+ # # [1]: nil
1328
+ # put_situation(scanner)
1329
+ # # Situation:
1330
+ # # pos: 12
1331
+ # # charpos: 4
1332
+ # # rest: "は"
1333
+ # # rest_size: 3
1334
+ #
1335
+ # If the match attempt fails:
1336
+ # * Clears match data.
1337
+ # * Returns `nil`.
1338
+ # * Does not update positions.
1339
+ # scanner.scan_until(/nope/) # => nil
1340
+ # match_values_cleared?(scanner) # => true
633
1341
  #
634
1342
  def scan_until: (Regexp) -> String?
635
1343
 
@@ -646,110 +1354,237 @@ class StringScanner
646
1354
 
647
1355
  # <!--
648
1356
  # rdoc-file=ext/strscan/strscan.c
649
- # - size
1357
+ # - size -> captures_count
650
1358
  # -->
651
- # Returns the amount of subgroups in the most recent match. The full match
652
- # counts as a subgroup.
1359
+ # Returns the count of captures if the most recent match attempt succeeded,
1360
+ # `nil` otherwise;
1361
+ # see [Captures Match Values](rdoc-ref:StringScanner@Captured+Match+Values):
1362
+ # scanner = StringScanner.new('Fri Dec 12 1975 14:39')
1363
+ # scanner.size # => nil
1364
+ #
1365
+ # pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) /
1366
+ # scanner.match?(pattern)
1367
+ # scanner.values_at(*0..scanner.size) # => ["Fri Dec 12 ", "Fri", "Dec", "12", nil]
1368
+ # scanner.size # => 4
653
1369
  #
654
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
655
- # s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
656
- # s.size # -> 4
1370
+ # scanner.match?(/nope/) # => nil
1371
+ # scanner.size # => nil
657
1372
  #
658
1373
  def size: () -> Integer
659
1374
 
660
1375
  # <!--
661
1376
  # rdoc-file=ext/strscan/strscan.c
662
- # - skip(pattern)
1377
+ # - skip(p1)
663
1378
  # -->
664
- # Attempts to skip over the given `pattern` beginning with the scan pointer. If
665
- # it matches, the scan pointer is advanced to the end of the match, and the
666
- # length of the match is returned. Otherwise, `nil` is returned.
667
- #
668
- # It's similar to #scan, but without returning the matched string.
669
- #
670
- # s = StringScanner.new('test string')
671
- # p s.skip(/\w+/) # -> 4
672
- # p s.skip(/\w+/) # -> nil
673
- # p s.skip(/\s+/) # -> 1
674
- # p s.skip("st") # -> 2
675
- # p s.skip(/\w+/) # -> 4
676
- # p s.skip(/./) # -> nil
1379
+ # call-seq:
1380
+ # skip(pattern) match_size or nil
1381
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
1382
+ # at the beginning of the [target
1383
+ # substring](rdoc-ref:StringScanner@Target+Substring);
1384
+ # If the match succeeds:
1385
+ # * Increments the [byte
1386
+ # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) by
1387
+ # substring.bytesize,
1388
+ # and may increment the [character
1389
+ # position](rdoc-ref:StringScanner@Character+Position).
1390
+ # * Sets [match values](rdoc-ref:StringScanner@Match+Values).
1391
+ # * Returns the size (bytes) of the matched substring.
1392
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1393
+ # scanner.string # => "こんにちは"
1394
+ # scanner.pos = 6
1395
+ # scanner.skip(/に/) # => 3
1396
+ # put_match_values(scanner)
1397
+ # # Basic match values:
1398
+ # # matched?: true
1399
+ # # matched_size: 3
1400
+ # # pre_match: "こん"
1401
+ # # matched : "に"
1402
+ # # post_match: "ちは"
1403
+ # # Captured match values:
1404
+ # # size: 1
1405
+ # # captures: []
1406
+ # # named_captures: {}
1407
+ # # values_at: ["に", nil]
1408
+ # # []:
1409
+ # # [0]: "に"
1410
+ # # [1]: nil
1411
+ # put_situation(scanner)
1412
+ # # Situation:
1413
+ # # pos: 9
1414
+ # # charpos: 3
1415
+ # # rest: "ちは"
1416
+ # # rest_size: 6
1417
+ #
1418
+ # scanner.skip(/nope/) # => nil
1419
+ # match_values_cleared?(scanner) # => true
677
1420
  #
678
1421
  def skip: (Regexp) -> Integer?
679
1422
 
680
1423
  # <!--
681
1424
  # rdoc-file=ext/strscan/strscan.c
682
- # - skip_until(pattern)
1425
+ # - skip_until(p1)
683
1426
  # -->
684
- # Advances the scan pointer until `pattern` is matched and consumed. Returns
685
- # the number of bytes advanced, or `nil` if no match was found.
686
- #
687
- # Look ahead to match `pattern`, and advance the scan pointer to the *end* of
688
- # the match. Return the number of characters advanced, or `nil` if the match
689
- # was unsuccessful.
690
- #
691
- # It's similar to #scan_until, but without returning the intervening string.
692
- #
693
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
694
- # s.skip_until /12/ # -> 10
695
- # s #
1427
+ # call-seq:
1428
+ # skip_until(pattern) -> matched_substring_size or nil
1429
+ # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern`
1430
+ # anywhere (at any
1431
+ # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)) in the
1432
+ # [target substring](rdoc-ref:StringScanner@Target+Substring);
1433
+ # does not modify the positions.
1434
+ # If the match attempt succeeds:
1435
+ # * Sets [match values](rdoc-ref:StringScanner@Match+Values).
1436
+ # * Returns the size of the matched substring.
1437
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1438
+ # scanner.string # => "こんにちは"
1439
+ # scanner.pos = 6
1440
+ # scanner.skip_until(/ち/) # => 6
1441
+ # put_match_values(scanner)
1442
+ # # Basic match values:
1443
+ # # matched?: true
1444
+ # # matched_size: 3
1445
+ # # pre_match: "こんに"
1446
+ # # matched : "ち"
1447
+ # # post_match: "は"
1448
+ # # Captured match values:
1449
+ # # size: 1
1450
+ # # captures: []
1451
+ # # named_captures: {}
1452
+ # # values_at: ["ち", nil]
1453
+ # # []:
1454
+ # # [0]: "ち"
1455
+ # # [1]: nil
1456
+ # put_situation(scanner)
1457
+ # # Situation:
1458
+ # # pos: 12
1459
+ # # charpos: 4
1460
+ # # rest: "は"
1461
+ # # rest_size: 3
1462
+ #
1463
+ # If the match attempt fails:
1464
+ # * Clears match values.
1465
+ # * Returns `nil`.
1466
+ # scanner.skip_until(/nope/) # => nil
1467
+ # match_values_cleared?(scanner) # => true
696
1468
  #
697
1469
  def skip_until: (Regexp) -> Integer?
698
1470
 
699
1471
  # <!--
700
1472
  # rdoc-file=ext/strscan/strscan.c
701
- # - string()
1473
+ # - string -> stored_string
702
1474
  # -->
703
- # Returns the string being scanned.
1475
+ # Returns the [stored string](rdoc-ref:StringScanner@Stored+String):
1476
+ # scanner = StringScanner.new('foobar')
1477
+ # scanner.string # => "foobar"
1478
+ # scanner.concat('baz')
1479
+ # scanner.string # => "foobarbaz"
704
1480
  #
705
1481
  def string: () -> String
706
1482
 
707
1483
  # <!--
708
1484
  # rdoc-file=ext/strscan/strscan.c
709
- # - string=(str)
1485
+ # - string = other_string -> other_string
710
1486
  # -->
711
- # Changes the string being scanned to `str` and resets the scanner. Returns
712
- # `str`.
1487
+ # Replaces the [stored string](rdoc-ref:StringScanner@Stored+String) with the
1488
+ # given `other_string`:
1489
+ # * Sets both [positions](rdoc-ref:StringScanner@Positions) to zero.
1490
+ # * Clears [match values](rdoc-ref:StringScanner@Match+Values).
1491
+ # * Returns `other_string`.
1492
+ # scanner = StringScanner.new('foobar')
1493
+ # scanner.scan(/foo/)
1494
+ # put_situation(scanner)
1495
+ # # Situation:
1496
+ # # pos: 3
1497
+ # # charpos: 3
1498
+ # # rest: "bar"
1499
+ # # rest_size: 3
1500
+ # match_values_cleared?(scanner) # => false
1501
+ #
1502
+ # scanner.string = 'baz' # => "baz"
1503
+ # put_situation(scanner)
1504
+ # # Situation:
1505
+ # # pos: 0
1506
+ # # charpos: 0
1507
+ # # rest: "baz"
1508
+ # # rest_size: 3
1509
+ # match_values_cleared?(scanner) # => true
713
1510
  #
714
1511
  def string=: (String) -> String
715
1512
 
716
1513
  # <!--
717
1514
  # rdoc-file=ext/strscan/strscan.c
718
- # - terminate
719
- # - clear
1515
+ # - terminate()
720
1516
  # -->
721
- # Sets the scan pointer to the end of the string and clear matching data.
1517
+ # call-seq:
1518
+ # terminate -> self
1519
+ # Sets the scanner to end-of-string;
1520
+ # returns `self`:
1521
+ # * Sets both [positions](rdoc-ref:StringScanner@Positions) to end-of-stream.
1522
+ # * Clears [match values](rdoc-ref:StringScanner@Match+Values).
1523
+ # scanner = StringScanner.new(HIRAGANA_TEXT)
1524
+ # scanner.string # => "こんにちは"
1525
+ # scanner.scan_until(/に/)
1526
+ # put_situation(scanner)
1527
+ # # Situation:
1528
+ # # pos: 9
1529
+ # # charpos: 3
1530
+ # # rest: "ちは"
1531
+ # # rest_size: 6
1532
+ # match_values_cleared?(scanner) # => false
1533
+ #
1534
+ # scanner.terminate # => #<StringScanner fin>
1535
+ # put_situation(scanner)
1536
+ # # Situation:
1537
+ # # pos: 15
1538
+ # # charpos: 5
1539
+ # # rest: ""
1540
+ # # rest_size: 0
1541
+ # match_values_cleared?(scanner) # => true
722
1542
  #
723
1543
  def terminate: () -> void
724
1544
 
725
1545
  # <!--
726
1546
  # rdoc-file=ext/strscan/strscan.c
727
- # - unscan()
1547
+ # - unscan -> self
728
1548
  # -->
729
- # Sets the scan pointer to the previous position. Only one previous position is
730
- # remembered, and it changes with each scanning operation.
731
- #
732
- # s = StringScanner.new('test string')
733
- # s.scan(/\w+/) # => "test"
734
- # s.unscan
735
- # s.scan(/../) # => "te"
736
- # s.scan(/\d/) # => nil
737
- # s.unscan # ScanError: unscan failed: previous match record not exist
1549
+ # Sets the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) to
1550
+ # its value previous to the recent successful
1551
+ # [match](rdoc-ref:StringScanner@Matching) attempt:
1552
+ # scanner = StringScanner.new('foobarbaz')
1553
+ # scanner.scan(/foo/)
1554
+ # put_situation(scanner)
1555
+ # # Situation:
1556
+ # # pos: 3
1557
+ # # charpos: 3
1558
+ # # rest: "barbaz"
1559
+ # # rest_size: 6
1560
+ # scanner.unscan
1561
+ # # => #<StringScanner 0/9 @ "fooba...">
1562
+ # put_situation(scanner)
1563
+ # # Situation:
1564
+ # # pos: 0
1565
+ # # charpos: 0
1566
+ # # rest: "foobarbaz"
1567
+ # # rest_size: 9
1568
+ #
1569
+ # Raises an exception if match values are clear:
1570
+ # scanner.scan(/nope/) # => nil
1571
+ # match_values_cleared?(scanner) # => true
1572
+ # scanner.unscan # Raises StringScanner::Error.
738
1573
  #
739
1574
  def unscan: () -> void
740
1575
 
741
1576
  # <!--
742
1577
  # rdoc-file=ext/strscan/strscan.c
743
- # - scanner.values_at( i1, i2, ... iN ) -> an_array
1578
+ # - values_at(*specifiers) -> array_of_captures or nil
744
1579
  # -->
745
- # Returns the subgroups in the most recent match at the given indices. If
746
- # nothing was priorly matched, it returns nil.
747
- #
748
- # s = StringScanner.new("Fri Dec 12 1975 14:39")
749
- # s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 "
750
- # s.values_at 0, -1, 5, 2 # -> ["Fri Dec 12 ", "12", nil, "Dec"]
751
- # s.scan(/(\w+) (\w+) (\d+) /) # -> nil
752
- # s.values_at 0, -1, 5, 2 # -> nil
1580
+ # Returns an array of captured substrings, or `nil` of none.
1581
+ # For each `specifier`, the returned substring is `[specifier]`;
1582
+ # see #[].
1583
+ # scanner = StringScanner.new('Fri Dec 12 1975 14:39')
1584
+ # pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) /
1585
+ # scanner.match?(pattern)
1586
+ # scanner.values_at(*0..3) # => ["Fri Dec 12 ", "Fri", "Dec", "12"]
1587
+ # scanner.values_at(*%i[wday month day]) # => ["Fri", "Dec", "12"]
753
1588
  #
754
1589
  def values_at: (*Integer) -> Array[String]?
755
1590
 
@@ -757,24 +1592,32 @@ class StringScanner
757
1592
 
758
1593
  # <!--
759
1594
  # rdoc-file=ext/strscan/strscan.c
760
- # - StringScanner.new(string, fixed_anchor: false)
761
- # - StringScanner.new(string, dup = false)
1595
+ # - StringScanner.new(string, fixed_anchor: false) -> string_scanner
762
1596
  # -->
763
- # Creates a new StringScanner object to scan over the given `string`.
764
- #
765
- # If `fixed_anchor` is `true`, `\A` always matches the beginning of the string.
766
- # Otherwise, `\A` always matches the current position.
767
- #
768
- # `dup` argument is obsolete and not used now.
1597
+ # Returns a new `StringScanner` object whose [stored
1598
+ # string](rdoc-ref:StringScanner@Stored+String)
1599
+ # is the given `string`;
1600
+ # sets the [fixed-anchor
1601
+ # property](rdoc-ref:StringScanner@Fixed-Anchor+Property):
1602
+ # scanner = StringScanner.new('foobarbaz')
1603
+ # scanner.string # => "foobarbaz"
1604
+ # scanner.fixed_anchor? # => false
1605
+ # put_situation(scanner)
1606
+ # # Situation:
1607
+ # # pos: 0
1608
+ # # charpos: 0
1609
+ # # rest: "foobarbaz"
1610
+ # # rest_size: 9
769
1611
  #
770
1612
  def initialize: (String, ?bool dup, ?fixed_anchor: bool) -> untyped
771
1613
 
772
1614
  # <!--
773
1615
  # rdoc-file=ext/strscan/strscan.c
774
- # - dup
775
- # - clone
1616
+ # - dup -> shallow_copy
776
1617
  # -->
777
- # Duplicates a StringScanner object.
1618
+ # Returns a shallow copy of `self`;
1619
+ # the [stored string](rdoc-ref:StringScanner@Stored+String) in the copy is the
1620
+ # same string as in `self`.
778
1621
  #
779
1622
  def initialize_copy: (StringScanner) -> void
780
1623
  end