rbs 3.1.3 → 3.2.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 +0 -6
- data/CHANGELOG.md +82 -0
- data/Gemfile +0 -6
- data/Gemfile.lock +12 -21
- data/README.md +1 -1
- data/Rakefile +45 -1
- data/Steepfile +3 -3
- data/core/array.rbs +0 -8
- data/core/binding.rbs +7 -69
- data/core/builtin.rbs +33 -8
- data/core/constants.rbs +13 -5
- data/core/dir.rbs +25 -25
- data/core/errno.rbs +474 -590
- data/core/exception.rbs +1 -1
- data/core/global_variables.rbs +27 -27
- data/core/io.rbs +163 -172
- data/core/kernel.rbs +58 -38
- data/core/module.rbs +34 -32
- data/core/object.rbs +3 -7
- data/core/string_io.rbs +9 -0
- data/core/thread.rbs +25 -1
- data/core/time.rbs +3 -3
- data/core/warning.rbs +3 -1
- data/docs/CONTRIBUTING.md +1 -1
- data/docs/rbs_by_example.md +16 -35
- data/docs/repo.md +1 -1
- data/docs/sigs.md +7 -7
- data/docs/stdlib.md +2 -3
- data/docs/syntax.md +40 -40
- data/lib/rbs/cli.rb +15 -4
- data/lib/rbs/collection/config/lockfile_generator.rb +6 -2
- data/lib/rbs/collection/installer.rb +5 -2
- data/lib/rbs/collection/sources/stdlib.rb +5 -1
- data/lib/rbs/errors.rb +8 -1
- data/lib/rbs/file_finder.rb +1 -1
- data/lib/rbs/prototype/rb.rb +64 -6
- data/lib/rbs/prototype/rbi.rb +2 -6
- data/lib/rbs/prototype/runtime.rb +29 -8
- data/lib/rbs/subtractor.rb +17 -0
- data/lib/rbs/type_name.rb +4 -4
- data/lib/rbs/version.rb +1 -1
- data/rbs.gemspec +1 -1
- data/schema/decls.json +1 -1
- data/sig/errors.rbs +54 -0
- data/sig/parser.rbs +2 -2
- data/sig/prototype/rb.rbs +9 -1
- data/sig/subtractor.rbs +4 -0
- data/stdlib/logger/0/logger.rbs +1 -1
- data/stdlib/observable/0/observable.rbs +219 -0
- data/stdlib/uri/0/common.rbs +24 -0
- data/stdlib/zlib/0/buf_error.rbs +79 -0
- data/stdlib/zlib/0/data_error.rbs +79 -0
- data/stdlib/zlib/0/deflate.rbs +276 -0
- data/stdlib/zlib/0/error.rbs +89 -0
- data/stdlib/zlib/0/gzip_file/crc_error.rbs +115 -0
- data/stdlib/zlib/0/gzip_file/error.rbs +128 -0
- data/stdlib/zlib/0/gzip_file/length_error.rbs +115 -0
- data/stdlib/zlib/0/gzip_file/no_footer.rbs +114 -0
- data/stdlib/zlib/0/gzip_file.rbs +228 -0
- data/stdlib/zlib/0/gzip_reader.rbs +362 -0
- data/stdlib/zlib/0/gzip_writer.rbs +237 -0
- data/stdlib/zlib/0/inflate.rbs +249 -0
- data/stdlib/zlib/0/mem_error.rbs +79 -0
- data/stdlib/zlib/0/need_dict.rbs +82 -0
- data/stdlib/zlib/0/stream_end.rbs +80 -0
- data/stdlib/zlib/0/stream_error.rbs +80 -0
- data/stdlib/zlib/0/version_error.rbs +80 -0
- data/stdlib/zlib/0/zstream.rbs +270 -0
- metadata +22 -6
- data/stdlib/prime/0/integer-extension.rbs +0 -41
- data/stdlib/prime/0/manifest.yaml +0 -2
- data/stdlib/prime/0/prime.rbs +0 -372
data/docs/rbs_by_example.md
CHANGED
@@ -6,20 +6,20 @@ The purpose of this doc is to teach you how to write RBS signatures by using the
|
|
6
6
|
|
7
7
|
## Examples
|
8
8
|
|
9
|
+
In each example, the first snippet is for *Ruby* and the second one is for *RBS*.
|
10
|
+
|
9
11
|
### Zero argument methods
|
10
12
|
|
11
13
|
**Example:** `String#empty?`
|
12
14
|
|
13
15
|
```ruby
|
14
|
-
# .rb
|
15
16
|
"".empty?
|
16
17
|
# => true
|
17
18
|
"hello".empty?
|
18
19
|
# => false
|
19
20
|
```
|
20
21
|
|
21
|
-
```
|
22
|
-
# .rbs
|
22
|
+
```rbs
|
23
23
|
class String
|
24
24
|
def empty?: () -> bool
|
25
25
|
end
|
@@ -32,14 +32,13 @@ end
|
|
32
32
|
**Example:** `String#include?`
|
33
33
|
|
34
34
|
```ruby
|
35
|
-
# .rb
|
36
35
|
"homeowner".include?("house")
|
37
36
|
# => false
|
38
37
|
"homeowner".include?("meow")
|
39
38
|
# => true
|
40
39
|
```
|
41
40
|
|
42
|
-
```
|
41
|
+
```rbs
|
43
42
|
class String
|
44
43
|
def include?: (String) -> bool
|
45
44
|
end
|
@@ -53,7 +52,6 @@ boolean value
|
|
53
52
|
**Example:** `String#end_with?`
|
54
53
|
|
55
54
|
```ruby
|
56
|
-
# .rb
|
57
55
|
"hello?".end_with?("!")
|
58
56
|
# => false
|
59
57
|
"hello?".end_with?("?")
|
@@ -64,8 +62,7 @@ boolean value
|
|
64
62
|
# => false
|
65
63
|
```
|
66
64
|
|
67
|
-
```
|
68
|
-
# .rbs
|
65
|
+
```rbs
|
69
66
|
class String
|
70
67
|
def end_with?: (*String) -> bool
|
71
68
|
end
|
@@ -79,7 +76,6 @@ returns a boolean value.
|
|
79
76
|
**Example:** `String#ljust`
|
80
77
|
|
81
78
|
```ruby
|
82
|
-
# .rb
|
83
79
|
"hello".ljust(4)
|
84
80
|
#=> "hello"
|
85
81
|
"hello".ljust(20)
|
@@ -88,8 +84,7 @@ returns a boolean value.
|
|
88
84
|
#=> "hello123412341234123"
|
89
85
|
```
|
90
86
|
|
91
|
-
```
|
92
|
-
# .rbs
|
87
|
+
```rbs
|
93
88
|
class String
|
94
89
|
def ljust: (Integer, ?String) -> String
|
95
90
|
end
|
@@ -102,7 +97,6 @@ end
|
|
102
97
|
**Example:** `Array#*`
|
103
98
|
|
104
99
|
```ruby
|
105
|
-
# .rb
|
106
100
|
[1, 2, 3] * ","
|
107
101
|
# => "1,2,3"
|
108
102
|
[1, 2, 3] * 2
|
@@ -112,8 +106,7 @@ end
|
|
112
106
|
*Note:* Some of the signatures after this point include type variables (e.g. `Elem`, `T`).
|
113
107
|
For now, it's safe to ignore them, but they're included for completeness.
|
114
108
|
|
115
|
-
```
|
116
|
-
# .rbs
|
109
|
+
```rbs
|
117
110
|
class Array[Elem]
|
118
111
|
def *: (String) -> String
|
119
112
|
| (Integer) -> Array[Elem]
|
@@ -128,7 +121,6 @@ end
|
|
128
121
|
**Example:** `String#<<`
|
129
122
|
|
130
123
|
```ruby
|
131
|
-
# .rb
|
132
124
|
a = "hello "
|
133
125
|
a << "world"
|
134
126
|
#=> "hello world"
|
@@ -136,8 +128,7 @@ a << 33
|
|
136
128
|
#=> "hello world!"
|
137
129
|
```
|
138
130
|
|
139
|
-
```
|
140
|
-
# .rbs
|
131
|
+
```rbs
|
141
132
|
class String
|
142
133
|
def <<: (String | Integer) -> String
|
143
134
|
end
|
@@ -148,7 +139,6 @@ end
|
|
148
139
|
### Nilable types
|
149
140
|
|
150
141
|
```ruby
|
151
|
-
# .rb
|
152
142
|
[1, 2, 3].first
|
153
143
|
# => 1
|
154
144
|
[].first
|
@@ -159,8 +149,7 @@ end
|
|
159
149
|
# => []
|
160
150
|
```
|
161
151
|
|
162
|
-
```
|
163
|
-
# .rbs
|
152
|
+
```rbs
|
164
153
|
class Enumerable[Elem]
|
165
154
|
def first: () -> Elem?
|
166
155
|
| (Integer) -> Array[Elem]
|
@@ -183,7 +172,6 @@ The `?` syntax is a convenient shorthand for a union with nil. An equivalent uni
|
|
183
172
|
**Example**: `String#lines`
|
184
173
|
|
185
174
|
```ruby
|
186
|
-
# .rb
|
187
175
|
"hello\nworld\n".lines
|
188
176
|
# => ["hello\n", "world\n"]
|
189
177
|
"hello world".lines(' ')
|
@@ -192,8 +180,7 @@ The `?` syntax is a convenient shorthand for a union with nil. An equivalent uni
|
|
192
180
|
# => ["hello", "world"]
|
193
181
|
```
|
194
182
|
|
195
|
-
```
|
196
|
-
# .rbs
|
183
|
+
```rbs
|
197
184
|
class String
|
198
185
|
def lines: (?String, ?chomp: bool) -> Array[String]
|
199
186
|
end
|
@@ -209,12 +196,11 @@ Keyword arguments are declared similar to in ruby, with the keyword immediately
|
|
209
196
|
**Example**: `Time.now`
|
210
197
|
|
211
198
|
```ruby
|
212
|
-
# .rb
|
213
199
|
Time.now
|
214
200
|
# => 2009-06-24 12:39:54 +0900
|
215
201
|
```
|
216
202
|
|
217
|
-
```
|
203
|
+
```rbs
|
218
204
|
class Time
|
219
205
|
def self.now: () -> Time
|
220
206
|
end
|
@@ -228,7 +214,6 @@ end
|
|
228
214
|
**Example**: `Array#filter`
|
229
215
|
|
230
216
|
```ruby
|
231
|
-
# .rb
|
232
217
|
[1,2,3,4,5].filter {|num| num.even? }
|
233
218
|
# => [2, 4]
|
234
219
|
%w[ a b c d e f ].filter {|v| v =~ /[aeiou]/ }
|
@@ -236,8 +221,7 @@ end
|
|
236
221
|
[1,2,3,4,5].filter
|
237
222
|
```
|
238
223
|
|
239
|
-
```
|
240
|
-
# .rbs
|
224
|
+
```rbs
|
241
225
|
class Array[Elem]
|
242
226
|
def filter: () { (Elem) -> boolish } -> ::Array[Elem]
|
243
227
|
| () -> ::Enumerator[Elem, ::Array[Elem]]
|
@@ -260,8 +244,7 @@ h.keys
|
|
260
244
|
# => ["a", "b", "c", "d"]
|
261
245
|
```
|
262
246
|
|
263
|
-
```
|
264
|
-
# .rbs
|
247
|
+
```rbs
|
265
248
|
class Hash[K, V]
|
266
249
|
def keys: () -> Array[K]
|
267
250
|
end
|
@@ -273,7 +256,6 @@ Generic types in RBS are parameterized at declaration time. These type variables
|
|
273
256
|
|
274
257
|
|
275
258
|
```ruby
|
276
|
-
# .rb
|
277
259
|
a = [ "a", "b", "c", "d" ]
|
278
260
|
a.collect {|x| x + "!"}
|
279
261
|
# => ["a!", "b!", "c!", "d!"]
|
@@ -281,8 +263,7 @@ a.collect.with_index {|x, i| x * i}
|
|
281
263
|
# => ["", "b", "cc", "ddd"]
|
282
264
|
```
|
283
265
|
|
284
|
-
```
|
285
|
-
# .rbs
|
266
|
+
```rbs
|
286
267
|
class Array[Elem]
|
287
268
|
def collect: [U] () { (Elem) -> U } -> Array[U]
|
288
269
|
| () -> Enumerator[Elem, Array[untyped]]
|
@@ -302,7 +283,7 @@ In this example, the method receives its signature from the inferred return type
|
|
302
283
|
# => [[2, 4, 6], [1, 3, 5]]
|
303
284
|
```
|
304
285
|
|
305
|
-
```
|
286
|
+
```rbs
|
306
287
|
class Enumerable[Elem]
|
307
288
|
def partition: () { (Elem) -> boolish } -> [Array[Elem], Array[Elem]]
|
308
289
|
| () -> ::Enumerator[Elem, [Array[Elem], Array[Elem] ]]
|
@@ -318,7 +299,7 @@ Tuples can be of any size, and they can have mixed types.
|
|
318
299
|
# => {1=>1, 2=>4, 3=>9, 4=>16, 5=>25}
|
319
300
|
```
|
320
301
|
|
321
|
-
```
|
302
|
+
```rbs
|
322
303
|
class Enumerable[Elem]
|
323
304
|
def to_h: () -> ::Hash[untyped, untyped]
|
324
305
|
| [T, U] () { (Elem) -> [T, U] } -> ::Hash[T, U]
|
data/docs/repo.md
CHANGED
data/docs/sigs.md
CHANGED
@@ -18,7 +18,7 @@ See [syntax guide](syntax.md).
|
|
18
18
|
When you finish writing signature, you may want to test the signature.
|
19
19
|
rbs provides a feature to test your signature.
|
20
20
|
|
21
|
-
```
|
21
|
+
```console
|
22
22
|
$ RBS_TEST_TARGET='Foo::*' bundle exec ruby -r rbs/test/setup test/foo_test.rb
|
23
23
|
```
|
24
24
|
|
@@ -74,7 +74,7 @@ The `rbs` test framework tries to the best error message for overloaded methods
|
|
74
74
|
|
75
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
76
|
|
77
|
-
```
|
77
|
+
```rbs
|
78
78
|
# First definition
|
79
79
|
class C
|
80
80
|
def foo: () -> untyped
|
@@ -99,14 +99,14 @@ The design of the signature testing aims to be non-intrusive. The setup is done
|
|
99
99
|
You need to require `rbs/test/setup` for signature testing.
|
100
100
|
You can do it using `-r` option through command line argument or the `RUBYOPT` environment variable.
|
101
101
|
|
102
|
-
```
|
102
|
+
```console
|
103
103
|
$ ruby -r rbs/test/setup run_tests.rb
|
104
104
|
$ RUBYOPT='-rrbs/test/setup' rake test
|
105
105
|
```
|
106
106
|
|
107
107
|
When you are using Bundler, you may need to require `bundler/setup` explicitly.
|
108
108
|
|
109
|
-
```
|
109
|
+
```console
|
110
110
|
$ RUBYOPT='-rbundler/setup -rrbs/test/setup' bundle exec rake test
|
111
111
|
```
|
112
112
|
|
@@ -130,7 +130,7 @@ You need to specify `RBS_TEST_TARGET` to run the test, and you can customize the
|
|
130
130
|
You may need to specify `-r` or `-I` to load signatures.
|
131
131
|
The default is `-I sig`.
|
132
132
|
|
133
|
-
```
|
133
|
+
```shell
|
134
134
|
RBS_TEST_OPT='-r pathname -I sig'
|
135
135
|
```
|
136
136
|
|
@@ -144,7 +144,7 @@ You can see the backtrace how the type error is caused and debug your program or
|
|
144
144
|
|
145
145
|
So, a typical command line to start the test would look like the following:
|
146
146
|
|
147
|
-
```
|
147
|
+
```console
|
148
148
|
$ RBS_TEST_LOGLEVEL=error \
|
149
149
|
RBS_TEST_TARGET='Kaigi::*' \
|
150
150
|
RBS_TEST_SKIP='Kaigi::MonkeyPatch' \
|
@@ -160,7 +160,7 @@ $ RBS_TEST_LOGLEVEL=error \
|
|
160
160
|
|
161
161
|
You can skip installing the instrumentation per-method basis using `rbs:test:skip` annotation.
|
162
162
|
|
163
|
-
```
|
163
|
+
```rbs
|
164
164
|
class String
|
165
165
|
%a{rbs:test:skip} def =~: (Regexp) -> Integer?
|
166
166
|
end
|
data/docs/stdlib.md
CHANGED
@@ -10,7 +10,7 @@ We support writing tests for core/stdlib signatures.
|
|
10
10
|
|
11
11
|
First, execute `generate:stdlib_test` rake task with a class name that you want to test.
|
12
12
|
|
13
|
-
```
|
13
|
+
```console
|
14
14
|
$ bundle exec rake 'generate:stdlib_test[String]'
|
15
15
|
Created: test/stdlib/String_test.rb
|
16
16
|
```
|
@@ -47,7 +47,6 @@ end
|
|
47
47
|
class StringTest < Test::Unit::TestCase
|
48
48
|
include TypeAssertions
|
49
49
|
|
50
|
-
# library "pathname", "set", "securerandom" # Declare library signatures to load
|
51
50
|
testing "::String"
|
52
51
|
|
53
52
|
def test_gsub
|
@@ -83,7 +82,7 @@ If the execution of the program escape from the class definition, the instrument
|
|
83
82
|
|
84
83
|
You can run the test with:
|
85
84
|
|
86
|
-
```
|
85
|
+
```console
|
87
86
|
$ bundle exec rake stdlib_test # Run all tests
|
88
87
|
$ bundle exec ruby test/stdlib/String_test.rb # Run specific tests
|
89
88
|
```
|
data/docs/syntax.md
CHANGED
@@ -51,7 +51,7 @@ _proc_ ::= _parameters?_ _self-type-binding?_ _block?_ `->` _type_
|
|
51
51
|
|
52
52
|
Class instance type denotes _an instance of a class_.
|
53
53
|
|
54
|
-
```
|
54
|
+
```rbs
|
55
55
|
Integer # Instance of Integer class
|
56
56
|
::Integer # Instance of ::Integer class
|
57
57
|
Hash[Symbol, String] # Instance of Hash class with type application of Symbol and String
|
@@ -61,7 +61,7 @@ Hash[Symbol, String] # Instance of Hash class with type application of S
|
|
61
61
|
|
62
62
|
Interface type denotes _type of a value which can be a subtype of the interface_.
|
63
63
|
|
64
|
-
```
|
64
|
+
```rbs
|
65
65
|
_ToS # _ToS interface
|
66
66
|
::MyApp::_Each[String] # Interface name with namespace and type application
|
67
67
|
```
|
@@ -72,7 +72,7 @@ Alias type denotes an alias declared with _alias declaration_.
|
|
72
72
|
|
73
73
|
The name of type aliases starts with lowercase `[a-z]`.
|
74
74
|
|
75
|
-
```
|
75
|
+
```rbs
|
76
76
|
name
|
77
77
|
::JSON::t # Alias name with namespace
|
78
78
|
list[Integer] # Type alias can be generic
|
@@ -82,7 +82,7 @@ list[Integer] # Type alias can be generic
|
|
82
82
|
|
83
83
|
Class singleton type denotes _the type of a singleton object of a class_.
|
84
84
|
|
85
|
-
```
|
85
|
+
```rbs
|
86
86
|
singleton(String)
|
87
87
|
singleton(::Hash) # Class singleton type cannot be parametrized.
|
88
88
|
```
|
@@ -91,7 +91,7 @@ singleton(::Hash) # Class singleton type cannot be parametrized.
|
|
91
91
|
|
92
92
|
Literal type denotes _a type with only one value of the literal_.
|
93
93
|
|
94
|
-
```
|
94
|
+
```rbs
|
95
95
|
123 # Integer
|
96
96
|
"hello world" # A string
|
97
97
|
:to_s # A symbol
|
@@ -102,7 +102,7 @@ true # true or false
|
|
102
102
|
|
103
103
|
Union type denotes _a type of one of the given types_.
|
104
104
|
|
105
|
-
```
|
105
|
+
```rbs
|
106
106
|
Integer | String # Integer or String
|
107
107
|
Array[Integer | String] # Array of Integer or String
|
108
108
|
```
|
@@ -111,7 +111,7 @@ Array[Integer | String] # Array of Integer or String
|
|
111
111
|
|
112
112
|
Intersection type denotes _a type of all of the given types_.
|
113
113
|
|
114
|
-
```
|
114
|
+
```rbs
|
115
115
|
_Reader & _Writer # _Reader and _Writer
|
116
116
|
```
|
117
117
|
|
@@ -121,7 +121,7 @@ Note that `&` has higher precedence than `|` that `A & B | C` is `(A & B) | C`.
|
|
121
121
|
|
122
122
|
Optional type denotes _a type of value or nil_.
|
123
123
|
|
124
|
-
```
|
124
|
+
```rbs
|
125
125
|
Integer?
|
126
126
|
Array[Integer?]
|
127
127
|
```
|
@@ -130,7 +130,7 @@ Array[Integer?]
|
|
130
130
|
|
131
131
|
Records are `Hash` objects, fixed set of keys, and heterogeneous.
|
132
132
|
|
133
|
-
```
|
133
|
+
```rbs
|
134
134
|
{ id: Integer, name: String } # Hash object like `{ id: 31, name: String }`
|
135
135
|
```
|
136
136
|
|
@@ -138,7 +138,7 @@ Records are `Hash` objects, fixed set of keys, and heterogeneous.
|
|
138
138
|
|
139
139
|
Tuples are `Array` objects, fixed size and heterogeneous.
|
140
140
|
|
141
|
-
```
|
141
|
+
```rbs
|
142
142
|
[ ] # Empty like `[]`
|
143
143
|
[String] # Single string like `["hi"]`
|
144
144
|
[Integer, Integer] # Pair of integers like `[1, 2]`
|
@@ -149,7 +149,7 @@ Tuples are `Array` objects, fixed size and heterogeneous.
|
|
149
149
|
|
150
150
|
### Type variable
|
151
151
|
|
152
|
-
```
|
152
|
+
```rbs
|
153
153
|
U
|
154
154
|
T
|
155
155
|
S
|
@@ -159,7 +159,7 @@ Elem
|
|
159
159
|
Type variables cannot be distinguished from _class instance types_.
|
160
160
|
They are scoped in _class/module/interface/alias declaration_ or _generic method types_.
|
161
161
|
|
162
|
-
```
|
162
|
+
```rbs
|
163
163
|
class Ref[T] # Object is scoped in the class declaration.
|
164
164
|
@value: T # Type variable `T`
|
165
165
|
def map: [X] { (T) -> X } -> Ref[X] # X is a type variable scoped in the method type.
|
@@ -193,7 +193,7 @@ It is an alias of `top` type, and you can use `boolish` if we want to allow any
|
|
193
193
|
|
194
194
|
We can see an example at the definition of `Enumerable#find`:
|
195
195
|
|
196
|
-
```
|
196
|
+
```rbs
|
197
197
|
module Enumerable[Elem, Return]
|
198
198
|
def find: () { (Elem) -> boolish } -> Elem?
|
199
199
|
end
|
@@ -201,7 +201,7 @@ end
|
|
201
201
|
|
202
202
|
We want to write something like:
|
203
203
|
|
204
|
-
```
|
204
|
+
```ruby
|
205
205
|
array.find {|x| x && x.some_test? } # The block will return (bool | nil)
|
206
206
|
```
|
207
207
|
|
@@ -218,7 +218,7 @@ They are all equivalent for the type system; they are all _top type_.
|
|
218
218
|
|
219
219
|
Proc type denotes type of procedures, `Proc` instances.
|
220
220
|
|
221
|
-
```
|
221
|
+
```rbs
|
222
222
|
^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
|
223
223
|
^(?String, size: Integer) -> bool # A procedure with `String` optional parameter, `size` keyword of `Integer`, and returns `bool`
|
224
224
|
```
|
@@ -266,7 +266,7 @@ Variable name can be used for documentation.
|
|
266
266
|
|
267
267
|
#### Examples
|
268
268
|
|
269
|
-
```
|
269
|
+
```rbs
|
270
270
|
# Two required positional `Integer` parameters, and returns `String`
|
271
271
|
(Integer, Integer) -> String
|
272
272
|
|
@@ -359,7 +359,7 @@ _method-name_ ::= ...
|
|
359
359
|
|
360
360
|
An instance variable definition consists of the name of an instance variable and its type.
|
361
361
|
|
362
|
-
```
|
362
|
+
```rbs
|
363
363
|
@name: String
|
364
364
|
@value: Hash[Symbol, Key]
|
365
365
|
```
|
@@ -370,7 +370,7 @@ Method definition has several syntax variations.
|
|
370
370
|
|
371
371
|
You can write `self.` or `self?.` before the name of the method to specify the kind of method: instance, singleton, or module function.
|
372
372
|
|
373
|
-
```
|
373
|
+
```rbs
|
374
374
|
def to_s: () -> String # Defines a instance method
|
375
375
|
def self.new: () -> AnObject # Defines singleton method
|
376
376
|
def self?.sqrt: (Numeric) -> Numeric # self? is for `module_function`s
|
@@ -380,7 +380,7 @@ def self?.sqrt: (Numeric) -> Numeric # self? is for `module_function`s
|
|
380
380
|
|
381
381
|
The method type can be connected with `|`s to define an overloaded method.
|
382
382
|
|
383
|
-
```
|
383
|
+
```rbs
|
384
384
|
def +: (Float) -> Float
|
385
385
|
| (Integer) -> Integer
|
386
386
|
| (Numeric) -> Numeric
|
@@ -388,7 +388,7 @@ def +: (Float) -> Float
|
|
388
388
|
|
389
389
|
Overloaded method can have `...` to overload an existing method. It is useful for monkey-patching.
|
390
390
|
|
391
|
-
```
|
391
|
+
```rbs
|
392
392
|
def +: (Float) -> Float
|
393
393
|
def +: (BigDecimal) -> BigDecimal
|
394
394
|
| ...
|
@@ -396,14 +396,14 @@ def +: (BigDecimal) -> BigDecimal
|
|
396
396
|
|
397
397
|
You need extra parentheses on return type to avoid ambiguity.
|
398
398
|
|
399
|
-
```
|
399
|
+
```rbs
|
400
400
|
def +: (Float | Integer) -> (Float | Integer)
|
401
401
|
| (Numeric) -> Numeric
|
402
402
|
```
|
403
403
|
|
404
404
|
Adding `public` and `private` modifier changes the visibility of the method.
|
405
405
|
|
406
|
-
```
|
406
|
+
```rbs
|
407
407
|
private def puts: (*untyped) -> void # Defines private instance method
|
408
408
|
|
409
409
|
public def self.puts: (*untyped) -> void # Defines public singleton method
|
@@ -417,7 +417,7 @@ Attribute definitions help to define methods and instance variables based on the
|
|
417
417
|
|
418
418
|
You can specify the name of instance variable using `(@some_name)` syntax and also omit the instance variable definition by specifying `()`.
|
419
419
|
|
420
|
-
```
|
420
|
+
```rbs
|
421
421
|
# Defines `id` method and `@id` instance variable.
|
422
422
|
attr_reader id: Integer
|
423
423
|
# @id: Integer
|
@@ -436,7 +436,7 @@ attr_accessor people (): Array[Person]
|
|
436
436
|
|
437
437
|
Attribute definitions can have the `public` and `private` modifiers like method definitions:
|
438
438
|
|
439
|
-
```
|
439
|
+
```rbs
|
440
440
|
private attr_accessor id: Integer
|
441
441
|
|
442
442
|
private attr_reader self.name: String
|
@@ -446,7 +446,7 @@ private attr_reader self.name: String
|
|
446
446
|
|
447
447
|
You can define mixins between class and modules.
|
448
448
|
|
449
|
-
```
|
449
|
+
```rbs
|
450
450
|
include Kernel
|
451
451
|
include Enumerable[String, void]
|
452
452
|
extend ActiveSupport::Concern
|
@@ -454,7 +454,7 @@ extend ActiveSupport::Concern
|
|
454
454
|
|
455
455
|
You can also `include` or `extend` an interface.
|
456
456
|
|
457
|
-
```
|
457
|
+
```rbs
|
458
458
|
include _Hashing
|
459
459
|
extend _LikeString
|
460
460
|
```
|
@@ -465,7 +465,7 @@ This allows importing `def`s from the interface to help developer implementing a
|
|
465
465
|
|
466
466
|
You can define an alias between methods.
|
467
467
|
|
468
|
-
```
|
468
|
+
```rbs
|
469
469
|
def map: [X] () { (String) -> X } -> Array[X]
|
470
470
|
alias collect map # `#collect` has the same type with `map`
|
471
471
|
```
|
@@ -548,7 +548,7 @@ Class declaration can have type parameters and superclass. When you omit supercl
|
|
548
548
|
|
549
549
|
Module declaration takes optional _self type_ parameter, which defines a constraint about a class when the module is mixed.
|
550
550
|
|
551
|
-
```
|
551
|
+
```rbs
|
552
552
|
interface _Each[A, B]
|
553
553
|
def each: { (A) -> void } -> B
|
554
554
|
end
|
@@ -572,7 +572,7 @@ class Bar = Array
|
|
572
572
|
|
573
573
|
The syntax defines a class and the definition is equivalent to the right-hand-side.
|
574
574
|
|
575
|
-
```
|
575
|
+
```rbs
|
576
576
|
class Baz < Bar[String] # Class alias can be inherited
|
577
577
|
include Foo # Module alias can be included
|
578
578
|
end
|
@@ -590,7 +590,7 @@ end
|
|
590
590
|
|
591
591
|
Interface declaration can have parameters but allows only a few of the members.
|
592
592
|
|
593
|
-
```
|
593
|
+
```rbs
|
594
594
|
interface _Hashing
|
595
595
|
def hash: () -> Integer
|
596
596
|
def eql?: (untyped) -> bool
|
@@ -602,7 +602,7 @@ There are several limitations which are not described in the grammar.
|
|
602
602
|
1. Interface cannot `include` modules
|
603
603
|
2. Interface cannot have singleton method definitions
|
604
604
|
|
605
|
-
```
|
605
|
+
```rbs
|
606
606
|
interface _Foo
|
607
607
|
include Bar # Error: cannot include modules
|
608
608
|
def self.new: () -> Foo # Error: cannot include singleton method definitions
|
@@ -613,14 +613,14 @@ end
|
|
613
613
|
|
614
614
|
You can declare an alias of types.
|
615
615
|
|
616
|
-
```
|
616
|
+
```rbs
|
617
617
|
type subject = Attendee | Speaker
|
618
618
|
type JSON::t = Integer | TrueClass | FalseClass | String | Hash[Symbol, t] | Array[t]
|
619
619
|
```
|
620
620
|
|
621
621
|
Type alias can be generic like class, module, and interface.
|
622
622
|
|
623
|
-
```
|
623
|
+
```rbs
|
624
624
|
type list[out T] = [T, list[T]] | nil
|
625
625
|
```
|
626
626
|
|
@@ -628,7 +628,7 @@ type list[out T] = [T, list[T]] | nil
|
|
628
628
|
|
629
629
|
You can declare a constant.
|
630
630
|
|
631
|
-
```
|
631
|
+
```rbs
|
632
632
|
Person::DefaultEmailAddress: String
|
633
633
|
```
|
634
634
|
|
@@ -636,13 +636,13 @@ Person::DefaultEmailAddress: String
|
|
636
636
|
|
637
637
|
You can declare a global variable.
|
638
638
|
|
639
|
-
```
|
639
|
+
```rbs
|
640
640
|
$LOAD_PATH: Array[String]
|
641
641
|
```
|
642
642
|
|
643
643
|
### Generics
|
644
644
|
|
645
|
-
```
|
645
|
+
```markdown
|
646
646
|
_module-type-parameter_ ::= _generics-unchecked_ _generics-variance_ _type-variable_ _generics-bound_
|
647
647
|
|
648
648
|
_method-type-param_ ::= _type-variable_ _generics-bound_
|
@@ -677,7 +677,7 @@ For classes with type parameters, you may specify if they are "invariant" (defau
|
|
677
677
|
|
678
678
|
For example, an `Array` of `String` can almost be considered to be an `Array` of `Object`, but not the reverse, so we can think of:
|
679
679
|
|
680
|
-
```
|
680
|
+
```rbs
|
681
681
|
# The `T` type parameter is covariant.
|
682
682
|
class Array[out T]
|
683
683
|
# etc.
|
@@ -732,7 +732,7 @@ The upper bound must be one of a class instance type, interface type, or class s
|
|
732
732
|
|
733
733
|
Directives are placed at the top of a file and provides per-file-basis features.
|
734
734
|
|
735
|
-
```
|
735
|
+
```markdown
|
736
736
|
_use-directive_ ::= `use` _use-clauses_
|
737
737
|
|
738
738
|
_use-clauses_ ::= _use-clause_ `,` ... `,` _use-clause_
|
@@ -745,7 +745,7 @@ _use-clause_ ::= _type-name_ # Single use clause
|
|
745
745
|
The *use directive* defines relative type names that is an alias of other type names.
|
746
746
|
We can use the simple type names if it is declared with *use*.
|
747
747
|
|
748
|
-
```
|
748
|
+
```rbs
|
749
749
|
use RBS::Namespace # => Defines `Namespace`
|
750
750
|
use RBS::TypeName as TN # => Defines `TN`
|
751
751
|
use RBS::AST::* # => Defines modules under `::RBS::AST::` namespace
|
@@ -755,7 +755,7 @@ use RBS::AST::* # => Defines modules under `::RBS::AST::` namespace
|
|
755
755
|
|
756
756
|
You can write single line comments. Comments must be on their own line. Comments can lead with whitespace.
|
757
757
|
|
758
|
-
```
|
758
|
+
```rbs
|
759
759
|
# This if interface Foo
|
760
760
|
# Usage of Foo is bar
|
761
761
|
interface _Foo
|