steep 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/lib/steep.rb +4 -0
- data/lib/steep/ast/types/any.rb +4 -0
- data/lib/steep/ast/types/boolean.rb +53 -0
- data/lib/steep/ast/types/bot.rb +4 -0
- data/lib/steep/ast/types/class.rb +4 -0
- data/lib/steep/ast/types/instance.rb +4 -0
- data/lib/steep/ast/types/intersection.rb +4 -0
- data/lib/steep/ast/types/literal.rb +59 -0
- data/lib/steep/ast/types/name.rb +4 -0
- data/lib/steep/ast/types/nil.rb +48 -0
- data/lib/steep/ast/types/self.rb +4 -0
- data/lib/steep/ast/types/top.rb +4 -0
- data/lib/steep/ast/types/tuple.rb +51 -0
- data/lib/steep/ast/types/union.rb +4 -0
- data/lib/steep/ast/types/var.rb +4 -0
- data/lib/steep/ast/types/void.rb +4 -0
- data/lib/steep/drivers/scaffold.rb +1 -1
- data/lib/steep/errors.rb +15 -0
- data/lib/steep/interface/builder.rb +5 -0
- data/lib/steep/interface/method.rb +10 -0
- data/lib/steep/parser.y +81 -39
- data/lib/steep/subtyping/check.rb +78 -0
- data/lib/steep/type_construction.rb +325 -195
- data/lib/steep/type_inference/type_env.rb +1 -1
- data/lib/steep/typing.rb +34 -19
- data/lib/steep/version.rb +1 -1
- data/smoke/and/a.rb +2 -2
- data/smoke/case/a.rb +1 -1
- data/smoke/literal/a.rb +2 -2
- data/stdlib/builtin.rbi +86 -84
- metadata +6 -2
@@ -78,7 +78,7 @@ module Steep
|
|
78
78
|
if lvar_types.key?(name) || common_vars.member?(name)
|
79
79
|
set(lvar: name, type: AST::Types::Union.build(types: types))
|
80
80
|
else
|
81
|
-
set(lvar: name, type: AST::Types::Union.build(types: types + [AST::Types::
|
81
|
+
set(lvar: name, type: AST::Types::Union.build(types: types + [AST::Types::Nil.new]))
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
data/lib/steep/typing.rb
CHANGED
@@ -4,8 +4,11 @@ module Steep
|
|
4
4
|
attr_reader :typing
|
5
5
|
attr_reader :nodes
|
6
6
|
attr_reader :var_typing
|
7
|
+
attr_reader :parent
|
8
|
+
|
9
|
+
def initialize(parent: nil)
|
10
|
+
@parent = parent
|
7
11
|
|
8
|
-
def initialize
|
9
12
|
@errors = []
|
10
13
|
@nodes = {}
|
11
14
|
@var_typing = {}
|
@@ -27,28 +30,18 @@ module Steep
|
|
27
30
|
typing.key?(node.__id__)
|
28
31
|
end
|
29
32
|
|
30
|
-
def add_var_type(variable, type)
|
31
|
-
if var_typing.key?(variable)
|
32
|
-
unless var_typing[variable] == type
|
33
|
-
raise "Unexpected variable typing: existing=#{var_typing[variable]}, new=#{type}"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
var_typing[variable] = type
|
38
|
-
end
|
39
|
-
|
40
33
|
def type_of(node:)
|
41
|
-
typing[node.__id__]
|
42
|
-
end
|
34
|
+
type = typing[node.__id__]
|
43
35
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
36
|
+
if type
|
37
|
+
type
|
38
|
+
else
|
39
|
+
if parent
|
40
|
+
parent.type_of(node: node)
|
41
|
+
else
|
42
|
+
raise "Unknown node for typing: #{node.inspect}"
|
48
43
|
end
|
49
44
|
end
|
50
|
-
|
51
|
-
raise "Unknown variable for typing: #{name}@#{label}"
|
52
45
|
end
|
53
46
|
|
54
47
|
def dump(io)
|
@@ -70,5 +63,27 @@ module Steep
|
|
70
63
|
|
71
64
|
"#{line}:#{col}:#{src}"
|
72
65
|
end
|
66
|
+
|
67
|
+
def new_child
|
68
|
+
yield self.class.new(parent: self)
|
69
|
+
end
|
70
|
+
|
71
|
+
def each_typing
|
72
|
+
nodes.each do |id, node|
|
73
|
+
yield node, typing[id]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def save!
|
78
|
+
raise "Unexpected save!" unless parent
|
79
|
+
|
80
|
+
each_typing do |node, type|
|
81
|
+
parent.add_typing(node, type)
|
82
|
+
end
|
83
|
+
|
84
|
+
errors.each do |error|
|
85
|
+
parent.add_error error
|
86
|
+
end
|
87
|
+
end
|
73
88
|
end
|
74
89
|
end
|
data/lib/steep/version.rb
CHANGED
data/smoke/and/a.rb
CHANGED
@@ -3,9 +3,9 @@
|
|
3
3
|
|
4
4
|
a = "foo"
|
5
5
|
|
6
|
-
# !expects IncompatibleAssignment: lhs_type=::String, rhs_type=(::
|
6
|
+
# !expects IncompatibleAssignment: lhs_type=::String, rhs_type=(::String | nil)
|
7
7
|
b = a && a.to_str
|
8
8
|
|
9
|
-
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=(::
|
9
|
+
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=(::String | nil)
|
10
10
|
c = a && a.to_str
|
11
11
|
|
data/smoke/case/a.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# @type var a: Integer
|
2
2
|
|
3
|
-
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=(::Array<::String> | ::Integer | ::
|
3
|
+
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=(::Array<::String> | ::Integer | ::String | nil)
|
4
4
|
a = case 1
|
5
5
|
when 2
|
6
6
|
1
|
data/smoke/literal/a.rb
CHANGED
@@ -10,7 +10,7 @@ x = :foo
|
|
10
10
|
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=::String
|
11
11
|
y = "foo"
|
12
12
|
|
13
|
-
# !expects IncompatibleAssignment: lhs_type=::String, rhs_type=
|
13
|
+
# !expects IncompatibleAssignment: lhs_type=::String, rhs_type=bool
|
14
14
|
x = true
|
15
|
-
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=
|
15
|
+
# !expects IncompatibleAssignment: lhs_type=::Integer, rhs_type=bool
|
16
16
|
y = false
|
data/stdlib/builtin.rbi
CHANGED
@@ -7,13 +7,13 @@ class Object <: BasicObject
|
|
7
7
|
def tap: { (self) -> any } -> self
|
8
8
|
def to_s: -> String
|
9
9
|
def hash: -> Integer
|
10
|
-
def eql?: (any) ->
|
11
|
-
def ==: (any) ->
|
12
|
-
def ===: (any) ->
|
13
|
-
def !=: (any) ->
|
10
|
+
def eql?: (any) -> bool
|
11
|
+
def ==: (any) -> bool
|
12
|
+
def ===: (any) -> bool
|
13
|
+
def !=: (any) -> bool
|
14
14
|
def class: -> class
|
15
15
|
def to_i: -> Integer
|
16
|
-
def is_a?: (Module) ->
|
16
|
+
def is_a?: (Module) -> bool
|
17
17
|
def inspect: -> String
|
18
18
|
def freeze: -> self
|
19
19
|
def method: (Symbol) -> Method
|
@@ -31,8 +31,8 @@ class Module
|
|
31
31
|
def extend: (Module) -> any
|
32
32
|
def attr_accessor: (*Symbol) -> any
|
33
33
|
def attr_writer: (*Symbol) -> any
|
34
|
-
def include: (Module) ->
|
35
|
-
def prepend: (Module) ->
|
34
|
+
def include: (Module) -> bool
|
35
|
+
def prepend: (Module) -> bool
|
36
36
|
end
|
37
37
|
|
38
38
|
class Method
|
@@ -49,13 +49,13 @@ module Kernel
|
|
49
49
|
| (String) -> any
|
50
50
|
| (*any) -> any
|
51
51
|
|
52
|
-
def block_given?: ->
|
52
|
+
def block_given?: -> bool
|
53
53
|
def enum_for: (Symbol, *any) -> any
|
54
54
|
def require_relative: (*String) -> void
|
55
55
|
def require: (*String) -> void
|
56
56
|
def loop: { () -> void } -> void
|
57
57
|
def puts: (*any) -> void
|
58
|
-
def eval: (String, ? Integer
|
58
|
+
def eval: (String, ? Integer?, ?String) -> any
|
59
59
|
end
|
60
60
|
|
61
61
|
class Array<'a>
|
@@ -72,11 +72,11 @@ class Array<'a>
|
|
72
72
|
def <<: ('a) -> self
|
73
73
|
|
74
74
|
def []: (Integer) -> 'a
|
75
|
-
| (Range<Integer>) ->
|
76
|
-
| (Integer, Integer) ->
|
75
|
+
| (Range<Integer>) -> self?
|
76
|
+
| (Integer, Integer) -> self?
|
77
77
|
def at: (Integer) -> 'a
|
78
|
-
| (Range<Integer>) ->
|
79
|
-
| (Integer, Integer) ->
|
78
|
+
| (Range<Integer>) -> self?
|
79
|
+
| (Integer, Integer) -> self?
|
80
80
|
def []=: (Integer, 'a) -> 'a
|
81
81
|
| (Integer, Integer, 'a) -> 'a
|
82
82
|
| (Integer, Integer, self) -> self
|
@@ -96,18 +96,18 @@ class Array<'a>
|
|
96
96
|
def combination: (?Integer) { (self) -> any } -> Array<self>
|
97
97
|
| (?Integer) -> Enumerator<self, Array<self>>
|
98
98
|
|
99
|
-
def empty?: ->
|
99
|
+
def empty?: -> bool
|
100
100
|
def compact: -> self
|
101
|
-
def compact!: ->
|
101
|
+
def compact!: -> self?
|
102
102
|
def concat: (*Array<'a>) -> self
|
103
103
|
| (*'a) -> self
|
104
|
-
def delete: ('a) ->
|
104
|
+
def delete: ('a) -> 'a?
|
105
105
|
| <'x> ('a) { ('a) -> any } -> ('a | 'x)
|
106
|
-
def delete_at: (Integer) ->
|
106
|
+
def delete_at: (Integer) -> 'a?
|
107
107
|
def delete_if: { ('a) -> any } -> self
|
108
108
|
| -> Enumerator<'a, self>
|
109
|
-
def reject!: { ('a) -> any } ->
|
110
|
-
| -> Enumerator<'a, self
|
109
|
+
def reject!: { ('a) -> any } -> self?
|
110
|
+
| -> Enumerator<'a, self?>
|
111
111
|
def dig: (Integer, any) -> any
|
112
112
|
def each: { ('a) -> any } -> self
|
113
113
|
| -> Enumerator<'a, self>
|
@@ -118,21 +118,21 @@ class Array<'a>
|
|
118
118
|
| (Integer) { (Integer) -> 'a } -> 'a
|
119
119
|
def fill: ('a) -> self
|
120
120
|
| { (Integer) -> 'a } -> self
|
121
|
-
| ('a, Integer, ?Integer
|
121
|
+
| ('a, Integer, ?Integer?) -> self
|
122
122
|
| ('a, Range<Integer>) -> self
|
123
|
-
| (Integer, ?Integer
|
123
|
+
| (Integer, ?Integer?) { (Integer) -> 'a} -> self
|
124
124
|
| (Range<Integer>) { (Integer) -> 'a } -> self
|
125
125
|
|
126
|
-
def find_index: ('a) ->
|
127
|
-
| { ('a) -> any } ->
|
128
|
-
| -> Enumerator<'a, Integer
|
126
|
+
def find_index: ('a) -> Integer?
|
127
|
+
| { ('a) -> any } -> Integer?
|
128
|
+
| -> Enumerator<'a, Integer?>
|
129
129
|
|
130
|
-
def index: ('a) ->
|
131
|
-
| { ('a) -> any } ->
|
132
|
-
| -> Enumerator<'a, Integer
|
130
|
+
def index: ('a) -> Integer?
|
131
|
+
| { ('a) -> any } -> Integer?
|
132
|
+
| -> Enumerator<'a, Integer?>
|
133
133
|
|
134
|
-
def flatten: (?Integer
|
135
|
-
def flatten!: (?Integer
|
134
|
+
def flatten: (?Integer?) -> Array<any>
|
135
|
+
def flatten!: (?Integer?) -> self?
|
136
136
|
|
137
137
|
def insert: (Integer, *'a) -> self
|
138
138
|
|
@@ -141,7 +141,7 @@ class Array<'a>
|
|
141
141
|
def keep_if: { ('a) -> any } -> self
|
142
142
|
| -> Enumerator<'a, self>
|
143
143
|
|
144
|
-
def last: ->
|
144
|
+
def last: -> 'a?
|
145
145
|
| (Integer) -> self
|
146
146
|
|
147
147
|
def length: -> Integer
|
@@ -152,7 +152,7 @@ class Array<'a>
|
|
152
152
|
def permutation: (?Integer) { (self) -> any } -> Array<self>
|
153
153
|
| (?Integer) -> Enumerator<self, Array<self>>
|
154
154
|
|
155
|
-
def pop: ->
|
155
|
+
def pop: -> 'a?
|
156
156
|
| (Integer) -> self
|
157
157
|
|
158
158
|
def unshift: (*'a) -> self
|
@@ -174,41 +174,41 @@ class Array<'a>
|
|
174
174
|
def reverse: -> self
|
175
175
|
def reverse!: -> self
|
176
176
|
|
177
|
-
def rindex: ('a) ->
|
178
|
-
| { ('a) -> any } ->
|
179
|
-
| -> Enumerator<'a, Integer
|
177
|
+
def rindex: ('a) -> Integer?
|
178
|
+
| { ('a) -> any } -> Integer?
|
179
|
+
| -> Enumerator<'a, Integer?>
|
180
180
|
|
181
181
|
def rotate: (?Integer) -> self
|
182
182
|
|
183
183
|
def rotate!: (?Integer) -> self
|
184
184
|
|
185
|
-
def sample: (?random: any) ->
|
185
|
+
def sample: (?random: any) -> 'a?
|
186
186
|
| (Integer, ?random: any) -> self
|
187
187
|
|
188
188
|
def select!: -> Enumerator<'a, self>
|
189
189
|
| { ('a) -> any } -> self
|
190
190
|
|
191
|
-
def shift: ->
|
191
|
+
def shift: -> 'a?
|
192
192
|
| (Integer) -> self
|
193
193
|
|
194
194
|
def shuffle: (?random: any) -> self
|
195
195
|
|
196
196
|
def shuffle!: (?random: any) -> self
|
197
197
|
|
198
|
-
def slice: (Integer) ->
|
199
|
-
| (Integer, Integer) ->
|
200
|
-
| (Range<Integer>) ->
|
198
|
+
def slice: (Integer) -> 'a?
|
199
|
+
| (Integer, Integer) -> self?
|
200
|
+
| (Range<Integer>) -> self?
|
201
201
|
|
202
|
-
def slice!: (Integer) ->
|
203
|
-
| (Integer, Integer) ->
|
204
|
-
| (Range<Integer>) ->
|
202
|
+
def slice!: (Integer) -> 'a?
|
203
|
+
| (Integer, Integer) -> self?
|
204
|
+
| (Range<Integer>) -> self?
|
205
205
|
|
206
206
|
def to_h: -> Hash<any, any>
|
207
207
|
|
208
208
|
def transpose: -> self
|
209
209
|
|
210
|
-
def uniq!: ->
|
211
|
-
| { ('a) -> any } ->
|
210
|
+
def uniq!: -> self?
|
211
|
+
| { ('a) -> any } -> self?
|
212
212
|
|
213
213
|
def values_at: (*Integer | Range<Integer>) -> self
|
214
214
|
|
@@ -217,7 +217,7 @@ class Array<'a>
|
|
217
217
|
end
|
218
218
|
|
219
219
|
class Hash<'key, 'value>
|
220
|
-
def []: ('key) ->
|
220
|
+
def []: ('key) -> 'value?
|
221
221
|
def []=: ('key, 'value) -> 'value
|
222
222
|
def size: -> Integer
|
223
223
|
def transform_values: <'a> { ('value) -> 'a } -> Hash<'key, 'a>
|
@@ -235,10 +235,12 @@ interface _ToS
|
|
235
235
|
def to_s: -> String
|
236
236
|
end
|
237
237
|
|
238
|
-
|
239
|
-
def !: ->
|
240
|
-
|
241
|
-
|
238
|
+
class TrueClass
|
239
|
+
def !: -> bool
|
240
|
+
end
|
241
|
+
|
242
|
+
class FalseClass
|
243
|
+
def !: -> bool
|
242
244
|
end
|
243
245
|
|
244
246
|
class NilClass
|
@@ -247,10 +249,10 @@ end
|
|
247
249
|
class Numeric
|
248
250
|
def +: (Numeric) -> Numeric
|
249
251
|
def /: (Numeric) -> Numeric
|
250
|
-
def <=: (any) ->
|
251
|
-
def >=: (any) ->
|
252
|
-
def < : (any) ->
|
253
|
-
def >: (any) ->
|
252
|
+
def <=: (any) -> bool
|
253
|
+
def >=: (any) -> bool
|
254
|
+
def < : (any) -> bool
|
255
|
+
def >: (any) -> bool
|
254
256
|
end
|
255
257
|
|
256
258
|
class Integer <: Numeric
|
@@ -357,13 +359,13 @@ interface _Iteratable<'a, 'b>
|
|
357
359
|
end
|
358
360
|
|
359
361
|
module Enumerable<'a, 'b> : _Iteratable<'a, 'b>
|
360
|
-
def all?: ->
|
361
|
-
| { ('a) -> any } ->
|
362
|
-
| (any) ->
|
362
|
+
def all?: -> bool
|
363
|
+
| { ('a) -> any } -> bool
|
364
|
+
| (any) -> bool
|
363
365
|
|
364
|
-
def any?: ->
|
365
|
-
| { ('a) -> any } ->
|
366
|
-
| (any) ->
|
366
|
+
def any?: -> bool
|
367
|
+
| { ('a) -> any } -> bool
|
368
|
+
| (any) -> bool
|
367
369
|
|
368
370
|
def chunk: { ('a) -> any } -> Enumerator<'a, self>
|
369
371
|
|
@@ -389,13 +391,13 @@ module Enumerable<'a, 'b> : _Iteratable<'a, 'b>
|
|
389
391
|
| (?Integer) { ('a) -> any } -> nil
|
390
392
|
|
391
393
|
def detect: ('a) { ('a) -> any } -> 'a
|
392
|
-
| { ('a) -> any } ->
|
393
|
-
| -> Enumerator<'a, 'a
|
394
|
+
| { ('a) -> any } -> 'a?
|
395
|
+
| -> Enumerator<'a, 'a?>
|
394
396
|
| ('a) -> Enumerator<'a, 'a>
|
395
397
|
|
396
398
|
def find: ('a) { ('a) -> any } -> 'a
|
397
|
-
| { ('a) -> any } ->
|
398
|
-
| -> Enumerator<'a, 'a
|
399
|
+
| { ('a) -> any } -> 'a?
|
400
|
+
| -> Enumerator<'a, 'a?>
|
399
401
|
| ('a) -> Enumerator<'a, 'a>
|
400
402
|
|
401
403
|
def drop: (Integer) -> Array<'a>
|
@@ -424,11 +426,11 @@ module Enumerable<'a, 'b> : _Iteratable<'a, 'b>
|
|
424
426
|
def select: -> Enumerator<'a, Array<'a>>
|
425
427
|
| { ('a) -> any } -> Array<'a>
|
426
428
|
|
427
|
-
def find_index: (any) ->
|
428
|
-
| { ('a) -> any } ->
|
429
|
-
| -> Enumerator<'a, Integer
|
429
|
+
def find_index: (any) -> Integer?
|
430
|
+
| { ('a) -> any } -> Integer?
|
431
|
+
| -> Enumerator<'a, Integer?>
|
430
432
|
|
431
|
-
def first: () ->
|
433
|
+
def first: () -> 'a?
|
432
434
|
| (Integer) -> Array<'a>
|
433
435
|
|
434
436
|
def grep: (any) -> Array<'a>
|
@@ -439,8 +441,8 @@ module Enumerable<'a, 'b> : _Iteratable<'a, 'b>
|
|
439
441
|
|
440
442
|
def group_by: <'x> { ('a) -> 'x } -> Hash<'x, Array<'a>>
|
441
443
|
|
442
|
-
def member?: (any) ->
|
443
|
-
def include?: (any) ->
|
444
|
+
def member?: (any) -> bool
|
445
|
+
def include?: (any) -> bool
|
444
446
|
|
445
447
|
def inject: <'x> ('x) { ('x, 'a) -> 'x } -> 'x
|
446
448
|
| (Symbol) -> any
|
@@ -453,20 +455,20 @@ module Enumerable<'a, 'b> : _Iteratable<'a, 'b>
|
|
453
455
|
| (any, Symbol) -> any
|
454
456
|
| { ('a, 'a) -> 'a } -> 'a
|
455
457
|
|
456
|
-
def max: ->
|
458
|
+
def max: -> 'a?
|
457
459
|
| (Integer) -> Array<'a>
|
458
|
-
| { ('a, 'a) -> Integer } ->
|
460
|
+
| { ('a, 'a) -> Integer } -> 'a?
|
459
461
|
| (Integer) { ('a, 'a) -> Integer } -> Array<'a>
|
460
462
|
|
461
|
-
def max_by: { ('a, 'a) -> Integer } ->
|
463
|
+
def max_by: { ('a, 'a) -> Integer } -> 'a?
|
462
464
|
| (Integer) { ('a, 'a) -> Integer } -> Array<'a>
|
463
465
|
|
464
|
-
def min: ->
|
466
|
+
def min: -> 'a?
|
465
467
|
| (Integer) -> Array<'a>
|
466
|
-
| { ('a, 'a) -> Integer } ->
|
468
|
+
| { ('a, 'a) -> Integer } -> 'a?
|
467
469
|
| (Integer) { ('a, 'a) -> Integer } -> Array<'a>
|
468
470
|
|
469
|
-
def min_by: { ('a, 'a) -> Integer } ->
|
471
|
+
def min_by: { ('a, 'a) -> Integer } -> 'a?
|
470
472
|
| (Integer) { ('a, 'a) -> Integer } -> Array<'a>
|
471
473
|
|
472
474
|
def min_max: -> Array<'a>
|
@@ -474,13 +476,13 @@ module Enumerable<'a, 'b> : _Iteratable<'a, 'b>
|
|
474
476
|
|
475
477
|
def min_max_by: { ('a, 'a) -> Integer } -> Array<'a>
|
476
478
|
|
477
|
-
def none?: ->
|
478
|
-
| { ('a) -> any } ->
|
479
|
-
| (any) ->
|
479
|
+
def none?: -> bool
|
480
|
+
| { ('a) -> any } -> bool
|
481
|
+
| (any) -> bool
|
480
482
|
|
481
|
-
def one?: ->
|
482
|
-
| { ('a) -> any } ->
|
483
|
-
| (any) ->
|
483
|
+
def one?: -> bool
|
484
|
+
| { ('a) -> any } -> bool
|
485
|
+
| (any) -> bool
|
484
486
|
|
485
487
|
def partition: { ('a) -> any } -> Array<Array<'a>>
|
486
488
|
| -> Enumerator<'a, Array<Array<'a>>>
|
@@ -533,7 +535,7 @@ class Regexp
|
|
533
535
|
end
|
534
536
|
|
535
537
|
class IO
|
536
|
-
def gets: ->
|
538
|
+
def gets: -> String?
|
537
539
|
def puts: (*any) -> void
|
538
540
|
end
|
539
541
|
|
@@ -541,10 +543,10 @@ class File <: IO
|
|
541
543
|
def self.binread: (String) -> String
|
542
544
|
def self.extname: (String) -> String
|
543
545
|
def self.basename: (String) -> String
|
544
|
-
def self.readable?: (String) ->
|
546
|
+
def self.readable?: (String) -> bool
|
545
547
|
def self.binwrite: (String, String) -> void
|
546
548
|
def self.read: (String) -> String
|
547
|
-
| (String, Integer
|
549
|
+
| (String, Integer?) -> String?
|
548
550
|
end
|
549
551
|
|
550
552
|
STDOUT: IO
|