io-like 0.3.1 → 0.4.0.pre1
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 +7 -0
- data/LICENSE +1 -1
- data/NEWS.md +14 -1
- data/README.md +75 -94
- data/lib/io/like.rb +1916 -1314
- data/lib/io/like_helpers/abstract_io.rb +512 -0
- data/lib/io/like_helpers/blocking_io.rb +86 -0
- data/lib/io/like_helpers/buffered_io.rb +555 -0
- data/lib/io/like_helpers/character_io/basic_reader.rb +122 -0
- data/lib/io/like_helpers/character_io/converter_reader.rb +252 -0
- data/lib/io/like_helpers/character_io.rb +529 -0
- data/lib/io/like_helpers/delegated_io.rb +250 -0
- data/lib/io/like_helpers/duplexed_io.rb +259 -0
- data/lib/io/like_helpers/io.rb +21 -0
- data/lib/io/like_helpers/io_wrapper.rb +290 -0
- data/lib/io/like_helpers/pipeline.rb +77 -0
- data/lib/io/like_helpers/ruby_facts.rb +33 -0
- data/lib/io/like_helpers.rb +14 -0
- metadata +107 -224
- data/.yardopts +0 -1
- data/Rakefile +0 -228
- data/ruby.1.8.mspec +0 -7
- data/spec/binmode_spec.rb +0 -29
- data/spec/close_read_spec.rb +0 -64
- data/spec/close_spec.rb +0 -36
- data/spec/close_write_spec.rb +0 -61
- data/spec/closed_spec.rb +0 -16
- data/spec/each_byte_spec.rb +0 -38
- data/spec/each_line_spec.rb +0 -11
- data/spec/each_spec.rb +0 -11
- data/spec/eof_spec.rb +0 -11
- data/spec/fixtures/classes.rb +0 -96
- data/spec/fixtures/gets.txt +0 -9
- data/spec/fixtures/numbered_lines.txt +0 -5
- data/spec/fixtures/one_byte.txt +0 -1
- data/spec/fixtures/paragraphs.txt +0 -7
- data/spec/fixtures/readlines.txt +0 -6
- data/spec/flush_spec.rb +0 -8
- data/spec/getc_spec.rb +0 -44
- data/spec/gets_spec.rb +0 -212
- data/spec/isatty_spec.rb +0 -6
- data/spec/lineno_spec.rb +0 -84
- data/spec/output_spec.rb +0 -47
- data/spec/pos_spec.rb +0 -53
- data/spec/print_spec.rb +0 -97
- data/spec/printf_spec.rb +0 -24
- data/spec/putc_spec.rb +0 -57
- data/spec/puts_spec.rb +0 -99
- data/spec/read_spec.rb +0 -162
- data/spec/readchar_spec.rb +0 -49
- data/spec/readline_spec.rb +0 -60
- data/spec/readlines_spec.rb +0 -140
- data/spec/readpartial_spec.rb +0 -92
- data/spec/rewind_spec.rb +0 -56
- data/spec/seek_spec.rb +0 -72
- data/spec/shared/each.rb +0 -204
- data/spec/shared/eof.rb +0 -116
- data/spec/shared/pos.rb +0 -39
- data/spec/shared/tty.rb +0 -12
- data/spec/shared/write.rb +0 -53
- data/spec/sync_spec.rb +0 -56
- data/spec/sysread_spec.rb +0 -87
- data/spec/sysseek_spec.rb +0 -68
- data/spec/syswrite_spec.rb +0 -60
- data/spec/tell_spec.rb +0 -7
- data/spec/to_io_spec.rb +0 -19
- data/spec/tty_spec.rb +0 -6
- data/spec/ungetc_spec.rb +0 -118
- data/spec/write_spec.rb +0 -61
- data/spec_helper.rb +0 -49
- /data/{LICENSE-rubyspec → rubyspec/LICENSE} +0 -0
@@ -0,0 +1,250 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'io/like_helpers/abstract_io'
|
4
|
+
require 'io/like_helpers/ruby_facts.rb'
|
5
|
+
|
6
|
+
class IO; module LikeHelpers
|
7
|
+
|
8
|
+
##
|
9
|
+
# This class implements {AbstractIO} by delegating most methods to a delegate
|
10
|
+
# stream. Use this class to implement streams that filter or mutate data sent
|
11
|
+
# through them.
|
12
|
+
class DelegatedIO < AbstractIO
|
13
|
+
##
|
14
|
+
# Defines methods for instances of this class that delegate calls to another
|
15
|
+
# object.
|
16
|
+
#
|
17
|
+
# The delegation first calls an assert method to ensure the stream is in the
|
18
|
+
# nessary state to be able to perform the delegation.
|
19
|
+
#
|
20
|
+
# @param methods [Array<Symbol>] a list of methods to delegate
|
21
|
+
# @param to [Symbol] the target object
|
22
|
+
# @param assert [Symbol] the kind of assertion to call (`:open`, `:readable`,
|
23
|
+
# or `:writable`)
|
24
|
+
#
|
25
|
+
# @return [Array<Symbol>] the names of the defined methods
|
26
|
+
private_class_method def self.delegate(*methods, to: :delegate, assert: :open)
|
27
|
+
unless %i{open readable writable}.include?(assert)
|
28
|
+
raise ArgumentError, "Invalid assert: #{assert}"
|
29
|
+
end
|
30
|
+
|
31
|
+
location = caller_locations(1, 1).first
|
32
|
+
file, line = location.path, location.lineno
|
33
|
+
|
34
|
+
methods.map do |method|
|
35
|
+
args = if /[^\]]=$/.match?(method)
|
36
|
+
'arg'
|
37
|
+
else
|
38
|
+
'*args, **kwargs, &b'
|
39
|
+
end
|
40
|
+
|
41
|
+
method_def = <<-EOM
|
42
|
+
def #{method}(#{args})
|
43
|
+
assert_#{assert}
|
44
|
+
#{to}.#{method}(#{args})
|
45
|
+
end
|
46
|
+
EOM
|
47
|
+
module_eval(method_def, file, line)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# @param delegate [LikeHelpers::AbstractIO] a readable and/or writable stream
|
53
|
+
#
|
54
|
+
# @return [Proc] a proc to be used as a fializer that calls #close on
|
55
|
+
# `delegate` when an instance of this class it garbage collected
|
56
|
+
def self.create_finalizer(delegate)
|
57
|
+
proc { |id| delegate.close }
|
58
|
+
end
|
59
|
+
|
60
|
+
##
|
61
|
+
# Creates a new intance of this class.
|
62
|
+
#
|
63
|
+
# @param delegate [LikeHelpers::AbstractIO] a readable and/or writable stream
|
64
|
+
# @param autoclose [Boolean] when `true` close the delegate when this stream
|
65
|
+
# is closed
|
66
|
+
def initialize(delegate, autoclose: true)
|
67
|
+
raise ArgumentError, 'delegate cannot be nil' if delegate.nil?
|
68
|
+
super()
|
69
|
+
|
70
|
+
@delegate = delegate
|
71
|
+
self.autoclose = autoclose
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Sets whether or not to close the delegate when {#close} is called.
|
76
|
+
#
|
77
|
+
# @param autoclose [Boolean] delegate will be closed when `true`
|
78
|
+
def autoclose=(autoclose)
|
79
|
+
assert_open
|
80
|
+
@autoclose = autoclose ? true : false
|
81
|
+
@autoclose ? enable_finalizer : disable_finalizer
|
82
|
+
autoclose
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Returns `true` if the delegate would be closed when {#close} is called
|
87
|
+
# and `false` otherwise.
|
88
|
+
#
|
89
|
+
# @return [Boolean]
|
90
|
+
def autoclose?
|
91
|
+
assert_open
|
92
|
+
@autoclose
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Closes this stream.
|
97
|
+
#
|
98
|
+
# The delegate is closed if autoclose is enabled for the stream.
|
99
|
+
#
|
100
|
+
# @return [nil] on success
|
101
|
+
# @return [:wait_readable, :wait_writable] if the stream is non-blocking and
|
102
|
+
# the operation would block
|
103
|
+
def close
|
104
|
+
return nil if closed?
|
105
|
+
|
106
|
+
begin
|
107
|
+
result = delegate.close if @autoclose
|
108
|
+
ensure
|
109
|
+
# Complete the closing process if the delegate closed normally or an
|
110
|
+
# exception was raised.
|
111
|
+
unless Symbol === result
|
112
|
+
disable_finalizer
|
113
|
+
result = super
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
##
|
121
|
+
# @return [String] a string representation of this object
|
122
|
+
def inspect
|
123
|
+
"<#{self.class}:#{delegate.inspect}#{' (closed)' if closed?}>"
|
124
|
+
end
|
125
|
+
|
126
|
+
##
|
127
|
+
# Returns `true` if the stream is readable and `false` otherwise.
|
128
|
+
#
|
129
|
+
# @return [Boolean]
|
130
|
+
def readable?
|
131
|
+
return false if closed?
|
132
|
+
return @readable if defined?(@readable) && ! @readable.nil?
|
133
|
+
@readable = delegate.readable?
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Returns `true` if the stream is writable and `false` otherwise.
|
138
|
+
#
|
139
|
+
# @return [Boolean]
|
140
|
+
def writable?
|
141
|
+
return false if closed?
|
142
|
+
return @writable if defined?(@writable) && ! @writable.nil?
|
143
|
+
@writable = delegate.writable?
|
144
|
+
end
|
145
|
+
|
146
|
+
##
|
147
|
+
# @method close_on_exec=(value)
|
148
|
+
# Calls `delegate.close_on_exec = value` after asserting that the stream is
|
149
|
+
# open.
|
150
|
+
delegate :close_on_exec=
|
151
|
+
|
152
|
+
##
|
153
|
+
# @method nonblock=(value)
|
154
|
+
# Calls `delegate.nonblock = value` after asserting that the stream is open.
|
155
|
+
delegate :nonblock=
|
156
|
+
|
157
|
+
# @!macro [attach] delegate_open
|
158
|
+
# @method $1(*args, **kwargs, &b)
|
159
|
+
# Calls `delegate.$1(*args, **kwargs, &b)` after asserting that the stream is open.
|
160
|
+
delegate :advise
|
161
|
+
delegate :close_on_exec?
|
162
|
+
delegate :fcntl
|
163
|
+
delegate :fdatasync
|
164
|
+
delegate :fileno
|
165
|
+
delegate :fsync
|
166
|
+
delegate :ioctl
|
167
|
+
delegate :nonblock?
|
168
|
+
delegate :path
|
169
|
+
delegate :pid
|
170
|
+
delegate :ready?
|
171
|
+
delegate :seek
|
172
|
+
delegate :stat
|
173
|
+
delegate :to_io
|
174
|
+
delegate :tty?
|
175
|
+
delegate :wait
|
176
|
+
|
177
|
+
##
|
178
|
+
# @method pread(*args, **kwargs, &b)
|
179
|
+
# Calls `delegate.read(*args, **kwargs, &b)` after asserting that the stream is readable.
|
180
|
+
delegate :pread, assert: :readable
|
181
|
+
|
182
|
+
##
|
183
|
+
# @method read(*args, **kwargs, &b)
|
184
|
+
# Calls `delegate.read(*args, **kwargs, &b)` after asserting that the stream is readable.
|
185
|
+
delegate :read, assert: :readable
|
186
|
+
|
187
|
+
##
|
188
|
+
# @method nread(*args, **kwargs, &b)
|
189
|
+
# Calls `delegate.nread(*args, **kwargs, &b)` after asserting that the stream is readable.
|
190
|
+
delegate :nread, assert: :readable
|
191
|
+
|
192
|
+
##
|
193
|
+
# @method pwrite(*args, **kwargs, &b)
|
194
|
+
# Calls `delegate.write(*args, **kwargs, &b)` after asserting that the stream is writable.
|
195
|
+
delegate :pwrite, assert: :writable
|
196
|
+
|
197
|
+
##
|
198
|
+
# @method write(*args, **kwargs, &b)
|
199
|
+
# Calls `delegate.write(*args, **kwargs, &b)` after asserting that the stream is writable.
|
200
|
+
delegate :write, assert: :writable
|
201
|
+
|
202
|
+
protected
|
203
|
+
|
204
|
+
##
|
205
|
+
# The delegate that receives delegated method calls.
|
206
|
+
attr_reader :delegate
|
207
|
+
|
208
|
+
private
|
209
|
+
|
210
|
+
##
|
211
|
+
# Removes all finalizers for this object.
|
212
|
+
#
|
213
|
+
# @return [nil]
|
214
|
+
def disable_finalizer
|
215
|
+
ObjectSpace.undefine_finalizer(self)
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
|
219
|
+
##
|
220
|
+
# Defines a finalizer for this object.
|
221
|
+
#
|
222
|
+
# @return [nil]
|
223
|
+
def enable_finalizer
|
224
|
+
ObjectSpace.define_finalizer(self, self.class.create_finalizer(delegate))
|
225
|
+
nil
|
226
|
+
end
|
227
|
+
|
228
|
+
##
|
229
|
+
# Creates an instance of this class that copies state from `other`.
|
230
|
+
#
|
231
|
+
# The delegate of `other` is `dup`'d.
|
232
|
+
#
|
233
|
+
# @param other [DelegatedIO] the instance to copy
|
234
|
+
#
|
235
|
+
# @return [nil]
|
236
|
+
#
|
237
|
+
# @raise [IOError] if `other` is closed
|
238
|
+
def initialize_copy(other)
|
239
|
+
super
|
240
|
+
|
241
|
+
disable_finalizer
|
242
|
+
@delegate = @delegate.dup
|
243
|
+
self.autoclose = true
|
244
|
+
|
245
|
+
nil
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end; end
|
249
|
+
|
250
|
+
# vim: ts=2 sw=2 et
|
@@ -0,0 +1,259 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'io/like_helpers/delegated_io'
|
4
|
+
|
5
|
+
class IO; module LikeHelpers
|
6
|
+
|
7
|
+
##
|
8
|
+
# This class encapsulates 2 streams (one readable, one writable) into a single
|
9
|
+
# stream. It is primarily intended to serve as an ancestor for {IO::Like} and
|
10
|
+
# should not be used directly.
|
11
|
+
class DuplexedIO < DelegatedIO
|
12
|
+
##
|
13
|
+
# Creates a new intance of this class.
|
14
|
+
#
|
15
|
+
# @param delegate_r [LikeHelpers::AbstractIO] a readable stream
|
16
|
+
# @param delegate_w [LikeHelpers::AbstractIO] a writable stream
|
17
|
+
# @param autoclose [Boolean] when `true` close the delegate when this stream
|
18
|
+
# is closed
|
19
|
+
def initialize(delegate_r, delegate_w = delegate_r, autoclose: true)
|
20
|
+
raise ArgumentError, 'delegate_r cannot be nil' if delegate_r.nil?
|
21
|
+
raise ArgumentError, 'delegate_w cannot be nil' if delegate_w.nil?
|
22
|
+
|
23
|
+
@delegate_w = delegate_w
|
24
|
+
@closed_write = false
|
25
|
+
|
26
|
+
super(delegate_r, autoclose: autoclose)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Closes this stream.
|
31
|
+
#
|
32
|
+
# The delegates are closed if autoclose is enabled for the stream.
|
33
|
+
#
|
34
|
+
# @return [nil] on success
|
35
|
+
# @return [:wait_readable, :wait_writable] if the stream is non-blocking and
|
36
|
+
# the operation would block
|
37
|
+
def close
|
38
|
+
return nil if closed?
|
39
|
+
|
40
|
+
begin
|
41
|
+
result = close_write
|
42
|
+
ensure
|
43
|
+
# Complete the closing process if the writable delegate closed normally or
|
44
|
+
# an exception was raised.
|
45
|
+
result = close_read unless Symbol === result
|
46
|
+
end
|
47
|
+
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
##
|
52
|
+
# Returns `true` if the readable delegate is closed and `false` otherwise.
|
53
|
+
#
|
54
|
+
# @return [Boolean]
|
55
|
+
alias_method :closed_read?, :closed?
|
56
|
+
|
57
|
+
##
|
58
|
+
# Returns `true` if both delegates are closed and `false` otherwise.
|
59
|
+
#
|
60
|
+
# @return [Boolean]
|
61
|
+
def closed?
|
62
|
+
closed_read? && closed_write?
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
66
|
+
# Returns `true` if the writable delegate is closed and `false` otherwise.
|
67
|
+
#
|
68
|
+
# @return [Boolean]
|
69
|
+
def closed_write?
|
70
|
+
@closed_write
|
71
|
+
end
|
72
|
+
|
73
|
+
##
|
74
|
+
# Closes the readable delegate.
|
75
|
+
#
|
76
|
+
# @return [nil] on success
|
77
|
+
# @return [:wait_readable, :wait_writable] if the stream is non-blocking and
|
78
|
+
# the operation would block
|
79
|
+
def close_read
|
80
|
+
return nil if closed_read?
|
81
|
+
|
82
|
+
begin
|
83
|
+
result = delegate_r.close if @autoclose
|
84
|
+
ensure
|
85
|
+
# Complete the closing process if the delegate closed normally or an
|
86
|
+
# exception was raised.
|
87
|
+
unless Symbol === result
|
88
|
+
@closed_write = true unless duplexed?
|
89
|
+
@closed = true
|
90
|
+
@delegate = @delegate_w
|
91
|
+
disable_finalizer
|
92
|
+
enable_finalizer if @autoclose && ! closed?
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
result
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Closes the writable delegate.
|
101
|
+
#
|
102
|
+
# @return [nil] on success
|
103
|
+
# @return [:wait_readable, :wait_writable] if the stream is non-blocking and
|
104
|
+
# the operation would block
|
105
|
+
def close_write
|
106
|
+
return nil if closed_write?
|
107
|
+
|
108
|
+
begin
|
109
|
+
result = delegate_w.close if @autoclose
|
110
|
+
ensure
|
111
|
+
# Complete the closing process if the delegate closed normally or an
|
112
|
+
# exception was raised.
|
113
|
+
unless Symbol === result
|
114
|
+
@closed = true unless duplexed?
|
115
|
+
@closed_write = true
|
116
|
+
@delegate_w = @delegate
|
117
|
+
disable_finalizer
|
118
|
+
enable_finalizer if @autoclose && ! closed?
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
result
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Sets the close-on-exec flag for the underlying file descriptors of the
|
127
|
+
# delegates.
|
128
|
+
#
|
129
|
+
# Note that setting this to `false` can lead to file descriptor leaks in
|
130
|
+
# multithreaded applications that fork and exec or use the `system` method.
|
131
|
+
#
|
132
|
+
# @return [Boolean]
|
133
|
+
def close_on_exec=(close_on_exec)
|
134
|
+
return super unless duplexed?
|
135
|
+
|
136
|
+
assert_open
|
137
|
+
|
138
|
+
delegate_w.close_on_exec = delegate_r.close_on_exec = close_on_exec
|
139
|
+
|
140
|
+
close_on_exec
|
141
|
+
end
|
142
|
+
|
143
|
+
##
|
144
|
+
# @return [String] a string representation of this object
|
145
|
+
def inspect
|
146
|
+
return super unless duplexed?
|
147
|
+
"<#{self.class}:#{delegate_r.inspect}, #{delegate_w.inspect}>"
|
148
|
+
end
|
149
|
+
|
150
|
+
##
|
151
|
+
# Sets the blocking mode for the stream.
|
152
|
+
#
|
153
|
+
# @return [Boolean]
|
154
|
+
def nonblock=(nonblock)
|
155
|
+
return super unless duplexed?
|
156
|
+
|
157
|
+
assert_open
|
158
|
+
|
159
|
+
delegate_w.nonblock = delegate_r.nonblock = nonblock
|
160
|
+
|
161
|
+
nonblock
|
162
|
+
end
|
163
|
+
|
164
|
+
##
|
165
|
+
# @method pwrite(*args, **kwargs, &b)
|
166
|
+
# Calls `delegate_w.write(*args, **kwargs, &b)` after asserting that the stream is writable.
|
167
|
+
delegate :pwrite, to: :delegate_w, assert: :writable
|
168
|
+
|
169
|
+
##
|
170
|
+
# Returns `true` if the stream is readable and `false` otherwise.
|
171
|
+
#
|
172
|
+
# @return [Boolean]
|
173
|
+
def readable?
|
174
|
+
return false if closed_read?
|
175
|
+
return @readable if defined?(@readable) && ! @readable.nil?
|
176
|
+
@readable = delegate_r.readable?
|
177
|
+
end
|
178
|
+
|
179
|
+
##
|
180
|
+
# @method write(*args, **kwargs, &b)
|
181
|
+
# Calls `delegate_w.write(*args, **kwargs, &b)` after asserting that the stream is writable.
|
182
|
+
delegate :write, to: :delegate_w, assert: :writable
|
183
|
+
|
184
|
+
##
|
185
|
+
# Returns `true` if the stream is writable and `false` otherwise.
|
186
|
+
#
|
187
|
+
# @return [Boolean]
|
188
|
+
def writable?
|
189
|
+
return false if closed_write?
|
190
|
+
return @writable if defined?(@writable) && ! @writable.nil?
|
191
|
+
@writable = delegate_w.writable?
|
192
|
+
end
|
193
|
+
|
194
|
+
protected
|
195
|
+
|
196
|
+
##
|
197
|
+
# Returns `true` if the stream is duplexed and `false` otherwise.
|
198
|
+
#
|
199
|
+
# Note that a duplexed stream can become non-duplexed if one of the delegates
|
200
|
+
# is closed via {#close_read} or {#close_write}.
|
201
|
+
#
|
202
|
+
# @return [Boolean]
|
203
|
+
def duplexed?
|
204
|
+
delegate_r != delegate_w
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
##
|
210
|
+
# Defines a finalizer for this object.
|
211
|
+
#
|
212
|
+
# @return [nil]
|
213
|
+
def enable_finalizer
|
214
|
+
if duplexed?
|
215
|
+
ObjectSpace.define_finalizer(
|
216
|
+
self, self.class.create_finalizer(delegate_w)
|
217
|
+
)
|
218
|
+
end
|
219
|
+
super
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Creates an instance of this class that copies state from `other`.
|
224
|
+
#
|
225
|
+
# The delegates of `other` are `dup`'d.
|
226
|
+
#
|
227
|
+
# @param other [DuplexedIO] the instance to copy
|
228
|
+
#
|
229
|
+
# @return [nil]
|
230
|
+
#
|
231
|
+
# @raise [IOError] if `other` is closed
|
232
|
+
def initialize_copy(other)
|
233
|
+
super
|
234
|
+
|
235
|
+
disable_finalizer
|
236
|
+
begin
|
237
|
+
@delegate_w = other.duplexed? ? @delegate_w.dup : @delegate
|
238
|
+
self.autoclose = true
|
239
|
+
rescue
|
240
|
+
delegate_r.close rescue nil
|
241
|
+
raise
|
242
|
+
end
|
243
|
+
|
244
|
+
nil
|
245
|
+
end
|
246
|
+
|
247
|
+
##
|
248
|
+
# The writable delegate.
|
249
|
+
attr_reader :delegate_w
|
250
|
+
|
251
|
+
##
|
252
|
+
# @!attribute [r] __ignore__
|
253
|
+
# @overload delegate_r
|
254
|
+
# The readable delegate. Aliases {#delegate}.
|
255
|
+
alias_method :delegate_r, :delegate
|
256
|
+
end
|
257
|
+
end; end
|
258
|
+
|
259
|
+
# vim: ts=2 sw=2 et
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class IO
|
4
|
+
unless const_defined?(:PRIORITY)
|
5
|
+
##
|
6
|
+
# Defined only if IO::PRIORITY is not defined.
|
7
|
+
PRIORITY = 2
|
8
|
+
end
|
9
|
+
|
10
|
+
unless const_defined?(:READABLE)
|
11
|
+
##
|
12
|
+
# Defined only if IO::READABLE is not defined.
|
13
|
+
READABLE = 1
|
14
|
+
end
|
15
|
+
|
16
|
+
unless const_defined?(:WRITABLE)
|
17
|
+
##
|
18
|
+
# Defined only if IO::WRITABLE is not defined.
|
19
|
+
WRITABLE = 4
|
20
|
+
end
|
21
|
+
end
|