Class: IO::LikeHelpers::DuplexedIO

Inherits:
DelegatedIO show all
Defined in:
lib/io/like_helpers/duplexed_io.rb

Overview

This class encapsulates 2 streams (one readable, one writable) into a single stream. It is primarily intended to serve as an ancestor for IO::Like and should not be used directly.

Direct Known Subclasses

IO::Like

Instance Method Summary collapse

Methods inherited from DelegatedIO

#advise, #autoclose=, #autoclose?, #close_on_exec?, create_finalizer, #fcntl, #fdatasync, #fileno, #fsync, #ioctl, #nonblock?, #nread, #path, #pid, #pread, #read, #ready?, #seek, #stat, #to_io, #tty?, #wait

Methods inherited from AbstractIO

#advise, #close_on_exec?, #fcntl, #fdatasync, #fileno, #fsync, #ioctl, #nonblock, #nonblock?, #nread, open, #path, #pid, #pread, #read, #ready?, #seek, #stat, #to_io, #tty?, #wait

Constructor Details

#initialize(delegate_r, delegate_w = delegate_r, autoclose: true) ⇒ DuplexedIO

Creates a new intance of this class.

Parameters:

  • delegate_r (LikeHelpers::AbstractIO)

    a readable stream

  • delegate_w (LikeHelpers::AbstractIO) (defaults to: delegate_r)

    a writable stream

  • autoclose (Boolean) (defaults to: true)

    when ‘true` close the delegate when this stream is closed

Raises:

  • (ArgumentError)


19
20
21
22
23
24
25
26
27
# File 'lib/io/like_helpers/duplexed_io.rb', line 19

def initialize(delegate_r, delegate_w = delegate_r, autoclose: true)
  raise ArgumentError, 'delegate_r cannot be nil' if delegate_r.nil?
  raise ArgumentError, 'delegate_w cannot be nil' if delegate_w.nil?

  @delegate_w = delegate_w
  @closed_write = false

  super(delegate_r, autoclose: autoclose)
end

Instance Method Details

#closenil, ...

Closes this stream.

The delegates are closed if autoclose is enabled for the stream.

Returns:

  • (nil)

    on success

  • (:wait_readable, :wait_writable)

    if the stream is non-blocking and the operation would block



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/io/like_helpers/duplexed_io.rb', line 37

def close
  return nil if closed?

  begin
    result = close_write
  ensure
    # Complete the closing process if the writable delegate closed normally or
    # an exception was raised.
    result = close_read unless Symbol === result
  end

  result
end

#close_on_exec=(close_on_exec) ⇒ Boolean

Sets the close-on-exec flag for the underlying file descriptors of the delegates.

Note that setting this to ‘false` can lead to file descriptor leaks in multithreaded applications that fork and exec or use the `system` method.

Returns:

  • (Boolean)


133
134
135
136
137
138
139
140
141
# File 'lib/io/like_helpers/duplexed_io.rb', line 133

def close_on_exec=(close_on_exec)
  return super unless duplexed?

  assert_open

  delegate_w.close_on_exec = delegate_r.close_on_exec = close_on_exec

  close_on_exec
end

#close_readnil, ...

Closes the readable delegate.

Returns:

  • (nil)

    on success

  • (:wait_readable, :wait_writable)

    if the stream is non-blocking and the operation would block



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/io/like_helpers/duplexed_io.rb', line 79

def close_read
  return nil if closed_read?

  begin
    result = delegate_r.close if @autoclose
  ensure
    # Complete the closing process if the delegate closed normally or an
    # exception was raised.
    unless Symbol === result
      @closed_write = true unless duplexed?
      @closed = true
      @delegate = @delegate_w
      disable_finalizer
      enable_finalizer if @autoclose && ! closed?
    end
  end

  result
end

#close_writenil, ...

Closes the writable delegate.

Returns:

  • (nil)

    on success

  • (:wait_readable, :wait_writable)

    if the stream is non-blocking and the operation would block



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/io/like_helpers/duplexed_io.rb', line 105

def close_write
  return nil if closed_write?

  begin
    result = delegate_w.close if @autoclose
  ensure
    # Complete the closing process if the delegate closed normally or an
    # exception was raised.
    unless Symbol === result
      @closed = true unless duplexed?
      @closed_write = true
      @delegate_w = @delegate
      disable_finalizer
      enable_finalizer if @autoclose && ! closed?
    end
  end

  result
end

#closed?Boolean

Returns ‘true` if both delegates are closed and `false` otherwise.

Returns:

  • (Boolean)


61
62
63
# File 'lib/io/like_helpers/duplexed_io.rb', line 61

def closed?
  closed_read? && closed_write?
end

#closed_read?Boolean

Returns ‘true` if the readable delegate is closed and `false` otherwise.

Returns:

  • (Boolean)


55
# File 'lib/io/like_helpers/duplexed_io.rb', line 55

alias_method :closed_read?, :closed?

#closed_write?Boolean

Returns ‘true` if the writable delegate is closed and `false` otherwise.

Returns:

  • (Boolean)


69
70
71
# File 'lib/io/like_helpers/duplexed_io.rb', line 69

def closed_write?
  @closed_write
end

#inspectString

Returns a string representation of this object.

Returns:

  • (String)

    a string representation of this object



145
146
147
148
# File 'lib/io/like_helpers/duplexed_io.rb', line 145

def inspect
  return super unless duplexed?
  "<#{self.class}:#{delegate_r.inspect}, #{delegate_w.inspect}>"
end

#nonblock=(nonblock) ⇒ Boolean

Sets the blocking mode for the stream.

Returns:

  • (Boolean)


154
155
156
157
158
159
160
161
162
# File 'lib/io/like_helpers/duplexed_io.rb', line 154

def nonblock=(nonblock)
  return super unless duplexed?

  assert_open

  delegate_w.nonblock = delegate_r.nonblock = nonblock

  nonblock
end

#pwrite(*args, **kwargs, &b) ⇒ Object

Calls ‘delegate_w.write(*args, **kwargs, &b)` after asserting that the stream is writable.



167
# File 'lib/io/like_helpers/duplexed_io.rb', line 167

delegate :pwrite, to: :delegate_w, assert: :writable

#readable?Boolean

Returns ‘true` if the stream is readable and `false` otherwise.

Returns:

  • (Boolean)


173
174
175
176
177
# File 'lib/io/like_helpers/duplexed_io.rb', line 173

def readable?
  return false if closed_read?
  return @readable if defined?(@readable) && ! @readable.nil?
  @readable = delegate_r.readable?
end

#writable?Boolean

Returns ‘true` if the stream is writable and `false` otherwise.

Returns:

  • (Boolean)


188
189
190
191
192
# File 'lib/io/like_helpers/duplexed_io.rb', line 188

def writable?
  return false if closed_write?
  return @writable if defined?(@writable) && ! @writable.nil?
  @writable = delegate_w.writable?
end

#write(*args, **kwargs, &b) ⇒ Object

Calls ‘delegate_w.write(*args, **kwargs, &b)` after asserting that the stream is writable.



182
# File 'lib/io/like_helpers/duplexed_io.rb', line 182

delegate :write, to: :delegate_w, assert: :writable