From 42d1c126af25260cfbc42dd4899b0e514ffe73a3 Mon Sep 17 00:00:00 2001 From: John Mair Date: Thu, 17 Feb 2011 10:22:59 +1300 Subject: [PATCH] version 0.5.0pre4 Almost ready for release. Updated examples to match new changes, updated README. --- README.markdown | 57 +++++----- TODO | 1 - examples/example_command_override.rb | 2 +- examples/example_image_edit.rb | 15 ++- examples/example_input2.rb | 2 +- lib/pry/commands.rb | 163 ++++++++++++++++++--------- lib/pry/version.rb | 2 +- 7 files changed, 146 insertions(+), 96 deletions(-) diff --git a/README.markdown b/README.markdown index 5de28b65..8d43eb5b 100644 --- a/README.markdown +++ b/README.markdown @@ -13,7 +13,7 @@ session to your code (with Pry) instead of bringing your code to a REPL session (as with IRB). It is not based on the IRB codebase, and implements some unique REPL -commands such as `show_method` and `show_doc` +commands such as `show-method`, `show-doc`, `ls` and `cd` Pry is also fairly flexible and allows significant user [customization](http://rdoc.info/github/banister/pry/master/file/wiki/Customizing-pry.md). It @@ -121,9 +121,9 @@ command. E.g => nil We can then jump back to any of the previous nesting levels by using -the `jump_to` command: +the `jump-to` command: - pry("friend":3)> jump_to 1 + pry("friend":3)> jump-to 1 Ending Pry session for "friend" Ending Pry session for 100 => 100 @@ -133,9 +133,9 @@ If we just want to go back one level of nesting we can of course use the `quit` or `exit` or `back` commands. To break out of all levels of Pry nesting and return immediately to the -calling process use `exit_all`: +calling process use `exit-all`: - pry("friend":3)> exit_all + pry("friend":3)> exit-all Ending Pry session for "friend" Ending Pry session for 100 Ending Pry session for Hello @@ -163,8 +163,8 @@ end. * Use `_pry_` to reference the Pry instance managing the current session. * Pry supports tab completion. * Pry has multi-line support built in. -* Pry has special commands not found in many other Ruby REPLs: `show_method`, `show_doc` -`jump_to`, `ls`, `cd`, `cat` +* Pry has special commands not found in many other Ruby REPLs: `show-method`, `show-doc` +`jump-to`, `ls`, `cd`, `cat` * Pry gives good control over nested sessions (important when exploring complicated runtime state) * Pry is not based on the IRB codebase. * Pry allows significant customizability. @@ -183,7 +183,7 @@ invoke any of these methods directly depending on exactly what aspect of the fun and so does not have an executable. It is designed to be used by other programs, not on its own. For a full-featured `irb` replacement see [ripl](https://github.com/cldwalker/ripl) -* Pry's `show_method` and `show_doc` commands do not work +* Pry's `show-method` and `show-doc` commands do not work in Ruby 1.8. Commands @@ -229,35 +229,34 @@ whitespace in between. If you want to access a method of the same name, prefix the invocation by whitespace. -* Typing `!` on a line by itself will refresh the REPL - useful for - getting you out of a situation if the parsing process - goes wrong. +* Typing `!` on a line by itself will clear the input buffer - useful for + getting you out of a situation where the parsing process + goes wrong and you get stuck in an endless read loop. * `status` shows status information about the current session. +* `version` Show Pry version information * `help` shows the list of session commands with brief explanations. * `exit` or `quit` or `back` will end the current Pry session and go back to the calling process or back one level of nesting (if there are nested sessions). -* `ls` returns a list of local variables and instance variables in the - current scope -* `ls_methods` List all methods defined on immediate class of receiver. -* `ls_imethods` List all instance methods defined on receiver. -* `cat ` Calls `inspect` on `` -* `cd ` Starts a `Pry` session on the variable . E.g `cd @x` +* `ls [OPTIONS] [VAR]` returns a list of local variables, instance variables, and + methods, etc. Highly flexible. See `ls --help` for more info. +* `cat VAR` Calls `inspect` on `VAR` +* `cd VAR` Starts a `Pry` session on the variable VAR. E.g `cd @x` (use `cd ..` to go back). -* `show_method ` Displays the sourcecode for the method - . E.g `show_method hello` -* `show_imethod ` Displays the sourcecode for the - instance method . E.g `show_imethod goodbye` -* `show_doc ` Displays comments for `` -* `show_idoc ` Displays comments for instance - method `` -* `exit_program` or `quit_program` will end the currently running +* `show-method [OPTIONS] METH` Displays the sourcecode for the method + `METH`. E.g `show-method hello`. See `show-method --help` for more info. +* `show-doc [OPTIONS] METH` Displays comments for `METH`. See `show-doc + --help` for more info. +* `exit-program` or `quit-program` will end the currently running program. * `nesting` Shows Pry nesting information. +* `cat-file FILE` Displays the contents of a file on disk in the Pry session. +* `eval-file [OPTIONS] FILE` Evals a Ruby script at top-level or in + the current context. See `eval-file --help` for more info. * `!pry` Starts a Pry session on the implied receiver; this can be used in the middle of an expression in multi-line input. -* `jump_to ` Unwinds the Pry stack (nesting level) until the appropriate nesting level is reached. -* `exit_all` breaks out of all Pry nesting levels and returns to the +* `jump-to NEST_LEVEL` Unwinds the Pry stack (nesting level) until the appropriate nesting level is reached. +* `exit-all` breaks out of all Pry nesting levels and returns to the calling process. * You can type `Pry.start(obj)` or `obj.pry` to nest another Pry session within the current one with `obj` as the receiver of the new session. Very useful @@ -308,7 +307,3 @@ Contact ------- Problems or questions contact me at [github](http://github.com/banister) - - - - diff --git a/TODO b/TODO index e4ef742d..b338cd9d 100644 --- a/TODO +++ b/TODO @@ -12,5 +12,4 @@ * add --help option to most commands * Get rid of ls_method and ls_imethods (subsumed by more powerful ls) * Get rid of show_idoc and show_imethod -* Support YARD and Rdoc documentation * Add special load-file command that evals target file in current context diff --git a/examples/example_command_override.rb b/examples/example_command_override.rb index 45736986..889eaeee 100644 --- a/examples/example_command_override.rb +++ b/examples/example_command_override.rb @@ -27,7 +27,7 @@ class MyCommands < Pry::CommandBase end # bring in a few other commands - import_from Pry::Commands, "quit", "show_method" + import_from Pry::Commands, "quit", "show-method" end # Start a Pry session using the commands defined in MyCommands diff --git a/examples/example_image_edit.rb b/examples/example_image_edit.rb index 238af3d8..1eefa5e4 100644 --- a/examples/example_image_edit.rb +++ b/examples/example_image_edit.rb @@ -31,23 +31,23 @@ class ImageCommands < Pry::CommandBase exit end - import_from Pry::Commands, "ls", "ls_methods", "!" + import_from Pry::Commands, "ls", "!" end class WinClass < Gosu::Window def initialize super(WIDTH, HEIGHT, false) - $img = TexPlay.create_image(self, 200, 200).clear :color => :black - $img.rect 0, 0, $img.width - 1, $img.height - 1 - - @binding = $img.__binding__ + @img = TexPlay.create_image(self, 200, 200).clear :color => :black + @img.rect 0, 0, @img.width - 1, @img.height - 1 + + @binding = Pry.binding_for(@img) @pry_instance = Pry.new(:commands => ImageCommands, :prompt => IMAGE_PROMPT) end def draw - $img.draw_rot(WIDTH / 2, HEIGHT / 2, 1, 0, 0.5, 0.5) + @img.draw_rot(WIDTH / 2, HEIGHT / 2, 1, 0, 0.5, 0.5) end def update @@ -57,7 +57,7 @@ class WinClass < Gosu::Window # being updated; instead we do a REP session, and let the image # update each time the user presses enter. We maintain the same # binding object to keep locals between calls to `Pry#rep()` -# @pry_instance.rep(@binding) + @pry_instance.rep(@binding) end end @@ -67,6 +67,5 @@ puts "Example: Try typing 'circle width/2, height/2, 95, :color => :blue, :fill puts "If you want to save your image, type: save(\"img.png\")" w = WinClass.new -Thread.new { Pry.start(w) } w.show diff --git a/examples/example_input2.rb b/examples/example_input2.rb index ee7486fe..bd4979d5 100644 --- a/examples/example_input2.rb +++ b/examples/example_input2.rb @@ -13,7 +13,7 @@ nesting puts 'hello from 2!!' _pry_.parent.input = Readline back -exit_all +exit-all CMDS # create our StringIO object diff --git a/lib/pry/commands.rb b/lib/pry/commands.rb index b0cee47b..c4f5522f 100644 --- a/lib/pry/commands.rb +++ b/lib/pry/commands.rb @@ -17,7 +17,7 @@ class Pry end end - command "!", "Clear the input buffer. Useful if the parsing process goes wrong." do + command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do output.puts "Input buffer cleared!" opts[:eval_string].clear end @@ -33,35 +33,33 @@ class Pry alias_command "quit-program", "exit-program", "" command "nesting", "Show nesting information." do - out = output nesting = opts[:nesting] - out.puts "Nesting status:" - out.puts "--" + output.puts "Nesting status:" + output.puts "--" nesting.each do |level, obj| if level == 0 - out.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)" + output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)" else - out.puts "#{level}. #{Pry.view_clip(obj)}" + output.puts "#{level}. #{Pry.view_clip(obj)}" end end end command "status", "Show status information." do - out = output nesting = opts[:nesting] - out.puts "Status:" - out.puts "--" - out.puts "Receiver: #{Pry.view_clip(target.eval('self'))}" - out.puts "Nesting level: #{nesting.level}" - out.puts "Pry version: #{Pry::VERSION}" - out.puts "Ruby version: #{RUBY_VERSION}" + output.puts "Status:" + output.puts "--" + output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}" + output.puts "Nesting level: #{nesting.level}" + output.puts "Pry version: #{Pry::VERSION}" + output.puts "Ruby version: #{RUBY_VERSION}" mn = meth_name_from_binding.call(target) - out.puts "Current method: #{mn ? mn : "N/A"}" - out.puts "Pry instance: #{Pry.active_instance}" - out.puts "Last result: #{Pry.view(Pry.last_result)}" + output.puts "Current method: #{mn ? mn : "N/A"}" + output.puts "Pry instance: #{Pry.active_instance}" + output.puts "Last result: #{Pry.view(Pry.last_result)}" end command "version", "Show Pry version." do @@ -74,7 +72,7 @@ class Pry command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args| options = {} - + # Set target local to the default -- note that we can set a different target for # ls if we like: e.g ls my_var target = target() @@ -82,51 +80,46 @@ class Pry OptionParser.new do |opts| opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\ List information about VAR (the current context by default). -Always shows local and instance variables by default; use -r to restrict to specific types. +Shows local and instance variables by default. -- } - - opts.on("-g", "--globals", "Display global variables.") do |g| + opts.on("-g", "--globals", "Display global variables.") do options[:g] = true end - opts.on("-c", "--constants", "Display constants.") do |c| + opts.on("-c", "--constants", "Display constants.") do options[:c] = true end - opts.on("-l", "--locals", "Display locals.") do |c| + opts.on("-l", "--locals", "Display locals.") do options[:l] = true end - opts.on("-i", "--ivars", "Display instance variables.") do |c| + opts.on("-i", "--ivars", "Display instance variables.") do options[:i] = true end - opts.on("-k", "--class-vars", "Display class variables.") do |c| + opts.on("-k", "--class-vars", "Display class variables.") do options[:k] = true end - opts.on("-m", "--methods", "Display methods.") do |c| + opts.on("-m", "--methods", "Display methods.") do options[:m] = true end - opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do |c| + opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do options[:M] = true end - opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do |c| + opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do options[:s] = true end - opts.on("-r", "--restrict", "Restrict to specified types.") do |c| - options[:r] = true - end - - opts.on("-a", "--all", "Display all types of entries.") do |a| + opts.on("-a", "--all", "Display all types of entries.") do options[:a] = true end - opts.on("-v", "--verbose", "Verbose ouput.") do |c| + opts.on("-v", "--verbose", "Verbose ouput.") do options[:v] = true end @@ -141,6 +134,14 @@ Always shows local and instance variables by default; use -r to restrict to spec # exit if we've displayed help next if options[:h] + # default is locals/ivars/class vars. + # Only occurs when no options or when only option is verbose + options.merge!({ + :l => true, + :i => true, + :k => true + }) if options.empty? || (options.size == 1 && options[:v]) + info = {} target_self = target.eval('self') @@ -148,23 +149,29 @@ Always shows local and instance variables by default; use -r to restrict to spec # interpolating in the string) options[:s] = !!options[:s] - # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby - # 1.8 + # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8 i = -1 - info["local variables"] = Array(target.eval("local_variables")).sort, i += 1 if !options[:r] || options[:l] || options[:a] - info["instance variables"] = Array(target.eval("instance_variables")).sort, i += 1 if !options[:r] || options[:i] || options[:a] - info["class variables"] = (target_self.is_a?(Module) ? Array(target.eval("class_variables")).sort : Array(target.eval("self.class.class_variables")).sort), i += 1 if !options[:r] || options[:k] || options[:a] - info["global variables"] = Array(target.eval("global_variables")).sort, i += 1 if options[:g] || options[:a] + # Start collecting the entries selected by the user + info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a] + info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a] + + info["class variables"] = [if target_self.is_a?(Module) + Array(target.eval("class_variables")).sort + else + Array(target.eval("self.class.class_variables")).sort + end, i += 1] if options[:k] || options[:a] + + info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a] - info["methods"] = Array(target.eval("methods(#{options[:s]}) + public_methods(#{options[:s]}) +\ + info["methods"] = [Array(target.eval("methods(#{options[:s]}) + public_methods(#{options[:s]}) +\ protected_methods(#{options[:s]}) +\ - private_methods(#{options[:s]})")).uniq.sort, i += 1 if options[:m] || options[:a] + private_methods(#{options[:s]})")).uniq.sort, i += 1] if options[:m] || options[:a] - info["instance methods"] = Array(target.eval("instance_methods(#{options[:s]}) +\ + info["instance methods"] = [Array(target.eval("instance_methods(#{options[:s]}) +\ public_instance_methods(#{options[:s]}) +\ protected_instance_methods(#{options[:s]}) +\ - private_instance_methods(#{options[:s]})")).uniq.sort, i += 1 if target_self.is_a?(Module) && (options[:M] || options[:a]) + private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && (options[:M] || options[:a]) # dealing with 1.8/1.9 compatibility issues :/ csuper = options[:s] @@ -172,8 +179,8 @@ Always shows local and instance variables by default; use -r to restrict to spec csuper = nil end - info["constants"] = Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") : - target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1 if options[:c] || options[:a] + info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") : + target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a] # verbose output? if options[:v] @@ -193,13 +200,63 @@ Always shows local and instance variables by default; use -r to restrict to spec end end + command "cat-file", "Show output of file FILE" do |file_name| + if !file_name + output.puts "Must provide a file name." + next + end + + output.puts File.read(file_name) + end + + command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args| + options = {} + file_name = nil + + OptionParser.new do |opts| + opts.banner = %{Usage: eval-file [OPTIONS] FILE +Eval a Ruby script at top-level or in the current context. +e.g: eval-script -c "hello.rb" +-- +} + opts.on("-c", "--context", "Eval the script in the current context.") do + options[:c] = true + end + + opts.on_tail("-h", "--help", "This message.") do + output.puts opts + options[:h] = true + end + end.order(args) do |v| + file_name = v + end + + next if options[:h] + + if !file_name + output.puts "You need to specify a file name. Type `eval-script --help` for help" + next + end + + old_constants = Object.constants + if options[:c] + target.eval(File.read(file_name)) + output.puts "--\nEval'd '#{file_name}' in the current context." + else + TOPLEVEL_BINDING.eval(File.read(file_name)) + output.puts "--\nEval'd '#{file_name}' at top-level." + end + new_constants = Object.constants - old_constants + output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty? + end + command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj| if !obj output.puts "Must provide an object to inspect." next end - output.puts target.eval("#{obj}.inspect") + output.puts Pry.view(target.eval("#{obj}")) end alias_command "inspect", "cat", "" @@ -224,11 +281,11 @@ Show the comments above method METH. Shows _method_ comments (rather than instan e.g show-doc hello_method -- } - opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do |m| + opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do options[:M] = true end - opts.on_tail("-h", "--help", "This message.") do |h| + opts.on_tail("-h", "--help", "This message.") do output.puts opts options[:h] = true end @@ -256,7 +313,7 @@ e.g show-doc hello_method doc = meth.comment file, line = meth.source_location - output.puts "From #{file} @ line ~#{line}:" + output.puts "From #{file} @ line ~#{line}:\n--" output.puts doc end @@ -270,11 +327,11 @@ Show the source for method METH. Shows _method_ source (rather than instance met e.g: show-method hello_method -- } - opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do |m| + opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do options[:M] = true end - opts.on_tail("-h", "--help", "This message.") do |h| + opts.on_tail("-h", "--help", "This message.") do output.puts opts options[:h] = true end @@ -305,7 +362,7 @@ e.g: show-method hello_method code = meth.source file, line = meth.source_location - output.puts "From #{file} @ line #{line}:" + output.puts "From #{file} @ line #{line}:\n--" output.puts code end @@ -321,7 +378,7 @@ e.g: show-method hello_method meth = cmds[command_name][:action] code = meth.source file, line = meth.source_location - output.puts "From #{file} @ line #{line}:" + output.puts "From #{file} @ line #{line}:\n--" output.puts code else output.puts "No such command: #{command_name}." diff --git a/lib/pry/version.rb b/lib/pry/version.rb index 56166c07..e69a7580 100644 --- a/lib/pry/version.rb +++ b/lib/pry/version.rb @@ -1,3 +1,3 @@ class Pry - VERSION = "0.5.0pre2" + VERSION = "0.5.0pre4" end