rbs 0.20.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +10 -4
- data/CHANGELOG.md +41 -0
- data/Gemfile +7 -2
- data/README.md +1 -1
- data/Rakefile +15 -4
- data/Steepfile +2 -1
- data/bin/annotate-with-rdoc +0 -4
- data/bin/test_runner.rb +4 -5
- data/core/builtin.rbs +4 -0
- data/core/encoding.rbs +1 -1
- data/core/file.rbs +4 -0
- data/core/io.rbs +240 -11
- data/core/kernel.rbs +57 -57
- data/core/module.rbs +43 -2
- data/core/unbound_method.rbs +16 -0
- data/docs/CONTRIBUTING.md +2 -2
- data/docs/stdlib.md +50 -12
- data/docs/syntax.md +0 -17
- data/goodcheck.yml +23 -3
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +7 -49
- data/lib/rbs/ast/members.rb +1 -1
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +580 -1006
- data/lib/rbs/definition_builder/ancestor_builder.rb +525 -0
- data/lib/rbs/definition_builder/method_builder.rb +217 -0
- data/lib/rbs/environment.rb +3 -8
- data/lib/rbs/environment_loader.rb +8 -4
- data/lib/rbs/errors.rb +88 -121
- data/lib/rbs/parser.rb +1017 -995
- data/lib/rbs/parser.y +25 -23
- data/lib/rbs/prototype/rb.rb +19 -5
- data/lib/rbs/prototype/rbi.rb +1 -1
- data/lib/rbs/prototype/runtime.rb +70 -34
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +22 -7
- data/lib/rbs/test/setup_helper.rb +0 -1
- data/lib/rbs/types.rb +6 -2
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +4 -3
- data/rbs.gemspec +1 -0
- data/sig/ancestor_builder.rbs +98 -0
- data/sig/declarations.rbs +4 -16
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +17 -71
- data/sig/errors.rbs +159 -0
- data/sig/method_builder.rbs +71 -0
- data/sig/substitution.rbs +3 -0
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/types.rbs +1 -15
- data/sig/validator.rbs +12 -0
- data/stdlib/csv/0/csv.rbs +3 -0
- data/stdlib/fileutils/0/fileutils.rbs +585 -0
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/pathname/0/pathname.rbs +2 -2
- data/stdlib/prettyprint/0/prettyprint.rbs +366 -0
- data/stdlib/prime/0/prime.rbs +6 -0
- data/stdlib/securerandom/0/securerandom.rbs +2 -0
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/uri/0/common.rbs +401 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/steep/Gemfile.lock +10 -11
- metadata +16 -5
- data/core/data.rbs +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d03121b9d58454590a45862ba1d479305feae4f2b4d10707ae8e1a3c24d4aba
|
4
|
+
data.tar.gz: f147d99859cfc7e18b41a751587f7b2cba484bf397d5b306b9fe69f15dd4b452
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2e325492bc73b6d9f2f62660c4e4821f7d3853780f39a957e02ad4b30fc44ca1e687fbde9d0b2843be786e51126fbb5473e1d5ae5c9c719f255bfc50fe2f7cde
|
7
|
+
data.tar.gz: '03995c9d63b9db359744338497985952eed7608729cb4a259b20af6e68de5eecdf3c996404701e2821f35d4bebfdb1e2c7c8e6289f9b5a7875fd4c6c507bde27'
|
data/.github/workflows/ruby.yml
CHANGED
@@ -12,8 +12,8 @@ jobs:
|
|
12
12
|
strategy:
|
13
13
|
matrix:
|
14
14
|
container_tag:
|
15
|
-
- master-nightly-
|
16
|
-
-
|
15
|
+
- master-nightly-focal
|
16
|
+
- 3.0-focal
|
17
17
|
- 2.7-bionic
|
18
18
|
job:
|
19
19
|
- test
|
@@ -27,12 +27,18 @@ jobs:
|
|
27
27
|
run: |
|
28
28
|
apt-get update
|
29
29
|
apt-get install -y libdb-dev
|
30
|
-
- name: Install
|
30
|
+
- name: Install bundler
|
31
31
|
run: |
|
32
32
|
ruby -v
|
33
33
|
gem install bundler
|
34
|
+
- name: bundle config set with
|
35
|
+
run: |
|
36
|
+
echo "NO_MINITEST=true" >> $GITHUB_ENV
|
37
|
+
bundle config set --local without 'minitest'
|
38
|
+
if: "contains(matrix.container_tag, 'master-nightly')"
|
39
|
+
- name: bin/setup
|
40
|
+
run: |
|
34
41
|
bin/setup
|
35
42
|
- name: Run test
|
36
43
|
run: |
|
37
44
|
bundle exec rake ${{ matrix.job }}
|
38
|
-
if: "!(matrix.job == 'stdlib_test' && contains(matrix.container_tag, '2.6'))"
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,47 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.0.1 (2021-01-27)
|
6
|
+
|
7
|
+
* Signature Updates
|
8
|
+
* PrettyPrint ([\#573](https://github.com/ruby/rbs/pull/573))
|
9
|
+
* FileUtils ([\#576](https://github.com/ruby/rbs/pull/576))
|
10
|
+
* UnboundMethod ([\#555](https://github.com/ruby/rbs/pull/555))
|
11
|
+
* IO ([\#571](https://github.com/ruby/rbs/pull/571))
|
12
|
+
* Kernel ([\#549](https://github.com/ruby/rbs/pull/549), [\#569](https://github.com/ruby/rbs/pull/569))
|
13
|
+
* File ([\#552](https://github.com/ruby/rbs/pull/552))
|
14
|
+
* Data is removed ([\#570](https://github.com/ruby/rbs/pull/570))
|
15
|
+
* Module ([\#568](https://github.com/ruby/rbs/pull/568))
|
16
|
+
* Object ([\#557](https://github.com/ruby/rbs/pull/557))
|
17
|
+
* Renew test sample code ([#581](https://github.com/ruby/rbs/pull/581))
|
18
|
+
* Add description to `generate:stdlib_test` Rake task ([\#578](https://github.com/ruby/rbs/pull/578))
|
19
|
+
* Declare supported ruby version >= 2.6 ([\#548](https://github.com/ruby/rbs/pull/548))
|
20
|
+
* Fix module self-type override ([\#577](https://github.com/ruby/rbs/pull/577))
|
21
|
+
* Fix parser to support all operator symbols ([\#550](https://github.com/ruby/rbs/pull/550))
|
22
|
+
* Migrate from Minitest to Test::Unit ([\#556](https://github.com/ruby/rbs/pull/556))
|
23
|
+
* Fix type alias parsing ([\#565](https://github.com/ruby/rbs/pull/565))
|
24
|
+
* Support end-less method definition in `prototype rb` ([\#561](https://github.com/ruby/rbs/pull/561))
|
25
|
+
* Support method argument forwarding in `prototype rb` ([\#560](https://github.com/ruby/rbs/pull/560))
|
26
|
+
|
27
|
+
## 1.0.0 (2020-12-24)
|
28
|
+
|
29
|
+
* Signature updates for `URI`, `IO`, `File`, `Pathname`, `Module`, and `Time` ([#529](https://github.com/ruby/rbs/pull/529), [#521](https://github.com/ruby/rbs/pull/521), [#520](https://github.com/ruby/rbs/pull/520), [#511](https://github.com/ruby/rbs/pull/511), [#517](https://github.com/ruby/rbs/pull/517), [#542](https://github.com/ruby/rbs/pull/542), [#546](https://github.com/ruby/rbs/pull/546), [#540](https://github.com/ruby/rbs/pull/540), [#538](https://github.com/ruby/rbs/pull/538))
|
30
|
+
* `rbs prototype runtime` generates `extend`s ([#535](https://github.com/ruby/rbs/pull/535))
|
31
|
+
* `rbs prototype runtime` stability improvements ([#533](https://github.com/ruby/rbs/pull/533), [#526](https://github.com/ruby/rbs/pull/526))
|
32
|
+
* `rbs prototype rb` compatibility improvements ([#545](https://github.com/ruby/rbs/pull/545))
|
33
|
+
* Implement method names escape in `RBS::Writer` ([#537](https://github.com/ruby/rbs/pull/537))
|
34
|
+
* Improve runtime type checker compatibility ([#532](https://github.com/ruby/rbs/pull/532), [#528](https://github.com/ruby/rbs/pull/528), [#547](https://github.com/ruby/rbs/pull/547))
|
35
|
+
* Fix `ruby2_keywords` for `Proc` in Ruby <2.7 ([#513](https://github.com/ruby/rbs/pull/513))
|
36
|
+
* Better compatibility for record type attribute names ([#525](https://github.com/ruby/rbs/pull/525), [#524](https://github.com/ruby/rbs/pull/524))
|
37
|
+
* Let module self-types be classes ([#523](https://github.com/ruby/rbs/pull/523))
|
38
|
+
* Delete `extension` syntax ([#543](https://github.com/ruby/rbs/pull/543))
|
39
|
+
* Method resolution improvements about `alias` and `.new` ([#522](https://github.com/ruby/rbs/pull/522), [#519](https://github.com/ruby/rbs/pull/519), [#516](https://github.com/ruby/rbs/pull/516))
|
40
|
+
* Better message for `DuplicatedMethodDefinitionError` ([#539](https://github.com/ruby/rbs/pull/539))
|
41
|
+
|
42
|
+
## 0.20.1 (2020-12-06)
|
43
|
+
|
44
|
+
* Make the order of RBS load reproducible ([#508](https://github.com/ruby/rbs/pull/508))
|
45
|
+
|
5
46
|
## 0.20.0 (2020-12-06)
|
6
47
|
|
7
48
|
* Signature updates for `TSort`, `DBM`, `Time`, and `Hash` ([#496](https://github.com/ruby/rbs/pull/496), [#497](https://github.com/ruby/rbs/pull/497), [#499](https://github.com/ruby/rbs/pull/499), [#507](https://github.com/ruby/rbs/pull/507))
|
data/Gemfile
CHANGED
@@ -5,12 +5,12 @@ gemspec
|
|
5
5
|
|
6
6
|
# Development dependencies
|
7
7
|
gem "rake"
|
8
|
-
gem "
|
8
|
+
gem "test-unit"
|
9
|
+
gem "test-unit-rr"
|
9
10
|
gem "rspec"
|
10
11
|
gem "racc"
|
11
12
|
gem "rubocop"
|
12
13
|
gem "rubocop-rubycw"
|
13
|
-
gem "minitest-reporters"
|
14
14
|
gem "json"
|
15
15
|
gem "json-schema"
|
16
16
|
gem 'stackprof'
|
@@ -22,4 +22,9 @@ gem "rbs-amber", path: "test/assets/test-gem"
|
|
22
22
|
|
23
23
|
group :ide, optional: true do
|
24
24
|
gem "ruby-debug-ide"
|
25
|
+
gem "debase", ">= 0.2.5.beta2"
|
26
|
+
end
|
27
|
+
|
28
|
+
group :minitest do
|
29
|
+
gem "minitest"
|
25
30
|
end
|
data/README.md
CHANGED
@@ -107,7 +107,7 @@ instance = builder.build_instance(string)
|
|
107
107
|
|
108
108
|
# Print the types of `gsub` method:
|
109
109
|
puts instance.methods[:gsub].method_types.join("\n")
|
110
|
-
#
|
110
|
+
# Outputs =>
|
111
111
|
# (::Regexp | ::string pattern, ::string replacement) -> ::String
|
112
112
|
# (::Regexp | ::string pattern, ::Hash[::String, ::String] hash) -> ::String
|
113
113
|
# (::Regexp | ::string pattern) { (::String match) -> ::_ToS } -> ::String
|
data/Rakefile
CHANGED
@@ -28,8 +28,6 @@ task :validate => :parser do
|
|
28
28
|
sh "#{ruby} #{rbs} validate --silent"
|
29
29
|
|
30
30
|
FileList["stdlib/*"].each do |path|
|
31
|
-
next if path =~ %r{stdlib/builtin}
|
32
|
-
|
33
31
|
lib = [File.basename(path).to_s]
|
34
32
|
|
35
33
|
if lib == ["bigdecimal-math"]
|
@@ -41,6 +39,18 @@ task :validate => :parser do
|
|
41
39
|
lib << "pstore"
|
42
40
|
end
|
43
41
|
|
42
|
+
if lib == ["logger"]
|
43
|
+
lib << "monitor"
|
44
|
+
end
|
45
|
+
|
46
|
+
if lib == ["csv"]
|
47
|
+
lib << "forwardable"
|
48
|
+
end
|
49
|
+
|
50
|
+
if lib == ["prime"]
|
51
|
+
lib << "singleton"
|
52
|
+
end
|
53
|
+
|
44
54
|
sh "#{ruby} #{rbs} #{lib.map {|l| "-r #{l}"}.join(" ")} validate --silent"
|
45
55
|
end
|
46
56
|
end
|
@@ -72,6 +82,7 @@ task :confirm_parser do
|
|
72
82
|
end
|
73
83
|
|
74
84
|
namespace :generate do
|
85
|
+
desc "Generate a test file for a stdlib class signatures"
|
75
86
|
task :stdlib_test, [:class] do |_task, args|
|
76
87
|
klass = args.fetch(:class) do
|
77
88
|
raise "Class name is necessary. e.g. rake 'generate:stdlib_test[String]'"
|
@@ -103,7 +114,7 @@ namespace :generate do
|
|
103
114
|
require_relative "test_helper"
|
104
115
|
|
105
116
|
<%- unless class_methods.empty? -%>
|
106
|
-
class <%= klass %>SingletonTest <
|
117
|
+
class <%= klass %>SingletonTest < Test::Unit::TestCase
|
107
118
|
include TypeAssertions
|
108
119
|
|
109
120
|
# library "pathname", "set", "securerandom" # Declare library signatures to load
|
@@ -121,7 +132,7 @@ namespace :generate do
|
|
121
132
|
<%- end -%>
|
122
133
|
|
123
134
|
<%- unless instance_methods.empty? -%>
|
124
|
-
class <%= klass %>Test <
|
135
|
+
class <%= klass %>Test < Test::Unit::TestCase
|
125
136
|
include TypeAssertions
|
126
137
|
|
127
138
|
# library "pathname", "set", "securerandom" # Declare library signatures to load
|
data/Steepfile
CHANGED
@@ -2,8 +2,9 @@ target :lib do
|
|
2
2
|
signature "sig"
|
3
3
|
check "lib"
|
4
4
|
ignore "lib/rbs/parser.rb"
|
5
|
+
ignore "lib/rbs/prototype", "lib/rbs/test", "lib/rbs/test.rb"
|
5
6
|
|
6
|
-
library "set", "pathname", "json", "logger"
|
7
|
+
library "set", "pathname", "json", "logger", "monitor", "tsort"
|
7
8
|
end
|
8
9
|
|
9
10
|
# target :lib do
|
data/bin/annotate-with-rdoc
CHANGED
@@ -140,10 +140,6 @@ ARGV.map {|f| Pathname(f) }.each do |path|
|
|
140
140
|
comment = comment_for_class(decl, stores: stores)
|
141
141
|
decl.instance_variable_set(:@comment, comment)
|
142
142
|
|
143
|
-
print_members stores, decl.name.to_s, decl.members
|
144
|
-
when RBS::AST::Declarations::Extension
|
145
|
-
puts " Importing documentation for #{decl.name} (#{decl.extension_name})"
|
146
|
-
|
147
143
|
print_members stores, decl.name.to_s, decl.members
|
148
144
|
end
|
149
145
|
end
|
data/bin/test_runner.rb
CHANGED
@@ -4,13 +4,12 @@ $LOAD_PATH << File.join(__dir__, "../lib")
|
|
4
4
|
|
5
5
|
require "set"
|
6
6
|
|
7
|
-
|
8
|
-
Gem::Version.new('
|
9
|
-
ruby_version <= Gem::Version.new('2.8.0')
|
7
|
+
IS_LATEST_RUBY = Gem::Version.new(RUBY_VERSION).yield_self do |ruby_version|
|
8
|
+
Gem::Version.new('3.0.0') <= ruby_version && ruby_version < Gem::Version.new('3.1.0')
|
10
9
|
end
|
11
10
|
|
12
|
-
unless
|
13
|
-
STDERR.puts "⚠️⚠️⚠️⚠️ stdlib test assumes Ruby
|
11
|
+
unless IS_LATEST_RUBY
|
12
|
+
STDERR.puts "⚠️⚠️⚠️⚠️ stdlib test assumes Ruby 3.0 but RUBY_VERSION==#{RUBY_VERSION} ⚠️⚠️⚠️⚠️"
|
14
13
|
end
|
15
14
|
|
16
15
|
KNOWN_FAILS = %w(dbm).map do |lib|
|
data/core/builtin.rbs
CHANGED
@@ -34,6 +34,10 @@ interface _Reader
|
|
34
34
|
def read: (?int length, ?string outbuf) -> String?
|
35
35
|
end
|
36
36
|
|
37
|
+
interface _ReaderPartial
|
38
|
+
def readpartial: (int maxlen, ?string outbuf) -> String
|
39
|
+
end
|
40
|
+
|
37
41
|
interface _Writer
|
38
42
|
# Writes the +data+ string. Returns the number of bytes written
|
39
43
|
def write: (*_ToS data) -> Integer
|
data/core/encoding.rbs
CHANGED
data/core/file.rbs
CHANGED
@@ -531,6 +531,10 @@ class File < IO
|
|
531
531
|
#
|
532
532
|
def self.mtime: (string | _ToPath | IO file_name) -> Time
|
533
533
|
|
534
|
+
# Alias of `File.new`.
|
535
|
+
def self.open: (string | _ToPath | int file_name, ?(string | int) mode, ?int perm) -> instance
|
536
|
+
| [T] (string | _ToPath | int file_name, ?(string | int) mode, ?int perm) { (File) -> T } -> T
|
537
|
+
|
534
538
|
# Returns `true` if the named file exists and the effective used id of the
|
535
539
|
# calling process is the owner of the file.
|
536
540
|
#
|
data/core/io.rbs
CHANGED
@@ -107,14 +107,85 @@ class IO < Object
|
|
107
107
|
|
108
108
|
include Enumerable[String]
|
109
109
|
|
110
|
-
|
110
|
+
# String Output---Writes *obj* to *ios*. *obj* will be converted to a string
|
111
|
+
# using `to_s`.
|
112
|
+
#
|
113
|
+
# $stdout << "Hello " << "world!\n"
|
114
|
+
#
|
115
|
+
# *produces:*
|
116
|
+
#
|
117
|
+
# Hello world!
|
118
|
+
#
|
119
|
+
def <<: (_ToS obj) -> self
|
111
120
|
|
112
|
-
|
121
|
+
# Announce an intention to access data from the current file in a specific
|
122
|
+
# pattern. On platforms that do not support the *posix_fadvise(2)* system call,
|
123
|
+
# this method is a no-op.
|
124
|
+
#
|
125
|
+
# *advice* is one of the following symbols:
|
126
|
+
#
|
127
|
+
# :normal
|
128
|
+
# : No advice to give; the default assumption for an open file.
|
129
|
+
# :sequential
|
130
|
+
# : The data will be accessed sequentially with lower offsets read before
|
131
|
+
# higher ones.
|
132
|
+
# :random
|
133
|
+
# : The data will be accessed in random order.
|
134
|
+
# :willneed
|
135
|
+
# : The data will be accessed in the near future.
|
136
|
+
# :dontneed
|
137
|
+
# : The data will not be accessed in the near future.
|
138
|
+
# :noreuse
|
139
|
+
# : The data will only be accessed once.
|
140
|
+
#
|
141
|
+
#
|
142
|
+
# The semantics of a piece of advice are platform-dependent. See *man 2
|
143
|
+
# posix_fadvise* for details.
|
144
|
+
#
|
145
|
+
# "data" means the region of the current file that begins at *offset* and
|
146
|
+
# extends for *len* bytes. If *len* is 0, the region ends at the last byte of
|
147
|
+
# the file. By default, both *offset* and *len* are 0, meaning that the advice
|
148
|
+
# applies to the entire file.
|
149
|
+
#
|
150
|
+
# If an error occurs, one of the following exceptions will be raised:
|
151
|
+
#
|
152
|
+
# IOError
|
153
|
+
# : The IO stream is closed.
|
154
|
+
# Errno::EBADF
|
155
|
+
# : The file descriptor of the current file is invalid.
|
156
|
+
# Errno::EINVAL
|
157
|
+
# : An invalid value for *advice* was given.
|
158
|
+
# Errno::ESPIPE
|
159
|
+
# : The file descriptor of the current file refers to a FIFO or pipe. (Linux
|
160
|
+
# raises Errno::EINVAL in this case).
|
161
|
+
# TypeError
|
162
|
+
# : Either *advice* was not a Symbol, or one of the other arguments was not an
|
163
|
+
# Integer.
|
164
|
+
# RangeError
|
165
|
+
# : One of the arguments given was too big/small.
|
166
|
+
#
|
167
|
+
# This list is not exhaustive; other Errno
|
168
|
+
# : exceptions are also possible.
|
169
|
+
#
|
170
|
+
def advise: ((:normal | :sequential | :random | :willneed | :dontneed | :noreuse) advise, ?Integer offset, ?Integer len) -> nil
|
113
171
|
|
114
|
-
|
172
|
+
# Sets auto-close flag.
|
173
|
+
#
|
174
|
+
# f = open("/dev/null")
|
175
|
+
# IO.for_fd(f.fileno)
|
176
|
+
# # ...
|
177
|
+
# f.gets # may cause Errno::EBADF
|
178
|
+
#
|
179
|
+
# f = open("/dev/null")
|
180
|
+
# IO.for_fd(f.fileno).autoclose = false
|
181
|
+
# # ...
|
182
|
+
# f.gets # won't cause Errno::EBADF
|
183
|
+
#
|
184
|
+
def autoclose=: (bool) -> bool
|
115
185
|
|
116
186
|
# Returns `true` if the underlying file descriptor of *ios* will be closed
|
117
|
-
# automatically at its finalization, otherwise `false
|
187
|
+
# automatically at its finalization, otherwise `false`.
|
188
|
+
#
|
118
189
|
def autoclose?: () -> bool
|
119
190
|
|
120
191
|
# Puts *ios* into binary mode. Once a stream is in binary mode, it cannot
|
@@ -405,7 +476,63 @@ class IO < Object
|
|
405
476
|
|
406
477
|
def puts: (*untyped arg0) -> NilClass
|
407
478
|
|
408
|
-
|
479
|
+
# Reads *length* bytes from the I/O stream.
|
480
|
+
#
|
481
|
+
# *length* must be a non-negative integer or `nil`.
|
482
|
+
#
|
483
|
+
# If *length* is a positive integer, `read` tries to read *length* bytes without
|
484
|
+
# any conversion (binary mode). It returns `nil` if an EOF is encountered before
|
485
|
+
# anything can be read. Fewer than *length* bytes are returned if an EOF is
|
486
|
+
# encountered during the read. In the case of an integer *length*, the resulting
|
487
|
+
# string is always in ASCII-8BIT encoding.
|
488
|
+
#
|
489
|
+
# If *length* is omitted or is `nil`, it reads until EOF and the encoding
|
490
|
+
# conversion is applied, if applicable. A string is returned even if EOF is
|
491
|
+
# encountered before any data is read.
|
492
|
+
#
|
493
|
+
# If *length* is zero, it returns an empty string (`""`).
|
494
|
+
#
|
495
|
+
# If the optional *outbuf* argument is present, it must reference a String,
|
496
|
+
# which will receive the data. The *outbuf* will contain only the received data
|
497
|
+
# after the method call even if it is not empty at the beginning.
|
498
|
+
#
|
499
|
+
# When this method is called at end of file, it returns `nil` or `""`, depending
|
500
|
+
# on *length*: `read`, `read(nil)`, and `read(0)` return `""`,
|
501
|
+
# `read(*positive_integer*)` returns `nil`.
|
502
|
+
#
|
503
|
+
# f = File.new("testfile")
|
504
|
+
# f.read(16) #=> "This is line one"
|
505
|
+
#
|
506
|
+
# # read whole file
|
507
|
+
# open("file") do |f|
|
508
|
+
# data = f.read # This returns a string even if the file is empty.
|
509
|
+
# # ...
|
510
|
+
# end
|
511
|
+
#
|
512
|
+
# # iterate over fixed length records
|
513
|
+
# open("fixed-record-file") do |f|
|
514
|
+
# while record = f.read(256)
|
515
|
+
# # ...
|
516
|
+
# end
|
517
|
+
# end
|
518
|
+
#
|
519
|
+
# # iterate over variable length records,
|
520
|
+
# # each record is prefixed by its 32-bit length
|
521
|
+
# open("variable-record-file") do |f|
|
522
|
+
# while len = f.read(4)
|
523
|
+
# len = len.unpack("N")[0] # 32-bit length
|
524
|
+
# record = f.read(len) # This returns a string even if len is 0.
|
525
|
+
# end
|
526
|
+
# end
|
527
|
+
#
|
528
|
+
# Note that this method behaves like the fread() function in C. This means it
|
529
|
+
# retries to invoke read(2) system calls to read data with the specified length
|
530
|
+
# (or until EOF). This behavior is preserved even if *ios* is in non-blocking
|
531
|
+
# mode. (This method is non-blocking flag insensitive as other methods.) If you
|
532
|
+
# need the behavior like a single read(2) system call, consider #readpartial,
|
533
|
+
# #read_nonblock, and #sysread.
|
534
|
+
#
|
535
|
+
def read: (?Integer? length, ?String outbuf) -> String?
|
409
536
|
|
410
537
|
def read_nonblock: (Integer len) -> String
|
411
538
|
| (Integer len, ?String buf) -> String
|
@@ -428,8 +555,63 @@ class IO < Object
|
|
428
555
|
|
429
556
|
def readlines: (?String sep, ?Integer limit) -> ::Array[String]
|
430
557
|
|
431
|
-
|
432
|
-
|
558
|
+
# Reads at most *maxlen* bytes from the I/O stream. It blocks only if *ios* has
|
559
|
+
# no data immediately available. It doesn't block if some data available.
|
560
|
+
#
|
561
|
+
# If the optional *outbuf* argument is present, it must reference a String,
|
562
|
+
# which will receive the data. The *outbuf* will contain only the received data
|
563
|
+
# after the method call even if it is not empty at the beginning.
|
564
|
+
#
|
565
|
+
# It raises EOFError on end of file.
|
566
|
+
#
|
567
|
+
# readpartial is designed for streams such as pipe, socket, tty, etc. It blocks
|
568
|
+
# only when no data immediately available. This means that it blocks only when
|
569
|
+
# following all conditions hold.
|
570
|
+
# * the byte buffer in the IO object is empty.
|
571
|
+
# * the content of the stream is empty.
|
572
|
+
# * the stream is not reached to EOF.
|
573
|
+
#
|
574
|
+
#
|
575
|
+
# When readpartial blocks, it waits data or EOF on the stream. If some data is
|
576
|
+
# reached, readpartial returns with the data. If EOF is reached, readpartial
|
577
|
+
# raises EOFError.
|
578
|
+
#
|
579
|
+
# When readpartial doesn't blocks, it returns or raises immediately. If the byte
|
580
|
+
# buffer is not empty, it returns the data in the buffer. Otherwise if the
|
581
|
+
# stream has some content, it returns the data in the stream. Otherwise if the
|
582
|
+
# stream is reached to EOF, it raises EOFError.
|
583
|
+
#
|
584
|
+
# r, w = IO.pipe # buffer pipe content
|
585
|
+
# w << "abc" # "" "abc".
|
586
|
+
# r.readpartial(4096) #=> "abc" "" ""
|
587
|
+
# r.readpartial(4096) # blocks because buffer and pipe is empty.
|
588
|
+
#
|
589
|
+
# r, w = IO.pipe # buffer pipe content
|
590
|
+
# w << "abc" # "" "abc"
|
591
|
+
# w.close # "" "abc" EOF
|
592
|
+
# r.readpartial(4096) #=> "abc" "" EOF
|
593
|
+
# r.readpartial(4096) # raises EOFError
|
594
|
+
#
|
595
|
+
# r, w = IO.pipe # buffer pipe content
|
596
|
+
# w << "abc\ndef\n" # "" "abc\ndef\n"
|
597
|
+
# r.gets #=> "abc\n" "def\n" ""
|
598
|
+
# w << "ghi\n" # "def\n" "ghi\n"
|
599
|
+
# r.readpartial(4096) #=> "def\n" "" "ghi\n"
|
600
|
+
# r.readpartial(4096) #=> "ghi\n" "" ""
|
601
|
+
#
|
602
|
+
# Note that readpartial behaves similar to sysread. The differences are:
|
603
|
+
# * If the byte buffer is not empty, read from the byte buffer instead of
|
604
|
+
# "sysread for buffered IO (IOError)".
|
605
|
+
# * It doesn't cause Errno::EWOULDBLOCK and Errno::EINTR. When readpartial
|
606
|
+
# meets EWOULDBLOCK and EINTR by read system call, readpartial retry the
|
607
|
+
# system call.
|
608
|
+
#
|
609
|
+
#
|
610
|
+
# The latter means that readpartial is nonblocking-flag insensitive. It blocks
|
611
|
+
# on the situation IO#sysread causes Errno::EWOULDBLOCK as if the fd is blocking
|
612
|
+
# mode.
|
613
|
+
#
|
614
|
+
def readpartial: (Integer maxlen, ?String outbuf) -> String
|
433
615
|
|
434
616
|
def reopen: (IO other_IO_or_path) -> IO
|
435
617
|
| (String other_IO_or_path, ?String mode_str) -> IO
|
@@ -508,13 +690,55 @@ class IO < Object
|
|
508
690
|
|
509
691
|
def ungetc: (String arg0) -> NilClass
|
510
692
|
|
511
|
-
|
693
|
+
# Writes the given strings to *ios*. The stream must be opened for writing.
|
694
|
+
# Arguments that are not a string will be converted to a string using `to_s`.
|
695
|
+
# Returns the number of bytes written in total.
|
696
|
+
#
|
697
|
+
# count = $stdout.write("This is", " a test\n")
|
698
|
+
# puts "That was #{count} bytes of data"
|
699
|
+
#
|
700
|
+
# *produces:*
|
701
|
+
#
|
702
|
+
# This is a test
|
703
|
+
# That was 15 bytes of data
|
704
|
+
#
|
705
|
+
def write: (*_ToS string) -> Integer
|
512
706
|
|
707
|
+
# Opens the file, optionally seeks to the given *offset*, then returns *length*
|
708
|
+
# bytes (defaulting to the rest of the file). #binread ensures the file is
|
709
|
+
# closed before returning. The open mode would be `"rb:ASCII-8BIT"`.
|
710
|
+
#
|
711
|
+
# IO.binread("testfile") #=> "This is line one\nThis is line two\nThis is line three\nAnd so on...\n"
|
712
|
+
# IO.binread("testfile", 20) #=> "This is line one\nThi"
|
713
|
+
# IO.binread("testfile", 20, 10) #=> "ne one\nThis is line "
|
714
|
+
#
|
513
715
|
def self.binread: (String name, ?Integer length, ?Integer offset) -> String
|
514
716
|
|
515
|
-
|
717
|
+
# Same as IO.write except opening the file in binary mode and ASCII-8BIT
|
718
|
+
# encoding (`"wb:ASCII-8BIT"`).
|
719
|
+
#
|
720
|
+
def self.binwrite: (String name, _ToS string, ?Integer offset, ?mode: String mode) -> Integer
|
516
721
|
|
517
|
-
|
722
|
+
# IO.copy_stream copies *src* to *dst*. *src* and *dst* is either a filename or
|
723
|
+
# an IO-like object. IO-like object for *src* should have #readpartial or #read
|
724
|
+
# method. IO-like object for *dst* should have #write method. (Specialized
|
725
|
+
# mechanisms, such as sendfile system call, may be used on appropriate
|
726
|
+
# situation.)
|
727
|
+
#
|
728
|
+
# This method returns the number of bytes copied.
|
729
|
+
#
|
730
|
+
# If optional arguments are not given, the start position of the copy is the
|
731
|
+
# beginning of the filename or the current file offset of the IO. The end
|
732
|
+
# position of the copy is the end of file.
|
733
|
+
#
|
734
|
+
# If *copy_length* is given, No more than *copy_length* bytes are copied.
|
735
|
+
#
|
736
|
+
# If *src_offset* is given, it specifies the start position of the copy.
|
737
|
+
#
|
738
|
+
# When *src_offset* is specified and *src* is an IO, IO.copy_stream doesn't move
|
739
|
+
# the current file offset.
|
740
|
+
#
|
741
|
+
def self.copy_stream: ((String | _Reader | _ReaderPartial) src, (String | _Writer) dst, ?Integer copy_length, ?Integer src_offset) -> Integer
|
518
742
|
|
519
743
|
def self.popen: (*untyped args) -> untyped
|
520
744
|
|
@@ -530,7 +754,12 @@ class IO < Object
|
|
530
754
|
|
531
755
|
def self.write: (String name, _ToS arg0, ?Integer offset, ?external_encoding: String external_encoding, ?internal_encoding: String internal_encoding, ?encoding: String encoding, ?textmode: untyped textmode, ?binmode: untyped binmode, ?autoclose: untyped autoclose, ?mode: String mode) -> Integer
|
532
756
|
|
533
|
-
def self.for_fd: (
|
757
|
+
def self.for_fd: (int fd, ?(string | int) mode, **untyped opt) -> instance
|
758
|
+
|
759
|
+
alias self.open self.for_fd
|
760
|
+
|
761
|
+
def self.open: [A] (int fd, ?(string | int) mode, **untyped opt) { (instance) -> A } -> A
|
762
|
+
| ...
|
534
763
|
|
535
764
|
def bytes: () { (Integer arg0) -> untyped } -> self
|
536
765
|
| () -> ::Enumerator[Integer, self]
|