Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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.
  • Loading branch information...
commit a04e56012ab396f343cd931b6ba5ba3e7372769c 1 parent fc15407
@banister banister authored
View
1  CHANGELOG
@@ -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 /`
View
8 lib/pry/command_context.rb
@@ -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 CommandContext
attr_accessor :opts
attr_accessor :command_set
attr_accessor :command_processor
+ attr_accessor :void
attr_accessor :_pry_
# Run a command from another command.
View
8 lib/pry/command_processor.rb
@@ -80,6 +80,8 @@ def command_matched(val, target)
# @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 @@ def process_commands(val, eval_string, target)
: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 @@ def process_commands(val, eval_string, target)
# @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 @@ def execute_command(target, command, options, *args)
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
View
6 lib/pry/command_set.rb
@@ -15,7 +15,11 @@ def call(context, *args)
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
View
4 lib/pry/default_commands/context.rb
@@ -23,10 +23,10 @@ module DefaultCommands
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
View
2  lib/pry/default_commands/introspection.rb
@@ -108,7 +108,7 @@ module DefaultCommands
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" \
View
6 lib/pry/pry_instance.rb
@@ -278,7 +278,7 @@ def show_result(result)
# @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 @@ def retrieve_line(eval_string, target)
# @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
View
9 test/test_command_set.rb
@@ -112,9 +112,9 @@
@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 @@
@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
View
23 test/test_pry.rb
@@ -713,6 +713,29 @@ def readline(*args)
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
Please sign in to comment.
Something went wrong with that request. Please try again.