From 571612f4cf84ef4fcb531824eb0867d1173940c6 Mon Sep 17 00:00:00 2001 From: John Mair Date: Mon, 27 Dec 2010 23:56:55 +1300 Subject: [PATCH] * completely merged Output and Commands classes, reduced Output to just a simple puts() method, a la Input and read() * Commands now completely manages 'help', so that 'help' returns full command list/doco and 'help cmd' returns doc for just that command * Turned out.session_start() and out.session_end() into hook methods: Pry.hooks :before_session, and :after_session * Refactored Pry#initialize, so no longer individually setting accessors and hash options, instead using ConfigOptions to iterate over accessors and set their default value to Pry.send(accessor_name) * TO DO: rewrite tests in terms of new program structure, since they're all failing due to major change (not because functionality is lacking but due to assumptions tests were making about program structure) --- lib/pry.rb | 2 + lib/pry/commands.rb | 44 +++++++++----------- lib/pry/hooks.rb | 6 +++ lib/pry/output.rb | 92 ----------------------------------------- lib/pry/print.rb | 11 +++++ lib/pry/pry_class.rb | 6 ++- lib/pry/pry_instance.rb | 46 +++++++++------------ 7 files changed, 61 insertions(+), 146 deletions(-) create mode 100644 lib/pry/hooks.rb create mode 100644 lib/pry/print.rb diff --git a/lib/pry.rb b/lib/pry.rb index 57543bdc..7cead0e0 100644 --- a/lib/pry.rb +++ b/lib/pry.rb @@ -7,6 +7,8 @@ require "method_source" require "#{direc}/pry/version" require "#{direc}/pry/input" require "#{direc}/pry/output" +require "#{direc}/pry/hooks" +require "#{direc}/pry/print" require "#{direc}/pry/commands" require "#{direc}/pry/prompts" require "#{direc}/pry/core_extensions" diff --git a/lib/pry/commands.rb b/lib/pry/commands.rb index b678e3c1..56bcf26c 100644 --- a/lib/pry/commands.rb +++ b/lib/pry/commands.rb @@ -15,8 +15,9 @@ class Pry ["exit_program", "quit_program"] => proc do exit end, - "help" => proc do |opts| - self.show_help + /^help\s*(.+)?/ => proc do |opts| + param = opts[:captures].first + self.show_help(param) opts[:eval_string].clear end, "nesting" => proc do |opts| @@ -91,8 +92,7 @@ class Pry def command_info @command_info ||= { "!" => "Refresh the REPL.", - ["exit_program", "quit_program"] => "end -the current program.", + ["exit_program", "quit_program"] => "end the current program.", "help" => "This menu.", "nesting" => "Show nesting information.", "status" => "Show status information.", @@ -109,27 +109,21 @@ the current program.", } end - def refresh - end - - def show_help - out.puts "Command list:" - out.puts "--" - out.puts "help This menu" - out.puts "status Show status information" - out.puts "! Refresh the REPL" - out.puts "nesting Show nesting information" - out.puts "ls Show the list of variables in the current scope" - out.puts "cat Show output of .inspect" - out.puts "cd Start a Pry session on (use `cd ..` to go back)" - out.puts "show_method Show the sourcecode for the method " - out.puts "show_imethod Show the sourcecode for the instance method " - out.puts "show_doc Show the comments above " - out.puts "show_idoc Show the comments above instance method " - out.puts "exit/quit/back End the current Pry session" - out.puts "exit_all End all nested Pry sessions" - out.puts "exit_program/quit_program End the current program" - out.puts "jump_to Jump to a Pry session further up the stack, exiting all sessions below" + def show_help(param) + if !param + out.puts "Command list:" + out.puts "--" + command_info.each do |k, v| + puts "#{Array(k).first}".ljust(33) + v + end + else + key = command_info.keys.find { |v| Array(v).any? { |k| k == param } } + if key + out.puts command_info[key] + else + out.puts "No info for command: #{param}" + end + end end def show_nesting(nesting) diff --git a/lib/pry/hooks.rb b/lib/pry/hooks.rb new file mode 100644 index 00000000..653e69d5 --- /dev/null +++ b/lib/pry/hooks.rb @@ -0,0 +1,6 @@ +class Pry + DEFAULT_HOOKS = { + :before_session => proc { |out, obj| out.puts "Beginning Pry session for #{Pry.view(obj)}" }, + :after_session => proc { |out, obj| out.puts "Ending Pry session for #{Pry.view(obj)}" } + } +end diff --git a/lib/pry/output.rb b/lib/pry/output.rb index 6748874f..2cf325c0 100644 --- a/lib/pry/output.rb +++ b/lib/pry/output.rb @@ -9,97 +9,5 @@ class Pry def puts(value) out.puts value end - - def refresh - out.puts "Refreshed REPL" - end - - def session_start(obj) - out.puts "Beginning Pry session for #{Pry.view(obj)}" - end - - def session_end(obj) - out.puts "Ending Pry session for #{Pry.view(obj)}" - end - - # the print component of READ-EVAL-PRINT-LOOP - def print(value) - case value - when Exception - out.puts "#{value.class}: #{value.message}" - else - out.puts "=> #{Pry.view(value)}" - end - end - - def show_help - out.puts "Command list:" - out.puts "--" - out.puts "help This menu" - out.puts "status Show status information" - out.puts "! Refresh the REPL" - out.puts "nesting Show nesting information" - out.puts "ls Show the list of variables in the current scope" - out.puts "cat Show output of .inspect" - out.puts "cd Start a Pry session on (use `cd ..` to go back)" - out.puts "show_method Show the sourcecode for the method " - out.puts "show_imethod Show the sourcecode for the instance method " - out.puts "show_doc Show the comments above " - out.puts "show_idoc Show the comments above instance method " - out.puts "exit/quit/back End the current Pry session" - out.puts "exit_all End all nested Pry sessions" - out.puts "exit_program/quit_program End the current program" - out.puts "jump_to Jump to a Pry session further up the stack, exiting all sessions below" - end - - def show_nesting(nesting) - out.puts "Nesting status:" - out.puts "--" - nesting.each do |level, obj| - if level == 0 - out.puts "#{level}. #{Pry.view(obj)} (Pry top level)" - else - out.puts "#{level}. #{Pry.view(obj)}" - end - end - end - - def show_status(nesting, target) - out.puts "Status:" - out.puts "--" - out.puts "Receiver: #{Pry.view(target.eval('self'))}" - out.puts "Nesting level: #{nesting.level}" - out.puts "Local variables: #{target.eval('Pry.view(local_variables)')}" - out.puts "Last result: #{Pry.view(Pry.last_result)}" - end - - def ls(target) - out.puts "#{target.eval('Pry.view(local_variables + instance_variables)')}" - end - - def cat(target, var) - out.puts target.eval("#{var}.inspect") - end - - def show_method(code) - out.puts code - end - - def show_doc(doc) - out.puts doc - end - - def warn_already_at_level(nesting_level) - out.puts "Already at nesting level #{nesting_level}" - end - - def err_invalid_nest_level(nest_level, max_nest_level) - out.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{nest_level}." - end - - def exit() end - def cd(*) end - def jump_to(nesting_level_breakout) end - def exit_program() end end end diff --git a/lib/pry/print.rb b/lib/pry/print.rb new file mode 100644 index 00000000..d2838890 --- /dev/null +++ b/lib/pry/print.rb @@ -0,0 +1,11 @@ +class Pry + DEFAULT_PRINT = proc do |output, value| + case value + when Exception + output.puts "#{value.class}: #{value.message}" + else + output.puts "=> #{Pry.view(value)}" + end + end +end + diff --git a/lib/pry/pry_class.rb b/lib/pry/pry_class.rb index 985c01af..ed312815 100644 --- a/lib/pry/pry_class.rb +++ b/lib/pry/pry_class.rb @@ -3,9 +3,9 @@ class Pry # class accessors class << self attr_reader :nesting - attr_accessor :last_result + attr_accessor :last_result, :active_instance attr_accessor :input, :output - attr_accessor :commands + attr_accessor :commands, :print, :hooks attr_accessor :default_prompt, :wait_prompt end @@ -28,6 +28,8 @@ class Pry @commands = Commands.new(@output) @default_prompt = DEFAULT_PROMPT @wait_prompt = WAIT_PROMPT + @print = DEFAULT_PRINT + @hooks = DEFAULT_HOOKS end self.reset_defaults diff --git a/lib/pry/pry_instance.rb b/lib/pry/pry_instance.rb index 8731ec66..d89ffcc6 100644 --- a/lib/pry/pry_instance.rb +++ b/lib/pry/pry_instance.rb @@ -1,24 +1,18 @@ class Pry - attr_accessor :input, :output, :commands - attr_accessor :default_prompt, :wait_prompt - + ConfigOptions = [:input, :output, :commands, :print, + :default_prompt, :wait_prompt, :hooks] + + attr_accessor *ConfigOptions def initialize(options={}) - options = { - :input => Pry.input, - :output => Pry.output, - :commands => Pry.commands, - :default_prompt => Pry.default_prompt, - :wait_prompt => Pry.wait_prompt - }.merge!(options) - - @input = options[:input] - @output = options[:output] - @commands = options[:commands] - @default_prompt = options[:default_prompt] - @wait_prompt = options[:wait_prompt] + options = ConfigOptions.each_with_object({}) { |v, h| h[v] = Pry.send(v) } + options.merge!(options) + + ConfigOptions.each do |key| + instance_variable_set("@#{key}", options[key]) + end end def nesting @@ -33,12 +27,16 @@ class Pry def repl(target=TOPLEVEL_BINDING) target = binding_for(target) target_self = target.eval('self') - output.session_start(target_self) + hooks[:before_session].call(output, target_self) + nesting_level = nesting.size + Pry.active_instance = self + # Make sure _ exists target.eval("_ = Pry.last_result") + target.eval("_pry_ = Pry.active_instance") break_level = catch(:breakout) do nesting << [nesting.size, target_self] @@ -48,7 +46,7 @@ class Pry end nesting.pop - output.session_end(target_self) + hooks[:after_session].call(output, target_self) # we only enter here if :breakout has been thrown if nesting_level != break_level @@ -61,21 +59,15 @@ class Pry # print def rep(target=TOPLEVEL_BINDING) target = binding_for(target) - value = re(target) - - # TODO - replace this with a callback - case value - when Exception - output.puts "#{value.class}: #{value.message}" - else - output.puts "=> #{Pry.view(value)}" - end + print.call output, re(target) end # eval def re(target=TOPLEVEL_BINDING) target = binding_for(target) Pry.last_result = target.eval r(target) + Pry.active_instance = self + target.eval("_pry_ = Pry.active_instance") target.eval("_ = Pry.last_result") rescue SystemExit => e exit