steep 0.3.0 → 0.4.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/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
|