pry 0.2.5pre2 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,13 +8,14 @@ _attach an irb-like session to any object at runtime_
8
8
  Pry is a simple Ruby REPL (Read-Eval-Print-Loop) that specializes in the interactive
9
9
  manipulation of objects during the running of a program.
10
10
 
11
- It is not based on the IRB codebase and is small, at around 260 LOC.
11
+ It is not based on the IRB codebase, and implements some unique REPL
12
+ commands such as `show_method` and `jump_to`
12
13
 
13
14
  * Install the [gem](https://rubygems.org/gems/pry): `gem install pry`
14
15
  * Read the [documentation](http://rdoc.info/github/banister/pry/master/file/README.markdown)
15
16
  * See the [source code](http://github.com/banister/pry)
16
17
 
17
- example: Interacting with an object at runtime
18
+ Example: Interacting with an object at runtime
18
19
  ---------------------------------------
19
20
 
20
21
  With the `Pry.start()` method we can pry (open an irb-like session) on
@@ -62,7 +63,7 @@ OR
62
63
  beginning Pry session for 6
63
64
  pry(6)>
64
65
 
65
- example: Pry sessions can nest arbitrarily deep so we can pry on objects inside objects:
66
+ Example: Pry sessions can nest arbitrarily deep so we can pry on objects inside objects:
66
67
  ----------------------------------------------------------------------------------------
67
68
 
68
69
  Here we will begin Pry at top-level, then pry on a class and then on
@@ -137,7 +138,7 @@ uses (such as implementing a quake-like console for games, for example). Here is
137
138
  list of Pry's features along with some of its limitations given at the
138
139
  end.
139
140
 
140
- Features:
141
+ ####Features:
141
142
 
142
143
  * Pry can be invoked at any time and on any object in the running program.
143
144
  * Pry sessions can nest arbitrarily deeply -- to go back one level of nesting type 'exit' or 'quit' or 'back'
@@ -145,45 +146,40 @@ Features:
145
146
  * Pry has multi-line support built in.
146
147
  * Pry gives good control over nested sessions (important when exploring complicated runtime state)
147
148
  * Pry is not based on the IRB codebase.
148
- * Pry is small; around 260 LOC.
149
- * Pry implements all the methods in the REPL chain separately: `Pry.r`
150
- for reading; `Pry.re` for eval; `Pry.rep` for printing; and `Pry.repl`
151
- for the loop (`Pry.start` is simply an alias for `Pry.repl`). You can
149
+ * Pry uses [RubyParser](https://github.com/seattlerb/ruby_parser) to
150
+ validate expressions in 1.8, and [Ripper](http://rdoc.info/docs/ruby-core/1.9.2/Ripper) for 1.9.
151
+ * Pry implements all the methods in the REPL chain separately: `Pry#r`
152
+ for reading; `Pry#re` for eval; `Pry#rep` for printing; and `Pry#repl`
153
+ for the loop (`Pry.start` simply wraps `Pry.new.repl`). You can
152
154
  invoke any of these methods directly depending on exactly what aspect of the functionality you need.
153
155
 
154
- Limitations:
156
+ ####Limitations:
155
157
 
156
158
  * Pry does not pretend to be a replacement for `irb`,
157
159
  and so does not have an executable. It is designed to be used by
158
160
  other programs, not on its own. For a full-featured `irb` replacement
159
161
  see [ripl](https://github.com/cldwalker/ripl)
160
- * Although Pry works fine in Ruby 1.9, only Ruby 1.8 syntax is
161
- supported. This is because Pry uses the
162
- [RubyParser](https://github.com/seattlerb/ruby_parser)
163
- gem internally to validate expressions, and RubyParser, as yet, only parses Ruby 1.8
164
- code. In practice this usually just means you cannot use the new
165
- hash literal syntax (this: syntax) or the 'stabby lambda' syntax
166
- (->).
162
+ * Pry's `show_method` and `show_instance_method` commands do not work
163
+ in Ruby 1.8.
167
164
 
168
165
  Commands
169
166
  -----------
170
167
 
171
168
  ### The Pry API:
172
169
 
173
- * `Pry.start()` and `Pry.into()` and `Pry.repl()` are all aliases of
174
- oneanother. They all start a Read-Eval-Print-Loop on the object they
175
- receive as a parameter. In the case of no parameter they operate on
176
- top-level (main). They can receive any object or a `Binding`
177
- object as parameter.
170
+ * `Pry.start()` Starts a Read-Eval-Print-Loop on the object it
171
+ receives as a parameter. In the case of no parameter it operates on
172
+ top-level (main). It can receive any object or a `Binding`
173
+ object as parameter. `Pry.start()` is implemented as `Pry.new.repl()`
178
174
  * `obj.pry` and `pry(obj)` may also be used as alternative syntax to `Pry.start(obj)`
179
- * If, for some reason you do not want to 'loop' then use `Pry.rep()`; it
175
+ * If, for some reason you do not want to 'loop' then use `Pry.new.rep()`; it
180
176
  only performs the Read-Eval-Print section of the REPL - it ends the
181
177
  session after just one line of input. It takes the same parameters as
182
- `Pry.repl()`
183
- * Likewise `Pry.re()` only performs the Read-Eval section of the REPL,
178
+ `Pry#repl()`
179
+ * Likewise `Pry#re()` only performs the Read-Eval section of the REPL,
184
180
  it returns the result of the evaluation or an Exception object in
185
- case of error. It also takes the same parameters as `Pry.repl()`
186
- * Similarly `Pry.r()` only performs the Read section of the REPL, only
181
+ case of error. It also takes the same parameters as `Pry#repl()`
182
+ * Similarly `Pry#r()` only performs the Read section of the REPL, only
187
183
  returning the Ruby expression (as a string). It takes the same parameters as all the others.
188
184
 
189
185
  ### Session commands
@@ -202,6 +198,13 @@ If you want to access a method of the same name, prefix the invocation by whites
202
198
  * `exit` or `quit` or `back` will end the current Pry session and go
203
199
  back to the calling process or back one level of nesting (if there
204
200
  are nested sessions).
201
+ * `ls` returns a list of local variables and instance variables in the
202
+ current scope
203
+ * `cd <var>` starts a `Pry` session on the variable <var>. E.g `cd @x`
204
+ * `show_method <methname>` Displays the sourcecode for the method
205
+ <methname>. E.g `show_method hello`
206
+ * `show_instance_method <methname>` Displays the sourcecode for the
207
+ instance method <methname>. E.g `show_instance_method goodbye`
205
208
  * `exit_program` or `quit_program` will end the currently running
206
209
  program.
207
210
  * `nesting` shows Pry nesting information.
data/Rakefile CHANGED
@@ -7,7 +7,7 @@ require "#{direc}/lib/pry/version"
7
7
 
8
8
  CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
9
9
  CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
10
- "ext/**/*~", "ext/**/*#*", "ext/**/*.obj",
10
+ "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*#*", "**/*#*.*",
11
11
  "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
12
12
 
13
13
  def apply_spec_defaults(s)
@@ -20,6 +20,7 @@ def apply_spec_defaults(s)
20
20
  s.description = s.summary
21
21
  s.require_path = 'lib'
22
22
  s.add_dependency("ruby_parser",">=2.0.5")
23
+ s.add_dependency("method_source",">=0.1.4")
23
24
  s.homepage = "http://banisterfiend.wordpress.com"
24
25
  s.has_rdoc = 'yard'
25
26
  s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb",
data/lib/pry.rb CHANGED
@@ -4,6 +4,8 @@
4
4
  direc = File.dirname(__FILE__)
5
5
 
6
6
  require 'ruby_parser'
7
+ require 'method_source'
8
+ require 'stringio'
7
9
  require "#{direc}/pry/version"
8
10
  require "#{direc}/pry/input"
9
11
  require "#{direc}/pry/output"
@@ -15,7 +17,7 @@ class Pry
15
17
 
16
18
  def self.view(obj)
17
19
  case obj
18
- when String, Symbol, nil
20
+ when String, Array, Hash, Symbol, nil
19
21
  obj.inspect
20
22
  else
21
23
  obj.to_s
@@ -65,7 +67,6 @@ class Pry
65
67
  def nesting=(v)
66
68
  self.class.nesting = v
67
69
  end
68
-
69
70
 
70
71
  # loop
71
72
  def repl(target=TOPLEVEL_BINDING)
@@ -107,6 +108,8 @@ class Pry
107
108
  target = binding_for(target)
108
109
  Pry.last_result = target.eval r(target)
109
110
  target.eval("_ = Pry.last_result")
111
+ rescue SystemExit => e
112
+ exit
110
113
  rescue Exception => e
111
114
  e
112
115
  end
@@ -145,22 +148,27 @@ class Pry
145
148
  eval_string.clear
146
149
  when "exit_all"
147
150
  throw(:breakout, 0)
148
- when "exit", "quit", "back"
151
+ when "exit", "quit", "back", /^cd\s*\.\./
149
152
  output.exit
150
153
  throw(:breakout, nesting.level)
151
- when /show_method\s*(\w*)/
154
+ when "ls"
155
+ output.ls(target)
156
+ eval_string.clear
157
+ when /^cd\s+(.+)/
158
+ obj = $~.captures.first
159
+ target.eval("#{obj}.pry")
160
+ eval_string.clear
161
+ when /^show_method\s*(.+)/
152
162
  meth_name = ($~.captures).first
153
- file, line = target.eval("method(:#{meth_name}).source_location")
154
- tp = Pry.new.tap { |v| v.input = SourceInput.new(file, line) }
155
- tp.r.display
163
+ code = get_method_source(target, meth_name, :method)
164
+ output.show_method code
156
165
  eval_string.clear
157
- when /show_instance_method\s*(\w*)/
166
+ when /^show_instance_method\s*(.+)/
158
167
  meth_name = ($~.captures).first
159
- file, line = target.eval("instance_method(:#{meth_name}).source_location")
160
- tp = Pry.new.tap { |v| v.input = SourceInput.new(file, line) }
161
- tp.r.display
168
+ code = get_method_source(target, meth_name, :instance_method)
169
+ output.show_method code
162
170
  eval_string.clear
163
- when /jump_to\s*(\d*)/
171
+ when /^jump_to\s*(\d*)/
164
172
  break_level = ($~.captures).first.to_i
165
173
  output.jump_to(break_level)
166
174
 
@@ -178,6 +186,10 @@ class Pry
178
186
  end
179
187
  end
180
188
 
189
+ def get_method_source(target, meth_name, kind)
190
+ target.eval("#{kind}(:#{meth_name}).source")
191
+ end
192
+
181
193
  def prompt(eval_string, target, nest)
182
194
  target_self = target.eval('self')
183
195
 
@@ -188,29 +200,23 @@ class Pry
188
200
  end
189
201
  end
190
202
 
191
- def valid_expression?(code)
192
- test_bed = Object.new.instance_eval { binding }
193
-
194
- begin
195
- test_bed.eval(code)
196
- rescue Exception => e
197
- case e
198
- when SyntaxError
199
- case e.message
200
- when /(parse|syntax) error.*?\$end/i, /unterminated/i
201
- return false
202
- end
203
- end
203
+ if RUBY_VERSION =~ /1.9/
204
+ require 'ripper'
205
+
206
+ def valid_expression?(code)
207
+ !!Ripper::SexpBuilder.new(code).parse
204
208
  end
205
- true
206
- end
207
-
208
- def old_valid_expression?(code)
209
- RubyParser.new.parse(code)
210
- rescue Racc::ParseError, SyntaxError
211
- false
209
+
212
210
  else
213
- true
211
+
212
+ def valid_expression?(code)
213
+ RubyParser.new.parse(code)
214
+ rescue Racc::ParseError, SyntaxError
215
+ false
216
+ else
217
+ true
218
+ end
219
+
214
220
  end
215
221
 
216
222
  def binding_for(target)
@@ -2,6 +2,8 @@ require 'readline'
2
2
 
3
3
  class Pry
4
4
  class Input
5
+ trap('INT') { exit }
6
+
5
7
  def read(prompt)
6
8
  Readline.readline(prompt, true)
7
9
  end
@@ -29,6 +29,10 @@ class Pry
29
29
  puts "status Show status information"
30
30
  puts "! Refresh the REPL"
31
31
  puts "nesting Show nesting information"
32
+ puts "ls Show the list of variables in the current scope"
33
+ puts "cd <var> Start a Pry session on <var> (use `cd ..` to go back)"
34
+ puts "show_method <methname> Show the sourcecode for the method <method_name>"
35
+ puts "show_instance_method <methname> Show the sourcecode for the instance method <method_name>"
32
36
  puts "exit/quit/back End the current Pry session"
33
37
  puts "exit_all End all nested Pry sessions"
34
38
  puts "exit_program/quit_program End the current program"
@@ -52,10 +56,18 @@ class Pry
52
56
  puts "--"
53
57
  puts "Receiver: #{Pry.view(target.eval('self'))}"
54
58
  puts "Nesting level: #{nesting.level}"
55
- puts "Local variables: #{Pry.view(target.eval("local_variables"))}"
59
+ puts "Local variables: #{target.eval('Pry.view(local_variables)')}"
56
60
  puts "Last result: #{Pry.view(Pry.last_result)}"
57
61
  end
58
62
 
63
+ def ls(target)
64
+ puts "#{target.eval('Pry.view(local_variables + instance_variables)')}"
65
+ end
66
+
67
+ def show_method(code)
68
+ code.display
69
+ end
70
+
59
71
  def warn_already_at_level(nesting_level)
60
72
  puts "Already at nesting level #{nesting_level}"
61
73
  end
@@ -1,3 +1,3 @@
1
1
  class Pry
2
- VERSION = "0.2.5pre2"
2
+ VERSION = "0.2.6"
3
3
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: true
4
+ prerelease: false
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 5pre2
9
- version: 0.2.5pre2
8
+ - 6
9
+ version: 0.2.6
10
10
  platform: ruby
11
11
  authors:
12
12
  - John Mair (banisterfiend)
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-12-15 00:00:00 +13:00
17
+ date: 2010-12-17 00:00:00 +13:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,6 +32,21 @@ dependencies:
32
32
  version: 2.0.5
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: method_source
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 1
46
+ - 4
47
+ version: 0.1.4
48
+ type: :runtime
49
+ version_requirements: *id002
35
50
  description: attach an irb-like session to any object at runtime
36
51
  email: jrmair@gmail.com
37
52
  executables: []
@@ -68,13 +83,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
68
83
  required_rubygems_version: !ruby/object:Gem::Requirement
69
84
  none: false
70
85
  requirements:
71
- - - ">"
86
+ - - ">="
72
87
  - !ruby/object:Gem::Version
73
88
  segments:
74
- - 1
75
- - 3
76
- - 1
77
- version: 1.3.1
89
+ - 0
90
+ version: "0"
78
91
  requirements: []
79
92
 
80
93
  rubyforge_project: