pry 0.6.7pre4 → 0.6.7

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -1,103 +1,103 @@
1
- dlext = Config::CONFIG['DLEXT']
2
- direc = File.dirname(__FILE__)
3
-
4
- require 'rake/clean'
5
- require 'rake/gempackagetask'
6
- require "#{direc}/lib/pry/version"
7
-
8
- CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
9
- CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
10
- "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*#*", "**/*#*.*",
11
- "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
12
-
13
- def apply_spec_defaults(s)
14
- s.name = "pry"
15
- s.summary = "attach an irb-like session to any object at runtime"
16
- s.version = Pry::VERSION
17
- s.date = Time.now.strftime '%Y-%m-%d'
18
- s.author = "John Mair (banisterfiend)"
19
- s.email = 'jrmair@gmail.com'
20
- s.description = s.summary
21
- s.require_path = 'lib'
22
- s.add_dependency("ruby_parser",">=2.0.5")
23
- s.add_dependency("coderay",">=0.9.7")
24
- s.add_development_dependency("bacon",">=1.1.0")
25
- s.homepage = "http://banisterfiend.wordpress.com"
26
- s.has_rdoc = 'yard'
27
- s.executables = ["pry"]
28
- s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb", "examples/**/*.rb",
29
- "test/*.rb", "CHANGELOG", "LICENSE", "README.markdown", "Rakefile", ".gemtest"]
30
- end
31
-
32
- task :test do
33
- sh "bacon -k #{direc}/test/test.rb"
34
- end
35
-
36
- desc "run pry"
37
- task :pry do
38
- require "#{direc}/lib/pry.rb"
39
- Pry.start
40
- end
41
-
42
- desc "show pry version"
43
- task :version do
44
- puts "Pry version: #{Pry::VERSION}"
45
- end
46
-
47
- namespace :ruby do
48
- spec = Gem::Specification.new do |s|
49
- apply_spec_defaults(s)
50
- s.add_dependency("method_source",">=0.3.4")
51
- s.platform = Gem::Platform::RUBY
52
- end
53
-
54
- Rake::GemPackageTask.new(spec) do |pkg|
55
- pkg.need_zip = false
56
- pkg.need_tar = false
57
- end
58
- end
59
-
60
- [:mingw32, :mswin32].each do |v|
61
- namespace v do
62
- spec = Gem::Specification.new do |s|
63
- apply_spec_defaults(s)
64
- s.add_dependency("method_source",">=0.3.4")
65
- s.add_dependency("win32console", ">=1.3.0")
66
- s.platform = "i386-#{v}"
67
- end
68
-
69
- Rake::GemPackageTask.new(spec) do |pkg|
70
- pkg.need_zip = false
71
- pkg.need_tar = false
72
- end
73
- end
74
- end
75
-
76
- namespace :jruby do
77
- spec = Gem::Specification.new do |s|
78
- apply_spec_defaults(s)
79
- s.add_dependency("method_source","=0.2.0")
80
- s.platform = "java"
81
- end
82
-
83
- Rake::GemPackageTask.new(spec) do |pkg|
84
- pkg.need_zip = false
85
- pkg.need_tar = false
86
- end
87
- end
88
-
89
-
90
- desc "build all platform gems at once"
91
- task :gems => [:rmgems, "ruby:gem", "jruby:gem", "mswin32:gem", "mingw32:gem"]
92
-
93
- desc "remove all platform gems"
94
- task :rmgems => ["ruby:clobber_package"]
95
-
96
- desc "build and push latest gems"
97
- task :pushgems => :gems do
98
- chdir("#{direc}/pkg") do
99
- Dir["*.gem"].each do |gemfile|
100
- sh "gem push #{gemfile}"
101
- end
102
- end
103
- end
1
+ dlext = Config::CONFIG['DLEXT']
2
+ direc = File.dirname(__FILE__)
3
+
4
+ require 'rake/clean'
5
+ require 'rake/gempackagetask'
6
+ require "#{direc}/lib/pry/version"
7
+
8
+ CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
9
+ CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
10
+ "ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*#*", "**/*#*.*",
11
+ "ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake")
12
+
13
+ def apply_spec_defaults(s)
14
+ s.name = "pry"
15
+ s.summary = "attach an irb-like session to any object at runtime"
16
+ s.version = Pry::VERSION
17
+ s.date = Time.now.strftime '%Y-%m-%d'
18
+ s.author = "John Mair (banisterfiend)"
19
+ s.email = 'jrmair@gmail.com'
20
+ s.description = s.summary
21
+ s.require_path = 'lib'
22
+ s.add_dependency("ruby_parser",">=2.0.5")
23
+ s.add_dependency("coderay",">=0.9.7")
24
+ s.add_development_dependency("bacon",">=1.1.0")
25
+ s.homepage = "http://banisterfiend.wordpress.com"
26
+ s.has_rdoc = 'yard'
27
+ s.executables = ["pry"]
28
+ s.files = Dir["ext/**/extconf.rb", "ext/**/*.h", "ext/**/*.c", "lib/**/*.rb", "examples/**/*.rb",
29
+ "test/*.rb", "CHANGELOG", "LICENSE", "README.markdown", "Rakefile", ".gemtest"]
30
+ end
31
+
32
+ task :test do
33
+ sh "bacon -k #{direc}/test/test.rb"
34
+ end
35
+
36
+ desc "run pry"
37
+ task :pry do
38
+ require "#{direc}/lib/pry.rb"
39
+ Pry.start
40
+ end
41
+
42
+ desc "show pry version"
43
+ task :version do
44
+ puts "Pry version: #{Pry::VERSION}"
45
+ end
46
+
47
+ namespace :ruby do
48
+ spec = Gem::Specification.new do |s|
49
+ apply_spec_defaults(s)
50
+ s.add_dependency("method_source",">=0.3.4")
51
+ s.platform = Gem::Platform::RUBY
52
+ end
53
+
54
+ Rake::GemPackageTask.new(spec) do |pkg|
55
+ pkg.need_zip = false
56
+ pkg.need_tar = false
57
+ end
58
+ end
59
+
60
+ [:mingw32, :mswin32].each do |v|
61
+ namespace v do
62
+ spec = Gem::Specification.new do |s|
63
+ apply_spec_defaults(s)
64
+ s.add_dependency("method_source",">=0.3.4")
65
+ s.add_dependency("win32console", ">=1.3.0")
66
+ s.platform = "i386-#{v}"
67
+ end
68
+
69
+ Rake::GemPackageTask.new(spec) do |pkg|
70
+ pkg.need_zip = false
71
+ pkg.need_tar = false
72
+ end
73
+ end
74
+ end
75
+
76
+ namespace :jruby do
77
+ spec = Gem::Specification.new do |s|
78
+ apply_spec_defaults(s)
79
+ s.add_dependency("method_source","=0.2.0")
80
+ s.platform = "java"
81
+ end
82
+
83
+ Rake::GemPackageTask.new(spec) do |pkg|
84
+ pkg.need_zip = false
85
+ pkg.need_tar = false
86
+ end
87
+ end
88
+
89
+
90
+ desc "build all platform gems at once"
91
+ task :gems => [:rmgems, "ruby:gem", "jruby:gem", "mswin32:gem", "mingw32:gem"]
92
+
93
+ desc "remove all platform gems"
94
+ task :rmgems => ["ruby:clobber_package"]
95
+
96
+ desc "build and push latest gems"
97
+ task :pushgems => :gems do
98
+ chdir("#{direc}/pkg") do
99
+ Dir["*.gem"].each do |gemfile|
100
+ sh "gem push #{gemfile}"
101
+ end
102
+ end
103
+ end
data/bin/pry CHANGED
@@ -1,82 +1,82 @@
1
- #!/usr/bin/env ruby
2
-
3
- # (C) John Mair (banisterfiend)
4
- # MIT license
5
-
6
- begin
7
- require 'pry'
8
- rescue LoadError
9
- require 'rubygems'
10
- require 'pry'
11
- end
12
- require 'optparse'
13
-
14
- # defaults
15
- options = {
16
- :context_string => "TOPLEVEL_BINDING",
17
- :loadrc => true
18
- }
19
-
20
- OptionParser.new do |opts|
21
- opts.banner = %{Usage: pry [OPTIONS]
22
- Start a Pry session.
23
- See: `https://github.com/banister` for more information.
24
- --
25
- }
26
- opts.on("-r", "--require FILE", "`require` a Ruby script at startup.") do |file|
27
- require file
28
- end
29
-
30
- opts.on("-e", "--exec CODE", "A line of Ruby code to execute in context before the session starts.") do |code|
31
- options[:code] = code
32
- end
33
-
34
- opts.on("-f", "Suppress loading of ~/.pryrc") do
35
- options[:loadrc] = false
36
- end
37
-
38
- opts.on("--color", "Start session with syntax highlighting on.") do
39
- Pry.color = true
40
- end
41
-
42
- opts.on("--simple-prompt", "Simple prompt mode.") do
43
- Pry.prompt = Pry::SIMPLE_PROMPT
44
- end
45
-
46
- opts.on("-I LOADPATH", "Specify $LOAD_PATH directory.") do |load_path|
47
- $LOAD_PATH << load_path
48
- end
49
-
50
- opts.on("-v", "--version", "Display the Pry version.") do
51
- puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}"
52
- exit
53
- end
54
-
55
- opts.on("-c", "--context CONTEXT",
56
- "Start the session in the specified context. Equivalent to `context.pry` in a session.") do |context|
57
-
58
- # save the context name
59
- options[:context_string] = context
60
- end
61
-
62
- opts.on_tail("-h", "--help", "This message.") do
63
- puts opts
64
- exit
65
- end
66
- end.parse!
67
-
68
- rcpath = File.expand_path("~/.pryrc")
69
-
70
- # load ~/.pryrc, if not suppressed with -f option
71
- load rcpath if File.exists?(rcpath) && options[:loadrc]
72
-
73
- # create the actual context
74
- context = Pry.binding_for(eval(options[:context_string]))
75
-
76
- # run code passed with `-e`, if there is any.
77
- if options[:code]
78
- Pry.new(:input => StringIO.new(options[:code]), :print => proc {}).rep(context)
79
- end
80
-
81
- # start the session
82
- context.pry
1
+ #!/usr/bin/env ruby
2
+
3
+ # (C) John Mair (banisterfiend)
4
+ # MIT license
5
+
6
+ begin
7
+ require 'pry'
8
+ rescue LoadError
9
+ require 'rubygems'
10
+ require 'pry'
11
+ end
12
+ require 'optparse'
13
+
14
+ # defaults
15
+ options = {
16
+ :context_string => "TOPLEVEL_BINDING",
17
+ :loadrc => true
18
+ }
19
+
20
+ OptionParser.new do |opts|
21
+ opts.banner = %{Usage: pry [OPTIONS]
22
+ Start a Pry session.
23
+ See: `https://github.com/banister` for more information.
24
+ --
25
+ }
26
+ opts.on("-r", "--require FILE", "`require` a Ruby script at startup.") do |file|
27
+ require file
28
+ end
29
+
30
+ opts.on("-e", "--exec CODE", "A line of Ruby code to execute in context before the session starts.") do |code|
31
+ options[:code] = code
32
+ end
33
+
34
+ opts.on("-f", "Suppress loading of ~/.pryrc") do
35
+ options[:loadrc] = false
36
+ end
37
+
38
+ opts.on("--color", "Start session with syntax highlighting on.") do
39
+ Pry.color = true
40
+ end
41
+
42
+ opts.on("--simple-prompt", "Simple prompt mode.") do
43
+ Pry.prompt = Pry::SIMPLE_PROMPT
44
+ end
45
+
46
+ opts.on("-I LOADPATH", "Specify $LOAD_PATH directory.") do |load_path|
47
+ $LOAD_PATH << load_path
48
+ end
49
+
50
+ opts.on("-v", "--version", "Display the Pry version.") do
51
+ puts "Pry version #{Pry::VERSION} on Ruby #{RUBY_VERSION}"
52
+ exit
53
+ end
54
+
55
+ opts.on("-c", "--context CONTEXT",
56
+ "Start the session in the specified context. Equivalent to `context.pry` in a session.") do |context|
57
+
58
+ # save the context name
59
+ options[:context_string] = context
60
+ end
61
+
62
+ opts.on_tail("-h", "--help", "This message.") do
63
+ puts opts
64
+ exit
65
+ end
66
+ end.parse!
67
+
68
+ rcpath = File.expand_path("~/.pryrc")
69
+
70
+ # load ~/.pryrc, if not suppressed with -f option
71
+ load rcpath if File.exists?(rcpath) && options[:loadrc]
72
+
73
+ # create the actual context
74
+ context = Pry.binding_for(eval(options[:context_string]))
75
+
76
+ # run code passed with `-e`, if there is any.
77
+ if options[:code]
78
+ Pry.new(:input => StringIO.new(options[:code]), :print => proc {}).rep(context)
79
+ end
80
+
81
+ # start the session
82
+ context.pry
data/lib/pry.rb CHANGED
@@ -1,32 +1,32 @@
1
- # (C) John Mair (banisterfiend) 2011
2
- # MIT License
3
-
4
- direc = File.dirname(__FILE__)
5
-
6
- $LOAD_PATH << File.expand_path(direc)
7
-
8
- require "method_source"
9
- require 'shellwords'
10
- require "readline"
11
- require "stringio"
12
- require "coderay"
13
-
14
- if RUBY_PLATFORM =~ /mswin/ || RUBY_PLATFORM =~ /mingw/
15
- begin
16
- require 'win32console'
17
- rescue LoadError
18
- $stderr.puts "Need to `gem install win32console`"
19
- exit 1
20
- end
21
- end
22
-
23
- require "pry/version"
24
- require "pry/hooks"
25
- require "pry/print"
26
- require "pry/command_base"
27
- require "pry/commands"
28
- require "pry/prompts"
29
- require "pry/completion"
30
- require "pry/core_extensions"
31
- require "pry/pry_class"
32
- require "pry/pry_instance"
1
+ # (C) John Mair (banisterfiend) 2011
2
+ # MIT License
3
+
4
+ direc = File.dirname(__FILE__)
5
+
6
+ $LOAD_PATH << File.expand_path(direc)
7
+
8
+ require "method_source"
9
+ require 'shellwords'
10
+ require "readline"
11
+ require "stringio"
12
+ require "coderay"
13
+
14
+ if RUBY_PLATFORM =~ /mswin/ || RUBY_PLATFORM =~ /mingw/
15
+ begin
16
+ require 'win32console'
17
+ rescue LoadError
18
+ $stderr.puts "Need to `gem install win32console`"
19
+ exit 1
20
+ end
21
+ end
22
+
23
+ require "pry/version"
24
+ require "pry/hooks"
25
+ require "pry/print"
26
+ require "pry/command_base"
27
+ require "pry/commands"
28
+ require "pry/prompts"
29
+ require "pry/completion"
30
+ require "pry/core_extensions"
31
+ require "pry/pry_class"
32
+ require "pry/pry_instance"
@@ -1,577 +1,577 @@
1
- require "optparse"
2
- require "method_source"
3
- require "pry/command_base"
4
- require "pry/pry_instance"
5
-
6
- class Pry
7
-
8
- # Default commands used by Pry.
9
- class Commands < CommandBase
10
-
11
- # We make this a lambda to avoid documenting it
12
- meth_name_from_binding = lambda do |b|
13
- meth_name = b.eval('__method__')
14
- if [nil, :__binding__, :__binding_impl__].include?(meth_name)
15
- nil
16
- else
17
- meth_name
18
- end
19
- end
20
-
21
- check_for_dynamically_defined_method = lambda do |file|
22
- if file =~ /(\(.*\))|<.*>/
23
- raise "Cannot retrieve source for dynamically defined method."
24
- end
25
- end
26
-
27
- remove_first_word = lambda do |text|
28
- text.split.drop(1).join(' ')
29
- end
30
-
31
- command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
32
- output.puts "Input buffer cleared!"
33
- opts[:eval_string].clear
34
- end
35
-
36
- command "!pry", "Start a Pry session on current self; this even works mid-expression." do
37
- Pry.start(target)
38
- end
39
-
40
- command "exit-program", "End the current program. Aliases: quit-program" do
41
- exit
42
- end
43
-
44
- alias_command "quit-program", "exit-program", ""
45
-
46
- command "toggle-color", "Toggle syntax highlighting." do
47
- Pry.color = !Pry.color
48
- output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
49
- end
50
-
51
- command "simple-prompt", "Toggle the simple prompt." do
52
- case Pry.active_instance.prompt
53
- when Pry::SIMPLE_PROMPT
54
- Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
55
- else
56
- Pry.active_instance.prompt = Pry::SIMPLE_PROMPT
57
- end
58
- end
59
-
60
- command "nesting", "Show nesting information." do
61
- nesting = opts[:nesting]
62
-
63
- output.puts "Nesting status:"
64
- output.puts "--"
65
- nesting.each do |level, obj|
66
- if level == 0
67
- output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
68
- else
69
- output.puts "#{level}. #{Pry.view_clip(obj)}"
70
- end
71
- end
72
- end
73
-
74
- command "status", "Show status information." do
75
- nesting = opts[:nesting]
76
-
77
- output.puts "Status:"
78
- output.puts "--"
79
- output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
80
- output.puts "Nesting level: #{nesting.level}"
81
- output.puts "Pry version: #{Pry::VERSION}"
82
- output.puts "Ruby version: #{RUBY_VERSION}"
83
-
84
- mn = meth_name_from_binding.call(target)
85
- output.puts "Current method: #{mn ? mn : "N/A"}"
86
- output.puts "Pry instance: #{Pry.active_instance}"
87
- output.puts "Last result: #{Pry.view(Pry.last_result)}"
88
- end
89
-
90
- command "version", "Show Pry version." do
91
- output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
92
- end
93
-
94
- command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
95
- str = remove_first_word.call(opts[:val])
96
- throw(:breakout, [0, target.eval(str)])
97
- end
98
-
99
- alias_command "!@", "exit-all", ""
100
-
101
- command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
102
- options = {}
103
-
104
- # Set target local to the default -- note that we can set a different target for
105
- # ls if we like: e.g ls my_var
106
- target = target()
107
-
108
- OptionParser.new do |opts|
109
- opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
110
- List information about VAR (the current context by default).
111
- Shows local and instance variables by default.
112
- --
113
- }
114
- opts.on("-g", "--globals", "Display global variables.") do
115
- options[:g] = true
116
- end
117
-
118
- opts.on("-c", "--constants", "Display constants.") do
119
- options[:c] = true
120
- end
121
-
122
- opts.on("-l", "--locals", "Display locals.") do
123
- options[:l] = true
124
- end
125
-
126
- opts.on("-i", "--ivars", "Display instance variables.") do
127
- options[:i] = true
128
- end
129
-
130
- opts.on("-k", "--class-vars", "Display class variables.") do
131
- options[:k] = true
132
- end
133
-
134
- opts.on("-m", "--methods", "Display methods (public methods by default).") do
135
- options[:m] = true
136
- end
137
-
138
- opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
139
- options[:M] = true
140
- end
141
-
142
- opts.on("-P", "--public", "Display public methods (with -m).") do
143
- options[:P] = true
144
- end
145
-
146
- opts.on("-r", "--protected", "Display protected methods (with -m).") do
147
- options[:r] = true
148
- end
149
-
150
- opts.on("-p", "--private", "Display private methods (with -m).") do
151
- options[:p] = true
152
- end
153
-
154
- opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
155
- options[:s] = true
156
- end
157
-
158
- opts.on("-a", "--all", "Display all types of entries.") do
159
- options[:a] = true
160
- end
161
-
162
- opts.on("-v", "--verbose", "Verbose ouput.") do
163
- options[:v] = true
164
- end
165
-
166
- opts.on_tail("-h", "--help", "Show this message.") do
167
- output.puts opts
168
- options[:h] = true
169
- end
170
- end.order(args) do |new_target|
171
- target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
172
- end
173
-
174
- # exit if we've displayed help
175
- next if options[:h]
176
-
177
- # default is locals/ivars/class vars.
178
- # Only occurs when no options or when only option is verbose
179
- options.merge!({
180
- :l => true,
181
- :i => true,
182
- :k => true
183
- }) if options.empty? || (options.size == 1 && options[:v])
184
-
185
- # Display public methods by default if -m or -M switch is used.
186
- options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r])
187
-
188
- info = {}
189
- target_self = target.eval('self')
190
-
191
- # ensure we have a real boolean and not a `nil` (important when
192
- # interpolating in the string)
193
- options[:s] = !!options[:s]
194
-
195
- # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
196
- i = -1
197
-
198
- # Start collecting the entries selected by the user
199
- info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
200
- info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
201
-
202
- info["class variables"] = [if target_self.is_a?(Module)
203
- Array(target.eval("class_variables")).sort
204
- else
205
- Array(target.eval("self.class.class_variables")).sort
206
- end, i += 1] if options[:k] || options[:a]
207
-
208
- info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
209
-
210
- info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
211
-
212
- info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
213
-
214
- info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
215
-
216
- info["public instance methods"] = [Array(target.eval("public_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:P]) || options[:a])
217
-
218
- info["protected instance methods"] = [Array(target.eval("protected_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:r]) || options[:a])
219
-
220
- info["private instance methods"] = [Array(target.eval("private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:p]) || options[:a])
221
-
222
- # dealing with 1.8/1.9 compatibility issues :/
223
- csuper = options[:s]
224
- if Module.method(:constants).arity == 0
225
- csuper = nil
226
- end
227
-
228
- info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
229
- target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
230
-
231
- # verbose output?
232
- if options[:v]
233
-
234
- # verbose
235
- info.sort_by { |k, v| v.last }.each do |k, v|
236
- if !v.first.empty?
237
- output.puts "#{k}:\n--"
238
- if Pry.color
239
- output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
240
- else
241
- output.puts Pry.view(v.first)
242
- end
243
- output.puts
244
- end
245
- end
246
-
247
- # plain
248
- else
249
- list = info.values.sort_by { |v| v.last }.map { |v| v.first }.inject(&:+)
250
- if Pry.color
251
- output.puts CodeRay.scan(Pry.view(list), :ruby).term
252
- else
253
- output.puts Pry.view(list)
254
- end
255
- list
256
- end
257
- end
258
-
259
- command "cat-file", "Show output of file FILE" do |file_name|
260
- if !file_name
261
- output.puts "Must provide a file name."
262
- next
263
- end
264
-
265
- contents = File.read(file_name)
266
- output.puts contents
267
- contents
268
- end
269
-
270
- command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
271
- options = {}
272
- target = target()
273
- file_name = nil
274
-
275
- OptionParser.new do |opts|
276
- opts.banner = %{Usage: eval-file [OPTIONS] FILE
277
- Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
278
- e.g: eval-file -c self "hello.rb"
279
- --
280
- }
281
- opts.on("-c", "--context CONTEXT", "Eval the script in the specified context.") do |context|
282
- options[:c] = true
283
- target = Pry.binding_for(target.eval(context))
284
- end
285
-
286
- opts.on_tail("-h", "--help", "This message.") do
287
- output.puts opts
288
- options[:h] = true
289
- end
290
- end.order(args) do |v|
291
- file_name = v
292
- end
293
-
294
- next if options[:h]
295
-
296
- if !file_name
297
- output.puts "You need to specify a file name. Type `eval-file --help` for help"
298
- next
299
- end
300
-
301
- old_constants = Object.constants
302
- if options[:c]
303
- target_self = target.eval('self')
304
- target.eval(File.read(file_name))
305
- output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
306
- else
307
- TOPLEVEL_BINDING.eval(File.read(file_name))
308
- output.puts "--\nEval'd '#{file_name}' at top-level."
309
- end
310
- new_constants = Object.constants - old_constants
311
- output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
312
- end
313
-
314
- command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
315
- if !obj
316
- output.puts "Must provide an object to inspect."
317
- next
318
- end
319
-
320
- output.puts Pry.view(target.eval("#{obj}"))
321
- end
322
-
323
- alias_command "inspect", "cat", ""
324
-
325
- command "cd", "Start a Pry session on VAR (use `cd ..` to go back and `cd /` to return to Pry top-level)", :keep_retval => true do |obj|
326
- if !obj
327
- output.puts "Must provide an object."
328
- next
329
- end
330
-
331
- throw(:breakout, opts[:nesting].level) if obj == ".."
332
-
333
- if obj == "/"
334
- throw(:breakout, 1) if opts[:nesting].level > 0
335
- next
336
- end
337
-
338
- target.eval("#{obj}.pry")
339
- end
340
-
341
- command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
342
- options = {}
343
- target = target()
344
- meth_name = nil
345
-
346
- OptionParser.new do |opts|
347
- opts.banner = %{Usage: show-doc [OPTIONS] [METH]
348
- Show the comments above method METH. Shows _method_ comments (rather than instance methods) by default.
349
- e.g show-doc hello_method
350
- --
351
- }
352
- opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
353
- options[:M] = true
354
- end
355
-
356
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
357
- target = Pry.binding_for(target.eval(context))
358
- end
359
-
360
- opts.on_tail("-h", "--help", "This message.") do
361
- output.puts opts
362
- options[:h] = true
363
- end
364
- end.order(args) do |v|
365
- meth_name = v
366
- end
367
-
368
- next if options[:h]
369
-
370
- if !meth_name
371
- output.puts "You need to specify a method. Type `show-doc --help` for help"
372
- next
373
- end
374
-
375
- begin
376
- if options[:M]
377
- meth = target.eval("instance_method(:#{meth_name})")
378
- else
379
- meth = target.eval("method(:#{meth_name})")
380
- end
381
- rescue
382
- output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
383
- next
384
- end
385
-
386
- doc = meth.comment
387
- file, line = meth.source_location
388
- check_for_dynamically_defined_method.call(file)
389
-
390
- output.puts "--\nFrom #{file} @ line ~#{line}:\n--"
391
-
392
- if Pry.color
393
- doc = CodeRay.scan(doc, :ruby).term
394
- end
395
-
396
- output.puts doc
397
- doc
398
- end
399
-
400
- command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
401
- options = {}
402
- target = target()
403
- meth_name = nil
404
-
405
- OptionParser.new do |opts|
406
- opts.banner = %{Usage: show-method [OPTIONS] [METH]
407
- Show the source for method METH. Shows _method_ source (rather than instance methods) by default.
408
- e.g: show-method hello_method
409
- --
410
- }
411
- opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
412
- options[:M] = true
413
- end
414
-
415
- opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
416
- target = Pry.binding_for(target.eval(context))
417
- end
418
-
419
- opts.on_tail("-h", "--help", "This message.") do
420
- output.puts opts
421
- options[:h] = true
422
- end
423
- end.order(args) do |v|
424
- meth_name = v
425
- end
426
-
427
- next if options[:h]
428
-
429
- # If no method name is given then use current method, if it exists
430
- meth_name = meth_name_from_binding.call(target) if !meth_name
431
-
432
- if !meth_name
433
- output.puts "You need to specify a method. Type `show-method --help` for help"
434
- next
435
- end
436
-
437
- begin
438
- if options[:M]
439
- meth = target.eval("instance_method(:#{meth_name})")
440
- else
441
- meth = target.eval("method(:#{meth_name})")
442
- end
443
- rescue
444
- target_self = target.eval('self')
445
- if !options[:M]&& target_self.is_a?(Module) &&
446
- target_self.method_defined?(meth_name)
447
- output.puts "Did you mean: show-method -M #{meth_name} ?"
448
- end
449
- output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
450
- next
451
- end
452
-
453
- code = meth.source
454
- file, line = meth.source_location
455
- check_for_dynamically_defined_method.call(file)
456
-
457
- output.puts "--\nFrom #{file} @ line #{line}:\n--"
458
-
459
- if Pry.color
460
- code = CodeRay.scan(code, :ruby).term
461
- end
462
-
463
- output.puts code
464
- code
465
- end
466
-
467
- command "show-command", "Show sourcecode for a Pry command, e.g: show-command cd" do |command_name|
468
- if !command_name
469
- output.puts "You must provide a command name."
470
- next
471
- end
472
-
473
- if commands[command_name]
474
- meth = commands[command_name][:action]
475
-
476
- code = meth.source
477
- file, line = meth.source_location
478
- check_for_dynamically_defined_method.call(file)
479
-
480
- output.puts "--\nFrom #{file} @ line #{line}:\n--"
481
-
482
- if Pry.color
483
- code = CodeRay.scan(code, :ruby).term
484
- end
485
-
486
- output.puts code
487
- code
488
- else
489
- output.puts "No such command: #{command_name}."
490
- end
491
- end
492
-
493
- command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
494
- break_level = break_level.to_i
495
- nesting = opts[:nesting]
496
-
497
- case break_level
498
- when nesting.level
499
- output.puts "Already at nesting level #{nesting.level}"
500
- when (0...nesting.level)
501
- throw(:breakout, break_level + 1)
502
- else
503
- max_nest_level = nesting.level - 1
504
- output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
505
- end
506
- end
507
-
508
- command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
509
- str = remove_first_word.call(opts[:val])
510
- throw(:breakout, [opts[:nesting].level, target.eval(str)])
511
- end
512
-
513
- alias_command "quit", "exit", ""
514
- alias_command "back", "exit", ""
515
-
516
- command "game", "" do |highest|
517
- highest = highest ? highest.to_i : 100
518
- num = rand(highest)
519
- output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
520
- count = 0
521
- while(true)
522
- count += 1
523
- str = Readline.readline("game > ", true)
524
- break if str == "." || !str
525
- val = str.to_i
526
- output.puts "Too large!" if val > num
527
- output.puts "Too small!" if val < num
528
- if val == num
529
- output.puts "Well done! You guessed right! It took you #{count} guesses."
530
- break
531
- end
532
- end
533
- end
534
-
535
- command "east-coker", "" do
536
- text = %{
537
- --
538
- Now the light falls
539
- Across the open field, leaving the deep lane
540
- Shuttered with branches, dark in the afternoon,
541
- Where you lean against a bank while a van passes,
542
- And the deep lane insists on the direction
543
- Into the village, in the electric heat
544
- Hypnotised. In a warm haze the sultry light
545
- Is absorbed, not refracted, by grey stone.
546
- The dahlias sleep in the empty silence.
547
- Wait for the early owl.
548
- -- T.S Eliot
549
- }
550
- output.puts text
551
- text
552
- end
553
-
554
- command "cohen-poem", "" do
555
- text = %{
556
- --
557
- When this American woman,
558
- whose thighs are bound in casual red cloth,
559
- comes thundering past my sitting place
560
- like a forest-burning Mongol tribe,
561
- the city is ravished
562
- and brittle buildings of a hundred years
563
- splash into the street;
564
- and my eyes are burnt
565
- for the embroidered Chinese girls,
566
- already old,
567
- and so small between the thin pines
568
- on these enormous landscapes,
569
- that if you turn your head
570
- they are lost for hours.
571
- -- Leonard Cohen
572
- }
573
- output.puts text
574
- text
575
- end
576
- end
577
- end
1
+ require "optparse"
2
+ require "method_source"
3
+ require "pry/command_base"
4
+ require "pry/pry_instance"
5
+
6
+ class Pry
7
+
8
+ # Default commands used by Pry.
9
+ class Commands < CommandBase
10
+
11
+ # We make this a lambda to avoid documenting it
12
+ meth_name_from_binding = lambda do |b|
13
+ meth_name = b.eval('__method__')
14
+ if [nil, :__binding__, :__binding_impl__].include?(meth_name)
15
+ nil
16
+ else
17
+ meth_name
18
+ end
19
+ end
20
+
21
+ check_for_dynamically_defined_method = lambda do |file|
22
+ if file =~ /(\(.*\))|<.*>/
23
+ raise "Cannot retrieve source for dynamically defined method."
24
+ end
25
+ end
26
+
27
+ remove_first_word = lambda do |text|
28
+ text.split.drop(1).join(' ')
29
+ end
30
+
31
+ command "!", "Clear the input buffer. Useful if the parsing process goes wrong and you get stuck in the read loop." do
32
+ output.puts "Input buffer cleared!"
33
+ opts[:eval_string].clear
34
+ end
35
+
36
+ command "!pry", "Start a Pry session on current self; this even works mid-expression." do
37
+ Pry.start(target)
38
+ end
39
+
40
+ command "exit-program", "End the current program. Aliases: quit-program" do
41
+ exit
42
+ end
43
+
44
+ alias_command "quit-program", "exit-program", ""
45
+
46
+ command "toggle-color", "Toggle syntax highlighting." do
47
+ Pry.color = !Pry.color
48
+ output.puts "Syntax highlighting #{Pry.color ? "on" : "off"}"
49
+ end
50
+
51
+ command "simple-prompt", "Toggle the simple prompt." do
52
+ case Pry.active_instance.prompt
53
+ when Pry::SIMPLE_PROMPT
54
+ Pry.active_instance.prompt = Pry::DEFAULT_PROMPT
55
+ else
56
+ Pry.active_instance.prompt = Pry::SIMPLE_PROMPT
57
+ end
58
+ end
59
+
60
+ command "nesting", "Show nesting information." do
61
+ nesting = opts[:nesting]
62
+
63
+ output.puts "Nesting status:"
64
+ output.puts "--"
65
+ nesting.each do |level, obj|
66
+ if level == 0
67
+ output.puts "#{level}. #{Pry.view_clip(obj)} (Pry top level)"
68
+ else
69
+ output.puts "#{level}. #{Pry.view_clip(obj)}"
70
+ end
71
+ end
72
+ end
73
+
74
+ command "status", "Show status information." do
75
+ nesting = opts[:nesting]
76
+
77
+ output.puts "Status:"
78
+ output.puts "--"
79
+ output.puts "Receiver: #{Pry.view_clip(target.eval('self'))}"
80
+ output.puts "Nesting level: #{nesting.level}"
81
+ output.puts "Pry version: #{Pry::VERSION}"
82
+ output.puts "Ruby version: #{RUBY_VERSION}"
83
+
84
+ mn = meth_name_from_binding.call(target)
85
+ output.puts "Current method: #{mn ? mn : "N/A"}"
86
+ output.puts "Pry instance: #{Pry.active_instance}"
87
+ output.puts "Last result: #{Pry.view(Pry.last_result)}"
88
+ end
89
+
90
+ command "version", "Show Pry version." do
91
+ output.puts "Pry version: #{Pry::VERSION} on Ruby #{RUBY_VERSION}."
92
+ end
93
+
94
+ command "exit-all", "End all nested Pry sessions. Accepts optional return value. Aliases: !@" do
95
+ str = remove_first_word.call(opts[:val])
96
+ throw(:breakout, [0, target.eval(str)])
97
+ end
98
+
99
+ alias_command "!@", "exit-all", ""
100
+
101
+ command "ls", "Show the list of vars in the current scope. Type `ls --help` for more info." do |*args|
102
+ options = {}
103
+
104
+ # Set target local to the default -- note that we can set a different target for
105
+ # ls if we like: e.g ls my_var
106
+ target = target()
107
+
108
+ OptionParser.new do |opts|
109
+ opts.banner = %{Usage: ls [OPTIONS] [VAR]\n\
110
+ List information about VAR (the current context by default).
111
+ Shows local and instance variables by default.
112
+ --
113
+ }
114
+ opts.on("-g", "--globals", "Display global variables.") do
115
+ options[:g] = true
116
+ end
117
+
118
+ opts.on("-c", "--constants", "Display constants.") do
119
+ options[:c] = true
120
+ end
121
+
122
+ opts.on("-l", "--locals", "Display locals.") do
123
+ options[:l] = true
124
+ end
125
+
126
+ opts.on("-i", "--ivars", "Display instance variables.") do
127
+ options[:i] = true
128
+ end
129
+
130
+ opts.on("-k", "--class-vars", "Display class variables.") do
131
+ options[:k] = true
132
+ end
133
+
134
+ opts.on("-m", "--methods", "Display methods (public methods by default).") do
135
+ options[:m] = true
136
+ end
137
+
138
+ opts.on("-M", "--instance-methods", "Display instance methods (only relevant to classes and modules).") do
139
+ options[:M] = true
140
+ end
141
+
142
+ opts.on("-P", "--public", "Display public methods (with -m).") do
143
+ options[:P] = true
144
+ end
145
+
146
+ opts.on("-r", "--protected", "Display protected methods (with -m).") do
147
+ options[:r] = true
148
+ end
149
+
150
+ opts.on("-p", "--private", "Display private methods (with -m).") do
151
+ options[:p] = true
152
+ end
153
+
154
+ opts.on("-s", "--super", "Include superclass entries (relevant to constant and methods options).") do
155
+ options[:s] = true
156
+ end
157
+
158
+ opts.on("-a", "--all", "Display all types of entries.") do
159
+ options[:a] = true
160
+ end
161
+
162
+ opts.on("-v", "--verbose", "Verbose ouput.") do
163
+ options[:v] = true
164
+ end
165
+
166
+ opts.on_tail("-h", "--help", "Show this message.") do
167
+ output.puts opts
168
+ options[:h] = true
169
+ end
170
+ end.order(args) do |new_target|
171
+ target = Pry.binding_for(target.eval("#{new_target}")) if !options[:h]
172
+ end
173
+
174
+ # exit if we've displayed help
175
+ next if options[:h]
176
+
177
+ # default is locals/ivars/class vars.
178
+ # Only occurs when no options or when only option is verbose
179
+ options.merge!({
180
+ :l => true,
181
+ :i => true,
182
+ :k => true
183
+ }) if options.empty? || (options.size == 1 && options[:v])
184
+
185
+ # Display public methods by default if -m or -M switch is used.
186
+ options[:P] = true if (options[:m] || options[:M]) && !(options[:p] || options[:r])
187
+
188
+ info = {}
189
+ target_self = target.eval('self')
190
+
191
+ # ensure we have a real boolean and not a `nil` (important when
192
+ # interpolating in the string)
193
+ options[:s] = !!options[:s]
194
+
195
+ # Numbers (e.g 0, 1, 2) are for ordering the hash values in Ruby 1.8
196
+ i = -1
197
+
198
+ # Start collecting the entries selected by the user
199
+ info["local variables"] = [Array(target.eval("local_variables")).sort, i += 1] if options[:l] || options[:a]
200
+ info["instance variables"] = [Array(target.eval("instance_variables")).sort, i += 1] if options[:i] || options[:a]
201
+
202
+ info["class variables"] = [if target_self.is_a?(Module)
203
+ Array(target.eval("class_variables")).sort
204
+ else
205
+ Array(target.eval("self.class.class_variables")).sort
206
+ end, i += 1] if options[:k] || options[:a]
207
+
208
+ info["global variables"] = [Array(target.eval("global_variables")).sort, i += 1] if options[:g] || options[:a]
209
+
210
+ info["public methods"] = [Array(target.eval("public_methods(#{options[:s]})")).uniq.sort, i += 1] if (options[:m] && options[:P]) || options[:a]
211
+
212
+ info["protected methods"] = [Array(target.eval("protected_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:r]) || options[:a]
213
+
214
+ info["private methods"] = [Array(target.eval("private_methods(#{options[:s]})")).sort, i += 1] if (options[:m] && options[:p]) || options[:a]
215
+
216
+ info["public instance methods"] = [Array(target.eval("public_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:P]) || options[:a])
217
+
218
+ info["protected instance methods"] = [Array(target.eval("protected_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:r]) || options[:a])
219
+
220
+ info["private instance methods"] = [Array(target.eval("private_instance_methods(#{options[:s]})")).uniq.sort, i += 1] if target_self.is_a?(Module) && ((options[:M] && options[:p]) || options[:a])
221
+
222
+ # dealing with 1.8/1.9 compatibility issues :/
223
+ csuper = options[:s]
224
+ if Module.method(:constants).arity == 0
225
+ csuper = nil
226
+ end
227
+
228
+ info["constants"] = [Array(target_self.is_a?(Module) ? target.eval("constants(#{csuper})") :
229
+ target.eval("self.class.constants(#{csuper})")).uniq.sort, i += 1] if options[:c] || options[:a]
230
+
231
+ # verbose output?
232
+ if options[:v]
233
+
234
+ # verbose
235
+ info.sort_by { |k, v| v.last }.each do |k, v|
236
+ if !v.first.empty?
237
+ output.puts "#{k}:\n--"
238
+ if Pry.color
239
+ output.puts CodeRay.scan(Pry.view(v.first), :ruby).term
240
+ else
241
+ output.puts Pry.view(v.first)
242
+ end
243
+ output.puts
244
+ end
245
+ end
246
+
247
+ # plain
248
+ else
249
+ list = info.values.sort_by { |v| v.last }.map { |v| v.first }.inject(&:+)
250
+ if Pry.color
251
+ output.puts CodeRay.scan(Pry.view(list), :ruby).term
252
+ else
253
+ output.puts Pry.view(list)
254
+ end
255
+ list
256
+ end
257
+ end
258
+
259
+ command "cat-file", "Show output of file FILE" do |file_name|
260
+ if !file_name
261
+ output.puts "Must provide a file name."
262
+ next
263
+ end
264
+
265
+ contents = File.read(file_name)
266
+ output.puts contents
267
+ contents
268
+ end
269
+
270
+ command "eval-file", "Eval a Ruby script. Type `eval-file --help` for more info." do |*args|
271
+ options = {}
272
+ target = target()
273
+ file_name = nil
274
+
275
+ OptionParser.new do |opts|
276
+ opts.banner = %{Usage: eval-file [OPTIONS] FILE
277
+ Eval a Ruby script at top-level or in the specified context. Defaults to top-level.
278
+ e.g: eval-file -c self "hello.rb"
279
+ --
280
+ }
281
+ opts.on("-c", "--context CONTEXT", "Eval the script in the specified context.") do |context|
282
+ options[:c] = true
283
+ target = Pry.binding_for(target.eval(context))
284
+ end
285
+
286
+ opts.on_tail("-h", "--help", "This message.") do
287
+ output.puts opts
288
+ options[:h] = true
289
+ end
290
+ end.order(args) do |v|
291
+ file_name = v
292
+ end
293
+
294
+ next if options[:h]
295
+
296
+ if !file_name
297
+ output.puts "You need to specify a file name. Type `eval-file --help` for help"
298
+ next
299
+ end
300
+
301
+ old_constants = Object.constants
302
+ if options[:c]
303
+ target_self = target.eval('self')
304
+ target.eval(File.read(file_name))
305
+ output.puts "--\nEval'd '#{file_name}' in the `#{target_self}` context."
306
+ else
307
+ TOPLEVEL_BINDING.eval(File.read(file_name))
308
+ output.puts "--\nEval'd '#{file_name}' at top-level."
309
+ end
310
+ new_constants = Object.constants - old_constants
311
+ output.puts "Brought in the following top-level constants: #{new_constants.inspect}" if !new_constants.empty?
312
+ end
313
+
314
+ command "cat", "Show output of VAR.inspect. Aliases: inspect" do |obj|
315
+ if !obj
316
+ output.puts "Must provide an object to inspect."
317
+ next
318
+ end
319
+
320
+ output.puts Pry.view(target.eval("#{obj}"))
321
+ end
322
+
323
+ alias_command "inspect", "cat", ""
324
+
325
+ command "cd", "Start a Pry session on VAR (use `cd ..` to go back and `cd /` to return to Pry top-level)", :keep_retval => true do |obj|
326
+ if !obj
327
+ output.puts "Must provide an object."
328
+ next
329
+ end
330
+
331
+ throw(:breakout, opts[:nesting].level) if obj == ".."
332
+
333
+ if obj == "/"
334
+ throw(:breakout, 1) if opts[:nesting].level > 0
335
+ next
336
+ end
337
+
338
+ target.eval("#{obj}.pry")
339
+ end
340
+
341
+ command "show-doc", "Show the comments above METH. Type `show-doc --help` for more info." do |*args|
342
+ options = {}
343
+ target = target()
344
+ meth_name = nil
345
+
346
+ OptionParser.new do |opts|
347
+ opts.banner = %{Usage: show-doc [OPTIONS] [METH]
348
+ Show the comments above method METH. Shows _method_ comments (rather than instance methods) by default.
349
+ e.g show-doc hello_method
350
+ --
351
+ }
352
+ opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
353
+ options[:M] = true
354
+ end
355
+
356
+ opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
357
+ target = Pry.binding_for(target.eval(context))
358
+ end
359
+
360
+ opts.on_tail("-h", "--help", "This message.") do
361
+ output.puts opts
362
+ options[:h] = true
363
+ end
364
+ end.order(args) do |v|
365
+ meth_name = v
366
+ end
367
+
368
+ next if options[:h]
369
+
370
+ if !meth_name
371
+ output.puts "You need to specify a method. Type `show-doc --help` for help"
372
+ next
373
+ end
374
+
375
+ begin
376
+ if options[:M]
377
+ meth = target.eval("instance_method(:#{meth_name})")
378
+ else
379
+ meth = target.eval("method(:#{meth_name})")
380
+ end
381
+ rescue
382
+ output.puts "Invalid method name: #{meth_name}. Type `show-doc --help` for help"
383
+ next
384
+ end
385
+
386
+ doc = meth.comment
387
+ file, line = meth.source_location
388
+ check_for_dynamically_defined_method.call(file)
389
+
390
+ output.puts "--\nFrom #{file} @ line ~#{line}:\n--"
391
+
392
+ if Pry.color
393
+ doc = CodeRay.scan(doc, :ruby).term
394
+ end
395
+
396
+ output.puts doc
397
+ doc
398
+ end
399
+
400
+ command "show-method", "Show the source for METH. Type `show-method --help` for more info." do |*args|
401
+ options = {}
402
+ target = target()
403
+ meth_name = nil
404
+
405
+ OptionParser.new do |opts|
406
+ opts.banner = %{Usage: show-method [OPTIONS] [METH]
407
+ Show the source for method METH. Shows _method_ source (rather than instance methods) by default.
408
+ e.g: show-method hello_method
409
+ --
410
+ }
411
+ opts.on("-M", "--instance-methods", "Operate on instance methods instead.") do
412
+ options[:M] = true
413
+ end
414
+
415
+ opts.on("-c", "--context CONTEXT", "Select object context to run under.") do |context|
416
+ target = Pry.binding_for(target.eval(context))
417
+ end
418
+
419
+ opts.on_tail("-h", "--help", "This message.") do
420
+ output.puts opts
421
+ options[:h] = true
422
+ end
423
+ end.order(args) do |v|
424
+ meth_name = v
425
+ end
426
+
427
+ next if options[:h]
428
+
429
+ # If no method name is given then use current method, if it exists
430
+ meth_name = meth_name_from_binding.call(target) if !meth_name
431
+
432
+ if !meth_name
433
+ output.puts "You need to specify a method. Type `show-method --help` for help"
434
+ next
435
+ end
436
+
437
+ begin
438
+ if options[:M]
439
+ meth = target.eval("instance_method(:#{meth_name})")
440
+ else
441
+ meth = target.eval("method(:#{meth_name})")
442
+ end
443
+ rescue
444
+ target_self = target.eval('self')
445
+ if !options[:M]&& target_self.is_a?(Module) &&
446
+ target_self.method_defined?(meth_name)
447
+ output.puts "Did you mean: show-method -M #{meth_name} ?"
448
+ end
449
+ output.puts "Invalid method name: #{meth_name}. Type `show-method --help` for help"
450
+ next
451
+ end
452
+
453
+ code = meth.source
454
+ file, line = meth.source_location
455
+ check_for_dynamically_defined_method.call(file)
456
+
457
+ output.puts "--\nFrom #{file} @ line #{line}:\n--"
458
+
459
+ if Pry.color
460
+ code = CodeRay.scan(code, :ruby).term
461
+ end
462
+
463
+ output.puts code
464
+ code
465
+ end
466
+
467
+ command "show-command", "Show sourcecode for a Pry command, e.g: show-command cd" do |command_name|
468
+ if !command_name
469
+ output.puts "You must provide a command name."
470
+ next
471
+ end
472
+
473
+ if commands[command_name]
474
+ meth = commands[command_name][:action]
475
+
476
+ code = meth.source
477
+ file, line = meth.source_location
478
+ check_for_dynamically_defined_method.call(file)
479
+
480
+ output.puts "--\nFrom #{file} @ line #{line}:\n--"
481
+
482
+ if Pry.color
483
+ code = CodeRay.scan(code, :ruby).term
484
+ end
485
+
486
+ output.puts code
487
+ code
488
+ else
489
+ output.puts "No such command: #{command_name}."
490
+ end
491
+ end
492
+
493
+ command "jump-to", "Jump to a Pry session further up the stack, exiting all sessions below." do |break_level|
494
+ break_level = break_level.to_i
495
+ nesting = opts[:nesting]
496
+
497
+ case break_level
498
+ when nesting.level
499
+ output.puts "Already at nesting level #{nesting.level}"
500
+ when (0...nesting.level)
501
+ throw(:breakout, break_level + 1)
502
+ else
503
+ max_nest_level = nesting.level - 1
504
+ output.puts "Invalid nest level. Must be between 0 and #{max_nest_level}. Got #{break_level}."
505
+ end
506
+ end
507
+
508
+ command "exit", "End the current Pry session. Accepts optional return value. Aliases: quit, back" do
509
+ str = remove_first_word.call(opts[:val])
510
+ throw(:breakout, [opts[:nesting].level, target.eval(str)])
511
+ end
512
+
513
+ alias_command "quit", "exit", ""
514
+ alias_command "back", "exit", ""
515
+
516
+ command "game", "" do |highest|
517
+ highest = highest ? highest.to_i : 100
518
+ num = rand(highest)
519
+ output.puts "Guess the number between 0-#{highest}: ('.' to quit)"
520
+ count = 0
521
+ while(true)
522
+ count += 1
523
+ str = Readline.readline("game > ", true)
524
+ break if str == "." || !str
525
+ val = str.to_i
526
+ output.puts "Too large!" if val > num
527
+ output.puts "Too small!" if val < num
528
+ if val == num
529
+ output.puts "Well done! You guessed right! It took you #{count} guesses."
530
+ break
531
+ end
532
+ end
533
+ end
534
+
535
+ command "east-coker", "" do
536
+ text = %{
537
+ --
538
+ Now the light falls
539
+ Across the open field, leaving the deep lane
540
+ Shuttered with branches, dark in the afternoon,
541
+ Where you lean against a bank while a van passes,
542
+ And the deep lane insists on the direction
543
+ Into the village, in the electric heat
544
+ Hypnotised. In a warm haze the sultry light
545
+ Is absorbed, not refracted, by grey stone.
546
+ The dahlias sleep in the empty silence.
547
+ Wait for the early owl.
548
+ -- T.S Eliot
549
+ }
550
+ output.puts text
551
+ text
552
+ end
553
+
554
+ command "cohen-poem", "" do
555
+ text = %{
556
+ --
557
+ When this American woman,
558
+ whose thighs are bound in casual red cloth,
559
+ comes thundering past my sitting place
560
+ like a forest-burning Mongol tribe,
561
+ the city is ravished
562
+ and brittle buildings of a hundred years
563
+ splash into the street;
564
+ and my eyes are burnt
565
+ for the embroidered Chinese girls,
566
+ already old,
567
+ and so small between the thin pines
568
+ on these enormous landscapes,
569
+ that if you turn your head
570
+ they are lost for hours.
571
+ -- Leonard Cohen
572
+ }
573
+ output.puts text
574
+ text
575
+ end
576
+ end
577
+ end