rbs 1.1.0 → 1.3.0
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/ruby.yml +5 -1
- data/.gitignore +2 -0
- data/CHANGELOG.md +81 -0
- data/README.md +1 -1
- data/Rakefile +11 -0
- data/Steepfile +1 -0
- data/core/array.rbs +2 -2
- data/core/basic_object.rbs +1 -1
- data/core/enumerable.rbs +1 -1
- data/core/hash.rbs +13 -5
- data/core/io.rbs +4 -4
- data/core/kernel.rbs +2 -2
- data/core/marshal.rbs +4 -3
- data/core/module.rbs +1 -1
- data/core/numeric.rbs +10 -0
- data/core/proc.rbs +1 -1
- data/core/random.rbs +4 -2
- data/core/range.rbs +2 -2
- data/core/struct.rbs +3 -2
- data/core/thread.rbs +1 -1
- data/docs/CONTRIBUTING.md +5 -3
- data/docs/rbs_by_example.md +328 -0
- data/docs/sigs.md +21 -2
- data/docs/stdlib.md +1 -1
- data/docs/syntax.md +11 -14
- data/lib/rbs.rb +1 -0
- data/lib/rbs/ast/annotation.rb +2 -2
- data/lib/rbs/ast/comment.rb +2 -2
- data/lib/rbs/ast/declarations.rb +37 -22
- data/lib/rbs/ast/members.rb +26 -26
- data/lib/rbs/cli.rb +3 -0
- data/lib/rbs/constant_table.rb +4 -1
- data/lib/rbs/definition.rb +1 -1
- data/lib/rbs/definition_builder.rb +16 -18
- data/lib/rbs/definition_builder/ancestor_builder.rb +10 -2
- data/lib/rbs/definition_builder/method_builder.rb +4 -2
- data/lib/rbs/errors.rb +36 -0
- data/lib/rbs/location.rb +106 -2
- data/lib/rbs/locator.rb +205 -0
- data/lib/rbs/method_type.rb +2 -2
- data/lib/rbs/parser.rb +1315 -962
- data/lib/rbs/parser.y +411 -75
- data/lib/rbs/prototype/rb.rb +7 -3
- data/lib/rbs/prototype/runtime.rb +118 -42
- data/lib/rbs/test/hook.rb +8 -2
- data/lib/rbs/type_name.rb +2 -3
- data/lib/rbs/type_name_resolver.rb +1 -1
- data/lib/rbs/types.rb +36 -34
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +4 -2
- data/rbs.gemspec +1 -1
- data/sig/ancestor_builder.rbs +2 -0
- data/sig/annotation.rbs +1 -1
- data/sig/cli.rbs +31 -21
- data/sig/comment.rbs +1 -1
- data/sig/declarations.rbs +106 -21
- data/sig/environment.rbs +2 -2
- data/sig/errors.rbs +15 -0
- data/sig/location.rbs +84 -3
- data/sig/locator.rbs +44 -0
- data/sig/members.rbs +76 -12
- data/sig/method_builder.rbs +1 -1
- data/sig/method_types.rbs +1 -1
- data/sig/namespace.rbs +1 -1
- data/sig/polyfill.rbs +4 -17
- data/sig/rbs.rbs +8 -4
- data/sig/typename.rbs +1 -1
- data/sig/types.rbs +67 -20
- data/sig/util.rbs +0 -4
- data/sig/writer.rbs +8 -2
- data/stdlib/dbm/0/dbm.rbs +43 -30
- data/stdlib/mutex_m/0/mutex_m.rbs +1 -1
- data/stdlib/net-http/0/net-http.rbs +1846 -0
- data/stdlib/optparse/0/optparse.rbs +1214 -0
- data/stdlib/resolv/0/resolv.rbs +1504 -0
- data/stdlib/rubygems/0/requirement.rbs +84 -2
- data/stdlib/rubygems/0/rubygems.rbs +2 -2
- data/stdlib/rubygems/0/version.rbs +2 -1
- data/stdlib/shellwords/0/shellwords.rbs +252 -0
- data/stdlib/socket/0/addrinfo.rbs +469 -0
- data/stdlib/socket/0/basic_socket.rbs +503 -0
- data/stdlib/socket/0/ip_socket.rbs +72 -0
- data/stdlib/socket/0/socket.rbs +2687 -0
- data/stdlib/socket/0/tcp_server.rbs +177 -0
- data/stdlib/socket/0/tcp_socket.rbs +35 -0
- data/stdlib/socket/0/udp_socket.rbs +111 -0
- data/stdlib/socket/0/unix_server.rbs +154 -0
- data/stdlib/socket/0/unix_socket.rbs +132 -0
- data/stdlib/timeout/0/timeout.rbs +5 -0
- data/steep/Gemfile.lock +19 -16
- metadata +18 -11
- data/bin/annotate-with-rdoc +0 -153
- data/bin/console +0 -14
- data/bin/query-rdoc +0 -103
- data/bin/rbs-prof +0 -9
- data/bin/run_in_md.rb +0 -49
- data/bin/setup +0 -8
- data/bin/sort +0 -89
- data/bin/steep +0 -4
- data/bin/test_runner.rb +0 -29
@@ -0,0 +1,328 @@
|
|
1
|
+
# RBS By Example
|
2
|
+
|
3
|
+
## Goal
|
4
|
+
|
5
|
+
The purpose of this doc is to teach you how to write RBS signatures by using the standard library's methods as a guide.
|
6
|
+
|
7
|
+
## Examples
|
8
|
+
|
9
|
+
### Zero argument methods
|
10
|
+
|
11
|
+
**Example:** `String#empty?`
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
# .rb
|
15
|
+
"".empty?
|
16
|
+
# => true
|
17
|
+
"hello".empty?
|
18
|
+
# => false
|
19
|
+
```
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
# .rbs
|
23
|
+
class String
|
24
|
+
def empty?: () -> bool
|
25
|
+
end
|
26
|
+
```
|
27
|
+
|
28
|
+
`String`'s `#empty` method takes no parameters, and returns a boolean value
|
29
|
+
|
30
|
+
### Single argument methods
|
31
|
+
|
32
|
+
**Example:** `String#include?`
|
33
|
+
|
34
|
+
```ruby
|
35
|
+
# .rb
|
36
|
+
"homeowner".include?("house")
|
37
|
+
# => false
|
38
|
+
"homeowner".include?("meow")
|
39
|
+
# => true
|
40
|
+
```
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
class String
|
44
|
+
def include?: (String) -> bool
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
`String`'s `include?` method takes one argument, a `String`, and returns a
|
49
|
+
boolean value
|
50
|
+
|
51
|
+
### Variable argument methods
|
52
|
+
|
53
|
+
**Example:** `String#end_with?`
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
# .rb
|
57
|
+
"hello?".end_with?("!")
|
58
|
+
# => false
|
59
|
+
"hello?".end_with?("?")
|
60
|
+
# => true
|
61
|
+
"hello?".end_with?("?", "!")
|
62
|
+
# => true
|
63
|
+
"hello?".end_with?(".", "!")
|
64
|
+
# => false
|
65
|
+
```
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
# .rbs
|
69
|
+
class String
|
70
|
+
def end_with?: (*String) -> bool
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
`String`'s `#end_with?` method takes any number of `String` arguments, and
|
75
|
+
returns a boolean value.
|
76
|
+
|
77
|
+
### Optional positional arguments
|
78
|
+
|
79
|
+
**Example:** `String#ljust`
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
# .rb
|
83
|
+
"hello".ljust(4)
|
84
|
+
#=> "hello"
|
85
|
+
"hello".ljust(20)
|
86
|
+
#=> "hello "
|
87
|
+
"hello".ljust(20, '1234')
|
88
|
+
#=> "hello123412341234123"
|
89
|
+
```
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
# .rbs
|
93
|
+
class String
|
94
|
+
def ljust: (Integer, ?String) -> String
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
`String`'s `ljust` takes one `Integer` argument, and an optional `String` argument, indicated by the the `?` prefix marker. It returns a `String`.
|
99
|
+
|
100
|
+
### Multiple signatures for a single method
|
101
|
+
|
102
|
+
**Example:** `Array#*`
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
# .rb
|
106
|
+
[1, 2, 3] * ","
|
107
|
+
# => "1,2,3"
|
108
|
+
[1, 2, 3] * 2
|
109
|
+
# => [1, 2, 3, 1, 2, 3]
|
110
|
+
```
|
111
|
+
|
112
|
+
*Note:* Some of the signatures after this point include type variables (e.g. `Elem`, `T`).
|
113
|
+
For now, it's safe to ignore them, but they're included for completeness.
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
# .rbs
|
117
|
+
class Array[Elem]
|
118
|
+
def *: (String) -> String
|
119
|
+
| (Integer) -> Array[Elem]
|
120
|
+
end
|
121
|
+
```
|
122
|
+
|
123
|
+
`Array`'s `*` method, when given a `String` returns a `String`. When given an
|
124
|
+
`Integer`, it returns an `Array` of the same contained type `Elem` (in our example case, `Elem` corresponds to `Integer`).
|
125
|
+
|
126
|
+
### Union types
|
127
|
+
|
128
|
+
**Example:** `String#<<`
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
# .rb
|
132
|
+
a = "hello "
|
133
|
+
a << "world"
|
134
|
+
#=> "hello world"
|
135
|
+
a << 33
|
136
|
+
#=> "hello world!"
|
137
|
+
```
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
# .rbs
|
141
|
+
class String
|
142
|
+
def <<: (String | Integer) -> String
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
146
|
+
`String`'s `<<` operator takes either a `String` or an `Integer`, and returns a `String`.
|
147
|
+
|
148
|
+
### Nilable types
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
# .rb
|
152
|
+
[1, 2, 3].first
|
153
|
+
# => 1
|
154
|
+
[].first
|
155
|
+
# => nil
|
156
|
+
[1, 2, 3].first(2)
|
157
|
+
# => [1, 2]
|
158
|
+
[].first(2)
|
159
|
+
# => []
|
160
|
+
```
|
161
|
+
|
162
|
+
```ruby
|
163
|
+
# .rbs
|
164
|
+
class Enumerable[Elem]
|
165
|
+
def first: () -> Elem?
|
166
|
+
| (Integer) -> Array[Elem]
|
167
|
+
end
|
168
|
+
```
|
169
|
+
|
170
|
+
`Enumerable`'s `#first` method has two different signatures.
|
171
|
+
|
172
|
+
When called with no arguments, the return value will either be an instance of
|
173
|
+
whatever type is contained in the enumerable, or `nil`. We represent that with
|
174
|
+
the type variable `Elem`, and the `?` suffix nilable marker.
|
175
|
+
|
176
|
+
When called with an `Integer` positional argument, the return value will be an
|
177
|
+
`Array` of whatever type is contained.
|
178
|
+
|
179
|
+
The `?` syntax is a convenient shorthand for a union with nil. An equivalent union type woould be `(Elem | nil)`.
|
180
|
+
|
181
|
+
### Keyword Arguments
|
182
|
+
|
183
|
+
**Example**: `String#lines`
|
184
|
+
|
185
|
+
```ruby
|
186
|
+
# .rb
|
187
|
+
"hello\nworld\n".lines
|
188
|
+
# => ["hello\n", "world\n"]
|
189
|
+
"hello world".lines(' ')
|
190
|
+
# => ["hello ", " ", "world"]
|
191
|
+
"hello\nworld\n".lines(chomp: true)
|
192
|
+
# => ["hello", "world"]
|
193
|
+
```
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
# .rbs
|
197
|
+
class String
|
198
|
+
def lines: (?String, ?chomp: bool) -> Array[String]
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
`String`'s `#lines` method take two arguments: one optional String argument, and another optional boolean keyword argument. It returns an `Array` of `String`s.
|
203
|
+
|
204
|
+
Keyword arguments are declared similar to in ruby, with the keyword immediately followed by a colon. Keyword arguments that are optional are indicated as optional using the same `?` prefix as positional arguments.
|
205
|
+
|
206
|
+
|
207
|
+
### Class methods
|
208
|
+
|
209
|
+
**Example**: `Time.now`
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
# .rb
|
213
|
+
Time.now
|
214
|
+
# => 2009-06-24 12:39:54 +0900
|
215
|
+
```
|
216
|
+
|
217
|
+
```ruby
|
218
|
+
class Time
|
219
|
+
def self.now: () -> Time
|
220
|
+
end
|
221
|
+
```
|
222
|
+
|
223
|
+
`Time`'s class method `now` takes no arguments, and returns an instance of the
|
224
|
+
`Time` class.
|
225
|
+
|
226
|
+
### Block Arguments
|
227
|
+
|
228
|
+
**Example**: `Array#filter`
|
229
|
+
|
230
|
+
```ruby
|
231
|
+
# .rb
|
232
|
+
[1,2,3,4,5].select {|num| num.even? }
|
233
|
+
# => [2, 4]
|
234
|
+
%w[ a b c d e f ].select {|v| v =~ /[aeiou]/ }
|
235
|
+
# => ["a", "e"]
|
236
|
+
[1,2,3,4,5].filter
|
237
|
+
```
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
# .rbs
|
241
|
+
class Array[Elem]
|
242
|
+
def filter: () { (Elem) -> boolish } -> ::Array[Elem]
|
243
|
+
| () -> ::Enumerator[Elem, ::Array[Elem]]
|
244
|
+
end
|
245
|
+
```
|
246
|
+
|
247
|
+
`Array`'s `#filter` method, when called with no arguments returns an Enumerator.
|
248
|
+
|
249
|
+
When called with a block, the method returns an `Array` of whatever type the original contained. The block will take one argument, of the type of the contained value, and the block will return a truthy or falsy value.
|
250
|
+
|
251
|
+
`boolish` is a special keyword for any type that will be treated as if it were a `bool`.
|
252
|
+
|
253
|
+
### Type Variables
|
254
|
+
|
255
|
+
**Example**: `Hash`, `Hash#keys`
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
|
259
|
+
h.keys
|
260
|
+
# => ["a", "b", "c", "d"]
|
261
|
+
```
|
262
|
+
|
263
|
+
```ruby
|
264
|
+
# .rbs
|
265
|
+
class Hash[K, V]
|
266
|
+
def keys: () -> Array[K]
|
267
|
+
end
|
268
|
+
```
|
269
|
+
|
270
|
+
Generic types in RBS are parameterized at declaration time. These type variables are then available throughout all the methods contained in the `class` block.
|
271
|
+
|
272
|
+
`Hash`'s `#keys` method takes no arguments, and returns an `Array` of the first type parameter. In the above example, `a` is of concrete type `Hash[String, Integer]`, so `#keys` returns an `Array` for `String`.
|
273
|
+
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
# .rb
|
277
|
+
a = [ "a", "b", "c", "d" ]
|
278
|
+
a.collect {|x| x + "!"}
|
279
|
+
# => ["a!", "b!", "c!", "d!"]
|
280
|
+
a.collect.with_index {|x, i| x * i}
|
281
|
+
# => ["", "b", "cc", "ddd"]
|
282
|
+
```
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
# .rbs
|
286
|
+
class Array[Elem]
|
287
|
+
def collect: [U] () { (Elem) -> U } -> Array[U]
|
288
|
+
| () -> Enumerator[Elem, Array[untyped]]
|
289
|
+
end
|
290
|
+
```
|
291
|
+
|
292
|
+
Type variables can also be introduced in methods. Here, in `Array`'s `#collect` method, we introduce a type variable `U`. The block passed to `#collect` will receive a parameter of type `Elem`, and return a value of type `U`. Then `#collect` will return an `Array` of type `U`.
|
293
|
+
|
294
|
+
In this example, the method receives its signature from the inferred return type of the passed block. When then block is absent, as in when the method returns an `Enumerator`, we can't infer the type, and so the return value of the enumerator can only be described as `Array[untyped]`.
|
295
|
+
|
296
|
+
### Tuples
|
297
|
+
|
298
|
+
**Examples**: `Enumerable#partition`, `Enumerable#to_h`
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
(1..6).partition { |v| v.even? }
|
302
|
+
# => [[2, 4, 6], [1, 3, 5]]
|
303
|
+
```
|
304
|
+
|
305
|
+
```ruby
|
306
|
+
class Enumerable[Elem]
|
307
|
+
def partition: () { (Elem) -> boolish } -> [Array[Elem], Array[Elem]]
|
308
|
+
| () -> ::Enumerator[Elem, [Array[Elem], Array[Elem] ]]
|
309
|
+
end
|
310
|
+
```
|
311
|
+
|
312
|
+
`Enumerable`'s `partition` method, when given a block, returns a 2-item tuple of `Array`s containing the original type of the `Enumerable`.
|
313
|
+
|
314
|
+
Tuples can be of any size, and they can have mixed types.
|
315
|
+
|
316
|
+
```ruby
|
317
|
+
(1..5).to_h {|x| [x, x ** 2]}
|
318
|
+
# => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
|
319
|
+
```
|
320
|
+
|
321
|
+
```ruby
|
322
|
+
class Enumerable[Elem]
|
323
|
+
def to_h: () -> ::Hash[untyped, untyped]
|
324
|
+
| [T, U] () { (Elem) -> [T, U] } -> ::Hash[T, U]
|
325
|
+
end
|
326
|
+
```
|
327
|
+
|
328
|
+
`Enumerable`'s `to_h` method, when given a block that returns a 2-item tuple, returns a `Hash` with keys the type of the first position in the tuple, and values the type of the second position in the tuple.
|
data/docs/sigs.md
CHANGED
@@ -26,7 +26,7 @@ The test installs instrumentations to spy the method calls and check if argument
|
|
26
26
|
If errors are reported by the test, you will fix the signature.
|
27
27
|
You will be sure that you ship a correct signature finally.
|
28
28
|
|
29
|
-
The instrumentations are
|
29
|
+
The instrumentations are implemented using `Module#prepend`.
|
30
30
|
It defines a module with same name of methods, which asserts the type of arguments/return values and calls `super`.
|
31
31
|
|
32
32
|
## Type errors
|
@@ -70,6 +70,23 @@ ERROR -- : [Kaigi::Conference#speakers] UnexpectedBlockError: unexpected block i
|
|
70
70
|
The error means there is a type error on overloaded methods.
|
71
71
|
The `rbs` test framework tries to the best error message for overloaded methods too, but it reports the `UnresolvedOverloadingError` when it fails.
|
72
72
|
|
73
|
+
### DuplicatedMethodDefinitionError
|
74
|
+
|
75
|
+
The error is reported when a method is defined multiple times, as RBS does not allow duplicate method definitions. When you need to overload a method, use the `...` syntax:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
# First definition
|
79
|
+
class C
|
80
|
+
def foo: () -> untyped
|
81
|
+
end
|
82
|
+
|
83
|
+
# Second definition, use `...` syntax to tell RBS that we're overloading the method
|
84
|
+
class C
|
85
|
+
def foo: () -> untyped
|
86
|
+
| ...
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
73
90
|
## Setting up the test
|
74
91
|
|
75
92
|
The design of the signature testing aims to be non-intrusive. The setup is done in two steps:
|
@@ -114,9 +131,11 @@ You may need to specify `-r` or `-I` to load signatures.
|
|
114
131
|
The default is `-I sig`.
|
115
132
|
|
116
133
|
```
|
117
|
-
RBS_TEST_OPT='-r
|
134
|
+
RBS_TEST_OPT='-r pathname -I sig'
|
118
135
|
```
|
119
136
|
|
137
|
+
Replacing `pathname` with the `stdlib` you want to include. For example, if you need to load `Set` and `BigDecimal` in `stdlib`, you would need to have `RBS_TEST_OPT='-r set -r bigdecimal -I sig'`
|
138
|
+
|
120
139
|
`RBS_TEST_LOGLEVEL` can be used to configure log level. Defaults to `info`.
|
121
140
|
|
122
141
|
`RBS_TEST_RAISE` may help to debug the type signatures.
|
data/docs/stdlib.md
CHANGED
@@ -57,7 +57,7 @@ But it will help you to have an overview of the signatures you are trying to wri
|
|
57
57
|
|
58
58
|
### What to do with existing RBS files
|
59
59
|
|
60
|
-
Generating prototypes will
|
60
|
+
Generating prototypes will overwrite existing RBS files, which might be undesirable.
|
61
61
|
You can try to find missing parts, or you can start from the scratch.
|
62
62
|
|
63
63
|
One non-trivial but absolutely better solution is to make a tool:
|
data/docs/syntax.md
CHANGED
@@ -11,8 +11,8 @@ _type_ ::= _class-name_ _type-arguments_ (Class instance type)
|
|
11
11
|
| _type_ `|` _type_ (Union type)
|
12
12
|
| _type_ `&` _type_ (Intersection type)
|
13
13
|
| _type_ `?` (Optional type)
|
14
|
-
| `{` _record-name_ `:` _type_ `,`
|
15
|
-
| `[]` | `[` _type_ `,`
|
14
|
+
| `{` _record-name_ `:` _type_ `,` etc. `}` (Record type)
|
15
|
+
| `[]` | `[` _type_ `,` etc. `]` (Tuples)
|
16
16
|
| _type-variable_ (Type variables)
|
17
17
|
| `^(` _parameters_ `) ->` _type_ (Proc type)
|
18
18
|
| `self`
|
@@ -36,7 +36,7 @@ _namespace_ ::= (Empty namespace)
|
|
36
36
|
| _namespace_ /[A-Z]\w*/ `::` (Namespace)
|
37
37
|
|
38
38
|
_type-arguments_ ::= (No application)
|
39
|
-
| `[` _type_ `,`
|
39
|
+
| `[` _type_ `,` etc. `]` (Type application)
|
40
40
|
|
41
41
|
_literal_ ::= _string-literal_
|
42
42
|
| _symbol-literal_
|
@@ -203,7 +203,6 @@ We can see an example at the definition of `Enumerable#find`:
|
|
203
203
|
```
|
204
204
|
module Enumerable[Elem, Return]
|
205
205
|
def find: () { (Elem) -> boolish } -> Elem?
|
206
|
-
...
|
207
206
|
end
|
208
207
|
```
|
209
208
|
|
@@ -233,11 +232,11 @@ _parameters_ ::= _required-positionals_ _optional-positionals_ _rest-positional_
|
|
233
232
|
|
234
233
|
_parameter_ ::= _type_ _var-name_ # Parameter with var name
|
235
234
|
| _type_ # Parameter without var name
|
236
|
-
_required-positionals_ ::= _parameter_ `,`
|
237
|
-
_optional-positionals_ ::= `?` _parameter_ `,`
|
235
|
+
_required-positionals_ ::= _parameter_ `,` etc.
|
236
|
+
_optional-positionals_ ::= `?` _parameter_ `,` etc.
|
238
237
|
_rest-positional_ ::= # Empty
|
239
238
|
| `*` _parameter_
|
240
|
-
_trailing-positionals_ ::= _parameter_ `,`
|
239
|
+
_trailing-positionals_ ::= _parameter_ `,` etc.
|
241
240
|
_keywords_ ::= # Empty
|
242
241
|
| `**` _parameter_ # Rest keyword
|
243
242
|
| _keyword_ `:` _parameter_ `,` _keywords_ # Required keyword
|
@@ -292,9 +291,10 @@ _method-member_ ::= `def` _method-name_ `:` _method-types_ # Instance
|
|
292
291
|
_method-types_ ::= # Empty
|
293
292
|
| `super` # `super` overloading
|
294
293
|
| _type-parameters_ _method-type_ `|` _method-types_ # Overloading types
|
294
|
+
| `...` # Overloading for duplicate definitions
|
295
295
|
|
296
296
|
_type-parameters_ ::= # Empty
|
297
|
-
| `[` _type-variable_ `,`
|
297
|
+
| `[` _type-variable_ `,` etc. `]`
|
298
298
|
|
299
299
|
_attribute-member_ ::= _attribute-type_ _method-name_ `:` _type_ # Attribute
|
300
300
|
| _attribute-type_ _method-name_ `(` _ivar-name_ `) :` _type_ # Attribute with variable name specification
|
@@ -352,9 +352,6 @@ def +: (Float | Integer) -> (Float | Integer)
|
|
352
352
|
| (Numeric) -> Numeric
|
353
353
|
```
|
354
354
|
|
355
|
-
Method types can end with `super` which means the methods from existing definitions.
|
356
|
-
This is useful to define an _extension_, which adds a new variation to the existing method preserving the original behavior.
|
357
|
-
|
358
355
|
### Attribute definition
|
359
356
|
|
360
357
|
Attribute definitions help to define methods and instance variables based on the convention of `attr_reader`, `attr_writer` and `attr_accessor` methods in Ruby.
|
@@ -450,7 +447,7 @@ _const-name_ ::= _namespace_ /[A-Z]\w*/
|
|
450
447
|
_global-name_ ::= /$[a-zA-Z]\w+/ | ...
|
451
448
|
|
452
449
|
_module-type-parameters_ ::= # Empty
|
453
|
-
| `[` _module-type-parameter_ `,`
|
450
|
+
| `[` _module-type-parameter_ `,` etc. `]`
|
454
451
|
|
455
452
|
_module-type-parameter_ ::= _check_ _variance_ _type-variable_
|
456
453
|
_variance_ ::= `out` | `in`
|
@@ -475,7 +472,7 @@ For example, an `Array` of `String` can almost be considered to be an `Array` of
|
|
475
472
|
|
476
473
|
```
|
477
474
|
class Array[out T]
|
478
|
-
#
|
475
|
+
# etc.
|
479
476
|
end
|
480
477
|
```
|
481
478
|
|
@@ -486,7 +483,7 @@ In those cases, one must use the `unchecked` keyword:
|
|
486
483
|
|
487
484
|
```
|
488
485
|
class Array[unchecked out T]
|
489
|
-
#
|
486
|
+
# etc.
|
490
487
|
end
|
491
488
|
```
|
492
489
|
|