Provide a place for commands to store state.

Commands can store state on an  `OpenStruct` exposed via the `state` method.
This `OpenStruct` is guaranteed to be unique to the command and to the associated Pry instance.

e.g

create_command "my-test" do
  def process
    state.my_state ||= 0
    state.my_state += 1
  end
end

The above `state.my_state` variable will increment by one for each invocation of `my-test`.
Further, it will not intefere with any state on `my-test` for any other Pry instance or with
any `state.my_state` variables defined for other commands on the same Pry instance.
This commit is contained in:
John Mair 2012-06-16 00:36:03 +12:00
parent 723e1166c0
commit 0871ac65f6
3 changed files with 86 additions and 1 deletions

View File

@ -225,9 +225,20 @@ class Pry
self._pry_ = context[:pry_instance]
end
# The value of {self} inside the {target} binding.
# @return [Object] The value of `self` inside the `target` binding.
def target_self; target.eval('self'); end
# @return [Hash] Pry commands can store arbitrary state
# here. This state persists between subsequent command invocations.
# All state saved here is unique to the command, it does not
# need to be namespaced.
# @example
# state.my_state = "my state" # this will not conflict with any
# # `state.my_state` used in another command.
def state
_pry_.command_state[match] ||= OpenStruct.new
end
# Revaluate the string (str) and perform interpolation.
# @param [String] str The string to reevaluate with interpolation.
#

View File

@ -28,6 +28,9 @@ class Pry
attr_accessor :extra_sticky_locals
# This is exposed via Pry::Command#state.
attr_reader :command_state
# Special treatment for hooks as we want to alert people of the
# changed API
attr_reader :hooks
@ -59,6 +62,7 @@ class Pry
@binding_stack = []
@indent = Pry::Indent.new
@command_state = {}
end
# Refresh the Pry instance settings from the Pry class.

View File

@ -623,4 +623,74 @@ describe "Pry::Command" do
mock_pry("show-command my-test").should =~ /output.puts command_name/
end
end
describe "commands can save state" do
before do
@set = Pry::CommandSet.new do
create_command "litella", "desc" do
def process
state.my_state ||= 0
state.my_state += 1
end
end
create_command "sanders", "desc" do
def process
state.my_state = "wood"
end
end
create_command /[Hh]ello-world/, "desc" do
def process
state.my_state ||= 0
state.my_state += 2
end
end
end.import Pry::Commands
end
it 'should save state for the command on the Pry#command_state hash' do
instance = nil
redirect_pry_io(InputTester.new("litella",
"exit-all")) do
instance = Pry.new(:commands => @set)
instance.repl
end
instance.command_state["litella"].my_state.should == 1
end
it 'should ensure state is maintained between multiple invocations of command' do
instance = nil
redirect_pry_io(InputTester.new("litella", "litella",
"exit-all")) do
instance = Pry.new(:commands => @set)
instance.repl
end
instance.command_state["litella"].my_state.should == 2
end
it 'should ensure state with same name stored stored seperately for each command' do
instance = nil
redirect_pry_io(InputTester.new("litella", "sanders", "exit-all")) do
instance = Pry.new(:commands => @set)
instance.repl
end
instance.command_state["litella"].my_state.should == 1
instance.command_state["sanders"].my_state.should =="wood"
end
it 'should ensure state can is properly saved for regex commands' do
instance = nil
redirect_pry_io(InputTester.new("hello-world", "Hello-world", "exit-all")) do
instance = Pry.new(:commands => @set)
instance.repl
end
instance.command_state[/[Hh]ello-world/].my_state.should == 4
end
end
end