From 61fdb7150ed50b01f5e17f6dc6e417ecedc20918 Mon Sep 17 00:00:00 2001 From: Ryan Fitzgerald Date: Mon, 15 Aug 2011 13:56:28 -0400 Subject: [PATCH] only interpolate once during command processing (fixes #200) --- lib/pry/command_processor.rb | 17 +++++++---------- test/test_command_processor.rb | 12 +++++++++++- test/test_pry.rb | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/lib/pry/command_processor.rb b/lib/pry/command_processor.rb index 6810e6e1..28ca2155 100644 --- a/lib/pry/command_processor.rb +++ b/lib/pry/command_processor.rb @@ -53,23 +53,20 @@ class Pry # interpolation against. # @return [Array] The command data and arg string pair def command_matched(val, target) - _, cmd_data = commands.commands.find do |name, data| + interpolated_val = begin + interpolate_string(val, target) + rescue Exception + nil + end + _, cmd_data = commands.commands.find do |name, data| prefix = convert_to_regex(Pry.config.command_prefix) prefix = "(?:#{prefix})?" unless data.options[:use_prefix] command_regex = /^#{prefix}#{convert_to_regex(name)}(?!\S)/ if data.options[:interpolate] - # If interpolation fails then the command cannot be matched, - # so early exit. - begin - interp_val = interpolate_string(val, target) - rescue Exception - next - end - - val.replace interp_val if command_regex =~ interp_val + val.replace interpolated_val if command_regex =~ interpolated_val else command_regex =~ val end diff --git a/test/test_command_processor.rb b/test/test_command_processor.rb index 22384b39..f0045461 100644 --- a/test/test_command_processor.rb +++ b/test/test_command_processor.rb @@ -245,11 +245,21 @@ describe "Pry::CommandProcessor" do end - it 'commands that have :interpolate => false should not be interpolated (interpolate_string should *not* be called)' do + it 'should not interpolate commands that have :interpolate => false (interpolate_string should *not* be called)' do @pry.commands.command("boast", "", :interpolate => false) {} # remember to use '' instead of "" when testing interpolation or # you'll cause yourself incredible confusion lambda { @command_processor.command_matched('boast #{c}', binding) }.should.not.raise NameError end + + it 'should only execute the contents of an interpolation once' do + $obj = 'a' + + redirect_pry_io(InputTester.new('#{$obj.succ!}'), StringIO.new) do + Pry.new.rep + end + + $obj.should == 'b' + end end diff --git a/test/test_pry.rb b/test/test_pry.rb index 732b0dbd..52c596a4 100644 --- a/test/test_pry.rb +++ b/test/test_pry.rb @@ -517,7 +517,7 @@ describe Pry do $test_interpolation = nil end - # bug fix for https://github.com/banister/pry/issues/170 + # bug fix for https://github.com/pry/pry/issues/170 it 'should not choke on complex string interpolation when checking if ruby code is a command' do redirect_pry_io(InputTester.new('/#{Regexp.escape(File.expand_path("."))}/'), str_output = StringIO.new) do pry