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