mirror of
https://github.com/pry/pry.git
synced 2022-11-09 12:35:05 -05:00
made it so commands (with :keep_retval => true) can now return nil as a legitimate return value. Created a new 'void' value to use instead when indicating no return value. also updated tests.
'void' method now available to commands, commands must return this when they do not want their result displayed when they use :keep_retval => true. void just maps to a random object Pry::CommandContext::VOID_VALUE.
This commit is contained in:
parent
fc15407150
commit
a04e56012a
9 changed files with 57 additions and 10 deletions
|
@ -20,6 +20,7 @@
|
|||
* ^C no longer captured
|
||||
* got rid of Pry.active_instance, Pry.last_exception and friends.
|
||||
* also special locals now shared among bindings in a pry instance (i.e _ex_ (and friends) re-injected into new binding entered with 'cd')
|
||||
* renamed inp and out to _in_ and _out_ (to avoid collisions with actual locals in debugging scope)
|
||||
* added third parameter to prompts, the pry instance itself (_pry) see https://github.com/pry/pry/issues/233 for why it's important
|
||||
* cd behaviour when no args performs the same as `cd /`
|
||||
|
||||
|
|
|
@ -2,6 +2,13 @@ class Pry
|
|||
# Command contexts are the objects runing each command.
|
||||
# Helper modules can be mixed into this class.
|
||||
class CommandContext
|
||||
|
||||
# represents a void return value for a command
|
||||
VOID_VALUE = Object.new
|
||||
|
||||
# give it a nice inspect
|
||||
def VOID_VALUE.inspect() "void" end
|
||||
|
||||
attr_accessor :output
|
||||
attr_accessor :target
|
||||
attr_accessor :captures
|
||||
|
@ -10,6 +17,7 @@ class Pry
|
|||
attr_accessor :opts
|
||||
attr_accessor :command_set
|
||||
attr_accessor :command_processor
|
||||
attr_accessor :void
|
||||
attr_accessor :_pry_
|
||||
|
||||
# Run a command from another command.
|
||||
|
|
|
@ -80,6 +80,8 @@ class Pry
|
|||
# @param [String] eval_string The cumulative lines of input for
|
||||
# multi-line input.
|
||||
# @param [Binding] target The receiver of the commands.
|
||||
# @return [Object] The value returned by the
|
||||
# command.
|
||||
def process_commands(val, eval_string, target)
|
||||
|
||||
# no command was matched, so return to caller
|
||||
|
@ -100,7 +102,9 @@ class Pry
|
|||
:captures => captures
|
||||
}
|
||||
|
||||
execute_command(target, command.name, options, *(captures + args))
|
||||
ret = execute_command(target, command.name, options, *(captures + args))
|
||||
|
||||
[ret, command.options[:keep_retval]]
|
||||
end
|
||||
|
||||
# Execute a Pry command.
|
||||
|
@ -109,6 +113,7 @@ class Pry
|
|||
# @param [String] command The name of the command to be run.
|
||||
# @param [Hash] options The options to set on the Commands object.
|
||||
# @param [Array] args The command arguments.
|
||||
# @return [Object] The value returned by the command
|
||||
def execute_command(target, command, options, *args)
|
||||
context = CommandContext.new
|
||||
|
||||
|
@ -120,6 +125,7 @@ class Pry
|
|||
context.eval_string = options[:eval_string]
|
||||
context.arg_string = options[:arg_string]
|
||||
context.command_set = commands
|
||||
context.void = Pry::CommandContext::VOID_VALUE
|
||||
context._pry_ = @pry_instance
|
||||
|
||||
context.command_processor = self
|
||||
|
|
|
@ -15,7 +15,11 @@ class Pry
|
|||
context.instance_eval(&stub_block)
|
||||
else
|
||||
ret = context.instance_exec(*correct_arg_arity(block.arity, args), &block)
|
||||
ret if options[:keep_retval]
|
||||
if options[:keep_retval]
|
||||
ret
|
||||
else
|
||||
Pry::CommandContext::VOID_VALUE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -23,10 +23,10 @@ class Pry
|
|||
nil
|
||||
when "::"
|
||||
_pry_.binding_stack.push TOPLEVEL_BINDING
|
||||
nil
|
||||
void
|
||||
else
|
||||
_pry_.binding_stack.push Pry.binding_for(target.eval(arg_string))
|
||||
nil
|
||||
void
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ class Pry
|
|||
end
|
||||
end
|
||||
|
||||
command "edit", "Invoke the default editor on a file. Type `edit --help` for more info" do |*args|
|
||||
command "edit", "Invoke the default editor on a file. Type `edit --help` for more info", :keep_retval => true do |*args|
|
||||
opts = Slop.parse!(args) do |opt|
|
||||
opt.banner "Usage: edit [OPTIONS] [FILE]\n" \
|
||||
"Edit the method FILE in an editor.\n" \
|
||||
|
|
|
@ -278,7 +278,7 @@ class Pry
|
|||
# @param [String] val The input string.
|
||||
# @return [Boolean] Whether the input is null.
|
||||
def null_input?(val)
|
||||
val.empty? && !Thread.current[:__pry_cmd_ret_value__]
|
||||
val.empty? && Thread.current[:__pry_cmd_ret_value__] == Pry::CommandContext::VOID_VALUE
|
||||
end
|
||||
|
||||
# Read a line of input and check for ^d, also determine prompt to use.
|
||||
|
@ -306,9 +306,9 @@ class Pry
|
|||
# @param [String] eval_string The cumulative lines of input.
|
||||
# @param [Binding] target The target of the Pry session.
|
||||
def process_line(val, eval_string, target)
|
||||
Thread.current[:__pry_cmd_ret_value__] = @command_processor.process_commands(val, eval_string, target)
|
||||
Thread.current[:__pry_cmd_ret_value__], keep_retval = @command_processor.process_commands(val, eval_string, target)
|
||||
|
||||
if Thread.current[:__pry_cmd_ret_value__]
|
||||
if keep_retval && Thread.current[:__pry_cmd_ret_value__] != Pry::CommandContext::VOID_VALUE
|
||||
eval_string << "Thread.current[:__pry_cmd_ret_value__]\n"
|
||||
else
|
||||
# only commands (with no ret_value) should have an empty `val` so this ignores their result
|
||||
|
|
|
@ -112,9 +112,9 @@ describe Pry::CommandSet do
|
|||
@set.commands['foo'].description.should == 'baz'
|
||||
end
|
||||
|
||||
it 'should return nil for commands by default' do
|
||||
it 'should return Pry::CommandContext::VOID_VALUE for commands by default' do
|
||||
@set.command('foo') { 3 }
|
||||
@set.run_command(nil, 'foo').should == nil
|
||||
@set.run_command(nil, 'foo').should == Pry::CommandContext::VOID_VALUE
|
||||
end
|
||||
|
||||
it 'should be able to keep return values' do
|
||||
|
@ -122,6 +122,11 @@ describe Pry::CommandSet do
|
|||
@set.run_command(nil, 'foo').should == 3
|
||||
end
|
||||
|
||||
it 'should be able to keep return values, even if return value is nil' do
|
||||
@set.command('foo', '', :keep_retval => true) { nil }
|
||||
@set.run_command(nil, 'foo').should == nil
|
||||
end
|
||||
|
||||
it 'should be able to have its own helpers' do
|
||||
@set.command('foo') do
|
||||
should.respond_to :my_helper
|
||||
|
|
|
@ -713,6 +713,29 @@ describe Pry do
|
|||
str_output.string !~ /=>/
|
||||
end
|
||||
|
||||
it 'should define a command that keeps its return value even when nil' do
|
||||
klass = Pry::CommandSet.new do
|
||||
command "hello", "", :keep_retval => true do
|
||||
nil
|
||||
end
|
||||
end
|
||||
str_output = StringIO.new
|
||||
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
|
||||
str_output.string.should =~ /nil/
|
||||
str_output.string.should =~ /=>/
|
||||
end
|
||||
|
||||
it 'should define a command that keeps its return value but does not return when value is void' do
|
||||
klass = Pry::CommandSet.new do
|
||||
command "hello", "", :keep_retval => true do
|
||||
void
|
||||
end
|
||||
end
|
||||
str_output = StringIO.new
|
||||
Pry.new(:input => StringIO.new("hello\n"), :output => str_output, :commands => klass).rep
|
||||
str_output.string.empty?.should == true
|
||||
end
|
||||
|
||||
it 'should set the commands default, and the default should be overridable' do
|
||||
klass = Pry::CommandSet.new do
|
||||
command "hello" do
|
||||
|
|
Loading…
Reference in a new issue