version 0.5.0pre4 Almost ready for release. Updated examples to match new changes, updated README.

This commit is contained in:
John Mair 2011-02-17 10:22:59 +13:00
parent f8f0919189
commit 42d1c126af
7 changed files with 146 additions and 96 deletions

View File

@ -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 <var>` Calls `inspect` on `<var>`
* `cd <var>` Starts a `Pry` session on the variable <var>. 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 <methname>` Displays the sourcecode for the method
<methname>. E.g `show_method hello`
* `show_imethod <methname>` Displays the sourcecode for the
instance method <methname>. E.g `show_imethod goodbye`
* `show_doc <methname>` Displays comments for `<methname>`
* `show_idoc <methname>` Displays comments for instance
method `<methname>`
* `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 <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
* `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)

1
TODO
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -13,7 +13,7 @@ nesting
puts 'hello from 2!!'
_pry_.parent.input = Readline
back
exit_all
exit-all
CMDS
# create our StringIO object

View File

@ -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}."

View File

@ -1,3 +1,3 @@
class Pry
VERSION = "0.5.0pre2"
VERSION = "0.5.0pre4"
end