Class: Expectr::Lambda
- Inherits:
-
Object
- Object
- Expectr::Lambda
- Includes:
- Interface
- Defined in:
- lib/expectr/lambda.rb,
lib/expectr/errstr.rb
Overview
Internal: The Expectr::Lambda Class contains the interface to interacting with ruby objects transparently via lambdas in a manner consistent with other Expectr interfaces.
All methods with the prefix ‘interface_’ in their name will return a Proc designed to be defined as an instance method in the primary Expectr object. These methods will all be documented as if they are the Proc in question.
Defined Under Namespace
Modules: Errstr
Instance Attribute Summary collapse
-
#reader ⇒ Object
readonly
Returns the value of attribute reader.
-
#writer ⇒ Object
readonly
Returns the value of attribute writer.
Class Method Summary collapse
-
.spawn(reader, writer, args = {}) ⇒ Object
Public: Present a streamlined interface to create a new Expectr instance.
Instance Method Summary collapse
-
#initialize(reader, writer) ⇒ Lambda
constructor
Public: Initialize a new Expectr::Lambda object.
-
#interface_interact_thread ⇒ Object
Public: Create a Thread containing the loop which is responsible for handling input from the user in interact mode.
-
#interface_output_loop ⇒ Object
Internal: Call the writer lambda, reading the output, forcing UTF-8 and appending to the internal buffer and printing to $stdout if appropriate.
-
#interface_prepare_interact_environment ⇒ Object
Public: Prepare the operating environment for interact mode, set the interact flag to true.
-
#interface_send ⇒ Object
Public: Send input to the active child process.
Methods included from Interface
#init_instance, #interface_prepare_interact_interface, #interface_restore_environment
Constructor Details
#initialize(reader, writer) ⇒ Lambda
Public: Initialize a new Expectr::Lambda object.
reader - Lambda which is meant to be interacted with as if it were
analogous to STDIN for a child process.
writer - Lambda which is meant to be interacted with as if it were
analogous to STDOUT for a child process.
Raises TypeError if arguments aren’t of type Proc.
25 26 27 28 29 30 31 32 |
# File 'lib/expectr/lambda.rb', line 25 def initialize(reader, writer) unless reader.kind_of?(Proc) && writer.kind_of?(Proc) raise(TypeError, Errstr::PROC_EXPECTED) end @reader = reader @writer = writer end |
Instance Attribute Details
#reader ⇒ Object (readonly)
Returns the value of attribute reader.
14 15 16 |
# File 'lib/expectr/lambda.rb', line 14 def reader @reader end |
#writer ⇒ Object (readonly)
Returns the value of attribute writer.
15 16 17 |
# File 'lib/expectr/lambda.rb', line 15 def writer @writer end |
Class Method Details
.spawn(reader, writer, args = {}) ⇒ Object
Public: Present a streamlined interface to create a new Expectr instance.
reader - Lambda which is meant to be interacted with as if it were
analogous to STDIN for a child process.
writer - Lambda which is meant to be interacted with as if it were
analogous to STDOUT for a child process.
args - A Hash used to specify options for the new object, per
Expectr#initialize.
Returns a new Expectr object
44 45 46 47 48 49 |
# File 'lib/expectr/lambda.rb', line 44 def self.spawn(reader, writer, args = {}) args[:interface] = :lambda args[:reader] = reader args[:writer] = writer Expectr.new('', args) end |
Instance Method Details
#interface_interact_thread ⇒ Object
Public: Create a Thread containing the loop which is responsible for handling input from the user in interact mode.
Returns a Thread containing the running loop.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/expectr/lambda.rb', line 93 def interface_interact_thread -> { Thread.new do env = prepare_interact_environment input = '' while @interact if select([$stdin], nil, nil, 1) c = $stdin.getc.chr send c unless c.nil? end end restore_environment(env) end } end |
#interface_output_loop ⇒ Object
Internal: Call the writer lambda, reading the output, forcing UTF-8 and appending to the internal buffer and printing to $stdout if appropriate.
Returns nothing.
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/expectr/lambda.rb', line 115 def interface_output_loop -> { buf = '' loop do buf.clear begin buf << @writer.call.to_s rescue Errno::EIO # Lambda is signaling that execution should end. return end process_output(buf) end } end |
#interface_prepare_interact_environment ⇒ Object
Public: Prepare the operating environment for interact mode, set the interact flag to true.
Returns a Hash containing old signal handlers and tty parameters.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/expectr/lambda.rb', line 66 def interface_prepare_interact_environment -> { env = {sig: {}} # Save old tty settings and set up the new environment env[:tty] = `stty -g` `stty -icanon min 1 time 0 -echo` # SIGINT should be sent to the child as \C-c env[:sig]['INT'] = trap 'INT' do send "\C-c" end # SIGTSTP should be sent to the process as \C-z env[:sig]['TSTP'] = trap 'TSTP' do send "\C-z" end @interact = true env } end |
#interface_send ⇒ Object
Public: Send input to the active child process.
args - Arguments to pass to the reader interface.
Returns nothing.
56 57 58 59 60 |
# File 'lib/expectr/lambda.rb', line 56 def interface_send ->(args) { @reader.call(*args) } end |