added input_stack support to Pry

input_stack allows Pry instances to seemlessly continue reading input from other input objects on the stack when the current object generates EOF
Useful when you need to temporarily divert reading to another object and then switch back to another object
This commit is contained in:
John Mair 2011-09-15 21:08:05 +12:00
parent f89f31ff49
commit 5a274b26df
4 changed files with 43 additions and 6 deletions

View File

@ -37,6 +37,13 @@ class Pry
# :after_session => proc { puts "goodbye" } # :after_session => proc { puts "goodbye" }
attr_accessor :hooks attr_accessor :hooks
# Get/Set the stack of input objects that a Pry instance switches
# to when its current input object encounters EOF.
# @return [Array] The array of input objects.
# @example
# Pry.config.input_stack = [StringIO.new("puts 'hello world'\nexit")]
attr_accessor :input_stack
# Get the array of Procs to be used for the prompts by default by # Get the array of Procs to be used for the prompts by default by
# all Pry instances. # all Pry instances.
# @return [Array<Proc>] The array of Procs to be used for the # @return [Array<Proc>] The array of Procs to be used for the

View File

@ -51,7 +51,7 @@ class Pry
def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins def_delegators :@plugin_manager, :plugins, :load_plugins, :locate_plugins
delegate_accessors :@config, :input, :output, :commands, :prompt, :print, :exception_handler, delegate_accessors :@config, :input, :output, :commands, :prompt, :print, :exception_handler,
:hooks, :color, :pager, :editor, :memory_size :hooks, :color, :pager, :editor, :memory_size, :input_stack
end end
# Load the rc files given in the `Pry::RC_FILES` array. # Load the rc files given in the `Pry::RC_FILES` array.
@ -95,12 +95,11 @@ class Pry
new(options).repl(target) new(options).repl(target)
end end
# A version of `Pry.view` that clips the output to `max_length` chars. # An inspector that clips the output to `max_length` chars.
# In case of > `max_length` chars the `#<Object...> notation is used. # In case of > `max_length` chars the `#<Object...> notation is used.
# @param obj The object to view. # @param obj The object to view.
# @param max_length The maximum number of chars before clipping occurs. # @param max_length The maximum number of chars before clipping occurs.
# @return [String] The string representation of `obj`. # @return [String] The string representation of `obj`.
#
def self.view_clip(obj, max_length = 60) def self.view_clip(obj, max_length = 60)
if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max_length if obj.kind_of?(Module) && obj.name.to_s != "" && obj.name.to_s.length <= max_length
obj.name.to_s obj.name.to_s
@ -184,6 +183,7 @@ class Pry
config.exception_handler = DEFAULT_EXCEPTION_HANDLER config.exception_handler = DEFAULT_EXCEPTION_HANDLER
config.exception_window_size = 5 config.exception_window_size = 5
config.hooks = DEFAULT_HOOKS config.hooks = DEFAULT_HOOKS
config.input_stack = []
config.color = true config.color = true
config.pager = true config.pager = true
config.editor = default_editor_for_platform config.editor = default_editor_for_platform

View File

@ -8,6 +8,8 @@ class Pry
attr_accessor :print attr_accessor :print
attr_accessor :exception_handler attr_accessor :exception_handler
attr_accessor :hooks attr_accessor :hooks
attr_accessor :input_stack
attr_accessor :custom_completions attr_accessor :custom_completions
attr_accessor :binding_stack attr_accessor :binding_stack
@ -20,6 +22,7 @@ class Pry
attr_reader :input_array attr_reader :input_array
attr_reader :output_array attr_reader :output_array
# Create a new `Pry` object. # Create a new `Pry` object.
# @param [Hash] options The optional configuration parameters. # @param [Hash] options The optional configuration parameters.
# @option options [#readline] :input The object to use for input. # @option options [#readline] :input The object to use for input.
@ -45,7 +48,7 @@ class Pry
attributes = [ attributes = [
:input, :output, :commands, :print, :input, :output, :commands, :print,
:exception_handler, :hooks, :custom_completions, :exception_handler, :hooks, :custom_completions,
:prompt, :memory_size :prompt, :memory_size, :input_stack
] ]
attributes.each do |attribute| attributes.each do |attribute|
@ -140,7 +143,7 @@ class Pry
exec_hook :before_session, output, target, self exec_hook :before_session, output, target, self
initialize_special_locals(target) initialize_special_locals(target)
@input_array << nil # add empty input so inp and out match @input_array << nil # add empty input so _in_ and _out_ match
Pry.active_sessions += 1 Pry.active_sessions += 1
binding_stack.push target binding_stack.push target
@ -400,7 +403,7 @@ class Pry
end end
rescue EOFError rescue EOFError
self.input = Pry.input self.input = input_stack.empty? ? Pry.config.input : input_stack.pop
"" ""
end end
end end

27
test/test_input_stack.rb Normal file
View File

@ -0,0 +1,27 @@
require 'helper'
describe "Pry#input_stack" do
it 'should accept :input_stack as a config option' do
stack = [StringIO.new("test")]
Pry.new(:input_stack => stack).input_stack.should == stack
end
it 'should use defaults from Pry.config' do
Pry.config.input_stack = [StringIO.new("exit")]
Pry.new.input_stack.should == Pry.config.input_stack
Pry.config.input_stack = []
end
it 'should read from all input objects on stack and exit session' do
stack = [b = StringIO.new(":cloister\nexit\n"), c = StringIO.new(":baron\n")]
instance = Pry.new(:input => StringIO.new(":alex\n"),
:output => str_output = StringIO.new,
:input_stack => stack)
instance.repl
str_output.string.should =~ /:alex/
str_output.string.should =~ /:baron/
str_output.string.should =~ /:cloister/
end
end