Skip to content

Commit

Permalink
Merge pull request #2307 from andrehjr/remove-ostruct-command-state
Browse files Browse the repository at this point in the history
Remove OpenStruct usage from Pry::CommandState
  • Loading branch information
andrehjr committed Apr 16, 2024
2 parents 4403462 + d8e41fa commit 6f4d2c1
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 34 deletions.
2 changes: 1 addition & 1 deletion lib/pry/command.rb
Expand Up @@ -200,7 +200,7 @@ def group(name = nil)
end

def state
Pry::CommandState.default.state_for(match)
Pry::CommandState.default.state_for(self)
end
end

Expand Down
17 changes: 11 additions & 6 deletions lib/pry/command_state.rb
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require 'ostruct'

class Pry
# CommandState is a data structure to hold per-command state.
#
Expand All @@ -20,12 +18,19 @@ def initialize
@command_state = {}
end

def state_for(command_name)
@command_state[command_name] ||= OpenStruct.new
def state_for(command_class)
@command_state[command_class] ||= command_struct(command_class)
end

def reset(command_class)
@command_state[command_class] = command_struct(command_class)
end

def reset(command_name)
@command_state[command_name] = OpenStruct.new
private

def command_struct(command_class)
Struct.new(:command, *command_class.command_options[:state])
.new(command: command_class)
end
end
end
2 changes: 2 additions & 0 deletions lib/pry/commands/cd.rb
Expand Up @@ -22,6 +22,8 @@ class Cd < Pry::ClassCommand
https://github.com/pry/pry/wiki/State-navigation#wiki-Changing_scope
BANNER

command_options state: %i[old_stack]

def process
state.old_stack ||= []

Expand Down
2 changes: 2 additions & 0 deletions lib/pry/commands/edit.rb
Expand Up @@ -22,6 +22,8 @@ class Edit < Pry::ClassCommand
https://github.com/pry/pry/wiki/Editor-integration#wiki-Edit_command
BANNER

command_options state: %i[dynamical_ex_file]

def options(opt)
opt.on :e, :ex, "Open the file that raised the most recent exception " \
"(_ex_.file)",
Expand Down
2 changes: 1 addition & 1 deletion lib/pry/commands/shell_command.rb
Expand Up @@ -7,7 +7,7 @@ class ShellCommand < Pry::ClassCommand
group 'Input and Output'
description "All text following a '.' is forwarded to the shell."
command_options listing: '.<shell command>', use_prefix: false,
takes_block: true
takes_block: true, state: %i[old_pwd]

banner <<-'BANNER'
Usage: .COMMAND_NAME
Expand Down
1 change: 1 addition & 0 deletions lib/pry/commands/shell_mode.rb
Expand Up @@ -6,6 +6,7 @@ class ShellMode < Pry::ClassCommand
match 'shell-mode'
group 'Input and Output'
description 'Toggle shell mode. Bring in pwd prompt and file completion.'
command_options state: %i[disabled prev_prompt]

banner <<-'BANNER'
Toggle shell mode. Bring in pwd prompt and file completion.
Expand Down
2 changes: 1 addition & 1 deletion lib/pry/commands/watch_expression.rb
Expand Up @@ -7,7 +7,7 @@ class WatchExpression < Pry::ClassCommand
group 'Context'
description 'Watch the value of an expression and print a notification ' \
'whenever it changes.'
command_options use_prefix: false
command_options use_prefix: false, state: %i[watch_expressions]

banner <<-'BANNER'
Usage: watch [EXPRESSION]
Expand Down
2 changes: 1 addition & 1 deletion lib/pry/control_d_handler.rb
Expand Up @@ -19,7 +19,7 @@ def self.default(pry_instance)
else
# Otherwise, saves current binding stack as old stack and pops last
# binding out of binding stack (the old stack still has that binding).
cd_state = Pry::CommandState.default.state_for('cd')
cd_state = Pry::CommandState.default.state_for(Pry::Command::Cd)
cd_state.old_stack = pry_instance.binding_stack.dup
pry_instance.binding_stack.pop
end
Expand Down
11 changes: 2 additions & 9 deletions spec/command_spec.rb
Expand Up @@ -420,7 +420,7 @@ def self.name

describe ".state" do
it "returns a command state" do
expect(described_class.state).to be_an(OpenStruct)
expect(described_class.state).to be_an(Struct)
end
end

Expand Down Expand Up @@ -478,17 +478,10 @@ def process; end
end

describe "#state" do
let(:target) { binding }

subject { Class.new(described_class).new(pry_instance: Pry.new) }

it "returns a state object" do
expect(subject.state).to be_an(OpenStruct)
end

it "remembers the state" do
subject.state.foo = :bar
expect(subject.state.foo).to eq(:bar)
expect(subject.state).to be_an(Struct)
end
end

Expand Down
26 changes: 14 additions & 12 deletions spec/command_state_spec.rb
Expand Up @@ -17,33 +17,35 @@

describe "#state_for" do
it "returns a state for the matching command" do
subject.state_for('command').foobar = 1
expect(subject.state_for('command').foobar).to eq(1)
subject.state_for(Pry::Command::Cd).old_stack = 1
expect(subject.state_for(Pry::Command::Cd).old_stack).to eq(1)
end

it "returns new state for new command" do
expect(subject.state_for('command'))
.not_to equal(subject.state_for('other-command'))
expect(subject.state_for(Pry::Command::Cd))
.not_to equal(subject.state_for(Pry::Command::Play))
end

it "memoizes state for the same command" do
expect(subject.state_for('command')).to equal(subject.state_for('command'))
state_a = subject.state_for(Pry::Command::Cd)
state_b = subject.state_for(Pry::Command::Cd)
expect(state_a).to equal(state_b)
end
end

describe "#reset" do
it "resets the command state for the given command" do
subject.state_for('command').foobar = 1
subject.reset('command')
expect(subject.state_for('command').foobar).to be_nil
subject.state_for(Pry::Command::Cd).old_stack = 1
subject.reset(Pry::Command::Cd)
expect(subject.state_for(Pry::Command::Cd).old_stack).to be_nil
end

it "doesn't reset command state for other commands" do
subject.state_for('command').foobar = 1
subject.state_for('other-command').foobar = 1
subject.reset('command')
subject.state_for(Pry::Command::Cd).old_stack = 1
subject.state_for(Pry::Command::WatchExpression).watch_expressions = 1
subject.reset(Pry::Command::Cd)

expect(subject.state_for('other-command').foobar).to eq(1)
expect(subject.state_for(Pry::Command::WatchExpression).watch_expressions).to eq(1)
end
end
end
2 changes: 1 addition & 1 deletion spec/commands/cd_spec.rb
Expand Up @@ -27,7 +27,7 @@ def old_stack
end
end

after { Pry::CommandState.default.reset('cd') }
after { Pry::CommandState.default.reset(Pry::Command::Cd) }

describe 'old stack toggling with `cd -`' do
describe 'in fresh pry instance' do
Expand Down
4 changes: 2 additions & 2 deletions spec/commands/shell_command_spec.rb
Expand Up @@ -7,12 +7,12 @@

@t = pry_tester(@o) do
def command_state
Pry::CommandState.default.state_for(Pry::Command::ShellCommand.match)
Pry::CommandState.default.state_for(Pry::Command::ShellCommand)
end
end
end

after { Pry::CommandState.default.reset(Pry::Command::ShellCommand.match) }
after { Pry::CommandState.default.reset(Pry::Command::ShellCommand) }

describe ".cd" do
before do
Expand Down

0 comments on commit 6f4d2c1

Please sign in to comment.