pry 0.3.0 → 0.4.0pre1

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.
@@ -0,0 +1,202 @@
1
+ # taken from irb
2
+
3
+ require "readline"
4
+
5
+ class Pry
6
+
7
+ # Implements tab completion for Readline in Pry
8
+ module InputCompleter
9
+
10
+ if Readline.respond_to?("basic_word_break_characters=")
11
+ Readline.basic_word_break_characters= " \t\n\"\\'`><=;|&{("
12
+ end
13
+
14
+ Readline.completion_append_character = nil
15
+
16
+ ReservedWords = [
17
+ "BEGIN", "END",
18
+ "alias", "and",
19
+ "begin", "break",
20
+ "case", "class",
21
+ "def", "defined", "do",
22
+ "else", "elsif", "end", "ensure",
23
+ "false", "for",
24
+ "if", "in",
25
+ "module",
26
+ "next", "nil", "not",
27
+ "or",
28
+ "redo", "rescue", "retry", "return",
29
+ "self", "super",
30
+ "then", "true",
31
+ "undef", "unless", "until",
32
+ "when", "while",
33
+ "yield",
34
+ ]
35
+
36
+ Operators = ["%", "&", "*", "**", "+", "-", "/",
37
+ "<", "<<", "<=", "<=>", "==", "===", "=~", ">", ">=", ">>",
38
+ "[]", "[]=", "^", "!", "!=", "!~"]
39
+
40
+ # Return a new completion proc for use by Readline.
41
+ # @param [Binding] target The current binding context.
42
+ # @param [Array<String>] commands The array of Pry commands.
43
+ def self.build_completion_proc(target, commands=[""])
44
+ proc do |input|
45
+ bind = target
46
+
47
+ case input
48
+ when /^(\/[^\/]*\/)\.([^.]*)$/
49
+ # Regexp
50
+ receiver = $1
51
+ message = Regexp.quote($2)
52
+
53
+ candidates = Regexp.instance_methods.collect{|m| m.to_s}
54
+ select_message(receiver, message, candidates)
55
+
56
+ when /^([^\]]*\])\.([^.]*)$/
57
+ # Array
58
+ receiver = $1
59
+ message = Regexp.quote($2)
60
+
61
+ candidates = Array.instance_methods.collect{|m| m.to_s}
62
+ select_message(receiver, message, candidates)
63
+
64
+ when /^([^\}]*\})\.([^.]*)$/
65
+ # Proc or Hash
66
+ receiver = $1
67
+ message = Regexp.quote($2)
68
+
69
+ candidates = Proc.instance_methods.collect{|m| m.to_s}
70
+ candidates |= Hash.instance_methods.collect{|m| m.to_s}
71
+ select_message(receiver, message, candidates)
72
+
73
+ when /^(:[^:.]*)$/
74
+ # Symbol
75
+ if Symbol.respond_to?(:all_symbols)
76
+ sym = $1
77
+ candidates = Symbol.all_symbols.collect{|s| ":" + s.id2name}
78
+ candidates.grep(/^#{sym}/)
79
+ else
80
+ []
81
+ end
82
+
83
+ when /^::([A-Z][^:\.\(]*)$/
84
+ # Absolute Constant or class methods
85
+ receiver = $1
86
+ candidates = Object.constants.collect{|m| m.to_s}
87
+ candidates.grep(/^#{receiver}/).collect{|e| "::" + e}
88
+
89
+ when /^([A-Z].*)::([^:.]*)$/
90
+ # Constant or class methods
91
+ receiver = $1
92
+ message = Regexp.quote($2)
93
+ begin
94
+ candidates = eval("#{receiver}.constants.collect{|m| m.to_s}", bind)
95
+ candidates |= eval("#{receiver}.methods.collect{|m| m.to_s}", bind)
96
+ rescue Exception
97
+ candidates = []
98
+ end
99
+ candidates.grep(/^#{message}/).collect{|e| receiver + "::" + e}
100
+
101
+ when /^(:[^:.]+)\.([^.]*)$/
102
+ # Symbol
103
+ receiver = $1
104
+ message = Regexp.quote($2)
105
+
106
+ candidates = Symbol.instance_methods.collect{|m| m.to_s}
107
+ select_message(receiver, message, candidates)
108
+
109
+ when /^(-?(0[dbo])?[0-9_]+(\.[0-9_]+)?([eE]-?[0-9]+)?)\.([^.]*)$/
110
+ # Numeric
111
+ receiver = $1
112
+ message = Regexp.quote($5)
113
+
114
+ begin
115
+ candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
116
+ rescue Exception
117
+ candidates = []
118
+ end
119
+ select_message(receiver, message, candidates)
120
+
121
+ when /^(-?0x[0-9a-fA-F_]+)\.([^.]*)$/
122
+ # Numeric(0xFFFF)
123
+ receiver = $1
124
+ message = Regexp.quote($2)
125
+
126
+ begin
127
+ candidates = eval(receiver, bind).methods.collect{|m| m.to_s}
128
+ rescue Exception
129
+ candidates = []
130
+ end
131
+ select_message(receiver, message, candidates)
132
+
133
+ when /^(\$[^.]*)$/
134
+ regmessage = Regexp.new(Regexp.quote($1))
135
+ candidates = global_variables.collect{|m| m.to_s}.grep(regmessage)
136
+
137
+ when /^([^."].*)\.([^.]*)$/
138
+ # variable
139
+ receiver = $1
140
+ message = Regexp.quote($2)
141
+
142
+ gv = eval("global_variables", bind).collect{|m| m.to_s}
143
+ lv = eval("local_variables", bind).collect{|m| m.to_s}
144
+ cv = eval("self.class.constants", bind).collect{|m| m.to_s}
145
+
146
+ if (gv | lv | cv).include?(receiver) or /^[A-Z]/ =~ receiver && /\./ !~ receiver
147
+ # foo.func and foo is local var. OR
148
+ # Foo::Bar.func
149
+ begin
150
+ candidates = eval("#{receiver}.methods", bind).collect{|m| m.to_s}
151
+ rescue Exception
152
+ candidates = []
153
+ end
154
+ else
155
+ # func1.func2
156
+ candidates = []
157
+ ObjectSpace.each_object(Module){|m|
158
+ begin
159
+ name = m.name
160
+ rescue Exception
161
+ name = ""
162
+ end
163
+ next if name != "IRB::Context" and
164
+ /^(IRB|SLex|RubyLex|RubyToken)/ =~ name
165
+ candidates.concat m.instance_methods(false).collect{|x| x.to_s}
166
+ }
167
+ candidates.sort!
168
+ candidates.uniq!
169
+ end
170
+ select_message(receiver, message, candidates)
171
+
172
+ when /^\.([^.]*)$/
173
+ # unknown(maybe String)
174
+
175
+ receiver = ""
176
+ message = Regexp.quote($1)
177
+
178
+ candidates = String.instance_methods(true).collect{|m| m.to_s}
179
+ select_message(receiver, message, candidates)
180
+
181
+ else
182
+ candidates = eval("methods | private_methods | local_variables | self.class.constants", bind).collect{|m| m.to_s}
183
+
184
+ (candidates|ReservedWords|commands).grep(/^#{Regexp.quote(input)}/)
185
+ end
186
+ end
187
+ end
188
+
189
+ def self.select_message(receiver, message, candidates)
190
+ candidates.grep(/^#{message}/).collect do |e|
191
+ case e
192
+ when /^[a-zA-Z_]/
193
+ receiver + "." + e
194
+ when /^[0-9]/
195
+ when *Operators
196
+ #receiver + " " + e
197
+ end
198
+ end
199
+ end
200
+ end
201
+ end
202
+
@@ -0,0 +1,47 @@
1
+ class Pry
2
+ module ObjectExtensions
3
+
4
+ # Start a Pry REPL.
5
+ # This method differs from `Pry.start` in that it does not
6
+ # support an options hash. Also, when no parameter is provided, the Pry
7
+ # session will start on the implied receiver rather than on
8
+ # top-level (as in the case of `Pry.start`).
9
+ # It has two forms of invocation. In the first form no parameter
10
+ # should be provided and it will start a pry session on the
11
+ # receiver. In the second form it should be invoked without an
12
+ # explicit receiver and one parameter; this will start a Pry
13
+ # session on the parameter.
14
+ # @param [Object, Binding] target The receiver of the Pry session.
15
+ # @example First form
16
+ # "dummy".pry
17
+ # @example Second form
18
+ # pry "dummy"
19
+ # @example Start a Pry session on current self (whatever that is)
20
+ # pry
21
+ def pry(target=self)
22
+ Pry.start(target)
23
+ end
24
+
25
+ # Return a binding object for the receiver.
26
+ def __binding__
27
+ if is_a?(Module)
28
+ return class_eval "binding"
29
+ end
30
+
31
+ unless respond_to? :__binding_impl__
32
+ self.class.class_eval <<-EXTRA
33
+ def __binding_impl__
34
+ binding
35
+ end
36
+ EXTRA
37
+ end
38
+
39
+ __binding_impl__
40
+ end
41
+ end
42
+ end
43
+
44
+ # bring the extensions into Object
45
+ class Object
46
+ include Pry::ObjectExtensions
47
+ end
@@ -0,0 +1,8 @@
1
+ class Pry
2
+
3
+ # The default hooks - display messages when beginning and ending Pry sessions.
4
+ DEFAULT_HOOKS = {
5
+ :before_session => proc { |out, obj| out.puts "Beginning Pry session for #{Pry.view(obj)}" },
6
+ :after_session => proc { |out, obj| out.puts "Ending Pry session for #{Pry.view(obj)}" }
7
+ }
8
+ end
@@ -0,0 +1,15 @@
1
+ class Pry
2
+
3
+ # The default print object - only show first line of backtrace and
4
+ # prepend output with `=>`
5
+ DEFAULT_PRINT = proc do |output, value|
6
+ case value
7
+ when Exception
8
+ output.puts "#{value.class}: #{value.message}"
9
+ output.puts "from #{value.backtrace.first}"
10
+ else
11
+ output.puts "=> #{Pry.view(value)}"
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,24 @@
1
+ class Pry
2
+
3
+ # The default prompt; includes the target and nesting level
4
+ DEFAULT_PROMPT = [
5
+ proc do |target_self, nest_level|
6
+ if nest_level == 0
7
+ "pry(#{Pry.view(target_self)})> "
8
+ else
9
+ "pry(#{Pry.view(target_self)}):#{Pry.view(nest_level)}> "
10
+ end
11
+ end,
12
+
13
+ proc do |target_self, nest_level|
14
+ if nest_level == 0
15
+ "pry(#{Pry.view(target_self)})* "
16
+ else
17
+ "pry(#{Pry.view(target_self)}):#{Pry.view(nest_level)}* "
18
+ end
19
+ end
20
+ ]
21
+
22
+ # A simple prompt - doesn't display target or nesting level
23
+ SIMPLE_PROMPT = [proc { "pry> " }, proc { "pry* " }]
24
+ end
@@ -0,0 +1,109 @@
1
+ require 'readline'
2
+
3
+ # @author John Mair (banisterfiend)
4
+ class Pry
5
+
6
+ # class accessors
7
+ class << self
8
+
9
+ # Get nesting data.
10
+ # This method should not need to be accessed directly.
11
+ # @return [Array] The unparsed nesting information.
12
+ attr_reader :nesting
13
+
14
+ # Get last value evaluated by Pry.
15
+ # This method should not need to be accessed directly.
16
+ # @return [Object] The last result.
17
+ attr_accessor :last_result
18
+
19
+ # Get the active Pry instance that manages the active Pry session.
20
+ # This method should not need to be accessed directly.
21
+ # @return [Pry] The active Pry instance.
22
+ attr_accessor :active_instance
23
+
24
+ # Get/Set the object to use for input by default by all Pry instances.
25
+ # @return [#readline] The object to use for input by default by all
26
+ # Pry instances.
27
+ attr_accessor :input
28
+
29
+ # Get/Set the object to use for output by default by all Pry instances.
30
+ # @return [#puts] The object to use for output by default by all
31
+ # Pry instances.
32
+ attr_accessor :output
33
+
34
+ # Get/Set the object to use for commands by default by all Pry instances.
35
+ # @return [Pry::CommandBase] The object to use for commands by default by all
36
+ # Pry instances.
37
+ attr_accessor :commands
38
+
39
+ # Get/Set the Proc to use for printing by default by all Pry
40
+ # instances.
41
+ # This is the 'print' component of the REPL.
42
+ # @return [Proc] The Proc to use for printing by default by all
43
+ # Pry instances.
44
+ attr_accessor :print
45
+
46
+ # Get/Set the Hash that defines Pry hooks used by default by all Pry
47
+ # instances.
48
+ # @return [Hash] The hooks used by default by all Pry instances.
49
+ # @example
50
+ # Pry.hooks :before_session => proc { puts "hello" },
51
+ # :after_session => proc { puts "goodbye" }
52
+ attr_accessor :hooks
53
+
54
+ # Get the array of Procs to be used for the prompts by default by
55
+ # all Pry instances.
56
+ # @return [Array<Proc>] The array of Procs to be used for the
57
+ # prompts by default by all Pry instances.
58
+ attr_accessor :prompt
59
+ end
60
+
61
+ # Start a Pry REPL.
62
+ # @param [Object, Binding] target The receiver of the Pry session
63
+ # @param [Hash] options
64
+ # @option options (see Pry#initialize)
65
+ # @example
66
+ # Pry.start(Object.new, :input => MyInput.new)
67
+ def self.start(target=TOPLEVEL_BINDING, options={})
68
+ new(options).repl(target)
69
+ end
70
+
71
+ # A custom version of `Kernel#inspect`.
72
+ # This method should not need to be accessed directly.
73
+ # @param obj The object to view.
74
+ # @return [String] The string representation of `obj`.
75
+ def self.view(obj)
76
+ case obj
77
+ when String, Hash, Array, Symbol, nil
78
+ obj.inspect
79
+ else
80
+ obj.to_s
81
+ end
82
+ end
83
+
84
+ # Set all the configurable options back to their default values
85
+ def self.reset_defaults
86
+ @input = Readline
87
+ @output = $stdout
88
+
89
+ # FIXME
90
+ @commands = Pry::Commands
91
+ @prompt = DEFAULT_PROMPT
92
+ @print = DEFAULT_PRINT
93
+ @hooks = DEFAULT_HOOKS
94
+ end
95
+
96
+ self.reset_defaults
97
+
98
+ @nesting = []
99
+ def @nesting.level
100
+ last.is_a?(Array) ? last.first : nil
101
+ end
102
+
103
+ # Return all active Pry sessions.
104
+ # @return [Array<Pry>] Active Pry sessions.
105
+ def self.sessions
106
+ # last element in nesting array is the pry instance
107
+ nesting.map(&:last)
108
+ end
109
+ end
@@ -0,0 +1,309 @@
1
+ require 'readline'
2
+
3
+ class Pry
4
+
5
+ # The list of configuration options.
6
+ ConfigOptions = [:input, :output, :commands, :print,
7
+ :prompt, :hooks]
8
+
9
+ attr_accessor *ConfigOptions
10
+
11
+ # Create a new `Pry` object.
12
+ # @param [Hash] options The optional configuration parameters.
13
+ # @option options [#readline] :input The object to use for input.
14
+ # @option options [#puts] :output The object to use for output.
15
+ # @option options [Pry::CommandBase] :commands The object to use for
16
+ # commands. (see commands.rb)
17
+ # @option options [Hash] :hooks The defined hook Procs (see hooks.rb)
18
+ # @option options [Array<Proc>] :default_prompt The array of Procs
19
+ # to use for the prompts. (see prompts.rb)
20
+ # @option options [Proc] :print The Proc to use for the 'print'
21
+ # component of the REPL. (see print.rb)
22
+ def initialize(options={})
23
+
24
+ h = {}
25
+ ConfigOptions.each { |v| h[v] = Pry.send(v) }
26
+ default_options = h
27
+ default_options.merge!(options)
28
+
29
+ ConfigOptions.each do |key|
30
+ instance_variable_set("@#{key}", default_options[key])
31
+ end
32
+ end
33
+
34
+ # Get nesting data.
35
+ # This method should not need to be accessed directly.
36
+ # @return [Array] The unparsed nesting information.
37
+ def nesting
38
+ self.class.nesting
39
+ end
40
+
41
+ # Set nesting data.
42
+ # This method should not need to be accessed directly.
43
+ # @param v nesting data.
44
+ def nesting=(v)
45
+ self.class.nesting = v
46
+ end
47
+
48
+ # Return parent of current Pry session.
49
+ # @return [Pry] The parent of the current Pry session.
50
+ def parent
51
+ idx = Pry.sessions.index(self)
52
+
53
+ if idx > 0
54
+ Pry.sessions[idx - 1]
55
+ else
56
+ nil
57
+ end
58
+ end
59
+
60
+ # Execute the hook `hook_name`, if it is defined.
61
+ # @param [Symbol] hook_name The hook to execute
62
+ # @param [Array] args The arguments to pass to the hook.
63
+ def exec_hook(hook_name, *args, &block)
64
+ hooks[hook_name].call(*args, &block) if hooks[hook_name]
65
+ end
66
+
67
+ # Start a read-eval-print-loop.
68
+ # If no parameter is given, default to top-level (main).
69
+ # @param [Object, Binding] target The receiver of the Pry session
70
+ # @return [Object] The target of the Pry session
71
+ # @example
72
+ # Pry.new.repl(Object.new)
73
+ def repl(target=TOPLEVEL_BINDING)
74
+ target = binding_for(target)
75
+ target_self = target.eval('self')
76
+
77
+ exec_hook :before_session, output, target_self
78
+
79
+ # cannot rely on nesting.level as
80
+ # nesting.level changes with new sessions
81
+ nesting_level = nesting.size
82
+
83
+ Pry.active_instance = self
84
+
85
+ # Make sure special locals exist
86
+ target.eval("_pry_ = Pry.active_instance")
87
+ target.eval("_ = Pry.last_result")
88
+
89
+ break_level = catch(:breakout) do
90
+ nesting.push [nesting.size, target_self, self]
91
+ loop do
92
+ rep(target)
93
+ end
94
+ end
95
+
96
+ nesting.pop
97
+
98
+ exec_hook :after_session, output, target_self
99
+
100
+ # keep throwing until we reach the desired nesting level
101
+ if nesting_level != break_level
102
+ throw :breakout, break_level
103
+ end
104
+
105
+ target_self
106
+ end
107
+
108
+ # Perform a read-eval-print.
109
+ # If no parameter is given, default to top-level (main).
110
+ # @param [Object, Binding] target The receiver of the read-eval-print
111
+ # @example
112
+ # Pry.new.rep(Object.new)
113
+ def rep(target=TOPLEVEL_BINDING)
114
+ target = binding_for(target)
115
+ print.call output, re(target)
116
+ end
117
+
118
+ # Perform a read-eval
119
+ # If no parameter is given, default to top-level (main).
120
+ # @param [Object, Binding] target The receiver of the read-eval-print
121
+ # @return [Object] The result of the eval or an `Exception` object in case of error.
122
+ # @example
123
+ # Pry.new.re(Object.new)
124
+ def re(target=TOPLEVEL_BINDING)
125
+ target = binding_for(target)
126
+
127
+ if input == Readline
128
+ # Readline tab completion
129
+ Readline.completion_proc = Pry::InputCompleter.build_completion_proc(target, commands.commands.keys)
130
+ end
131
+
132
+ # eval the expression and save to last_result
133
+ Pry.last_result = target.eval r(target)
134
+
135
+ # save the pry instance to active_instance
136
+ Pry.active_instance = self
137
+
138
+ # define locals _pry_ and _ (active instance and last expression)
139
+ target.eval("_pry_ = Pry.active_instance")
140
+ target.eval("_ = Pry.last_result")
141
+ rescue SystemExit => e
142
+ exit
143
+ rescue Exception => e
144
+ e
145
+ end
146
+
147
+ # Perform a read.
148
+ # If no parameter is given, default to top-level (main).
149
+ # This is a multi-line read; so the read continues until a valid
150
+ # Ruby expression is received.
151
+ # Pry commands are also accepted here and operate on the target.
152
+ # @param [Object, Binding] target The receiver of the read.
153
+ # @return [String] The Ruby expression.
154
+ # @example
155
+ # Pry.new.r(Object.new)
156
+ def r(target=TOPLEVEL_BINDING)
157
+ target = binding_for(target)
158
+ eval_string = ""
159
+
160
+ loop do
161
+ current_prompt = select_prompt(eval_string.empty?, target.eval('self'))
162
+
163
+ val = readline(current_prompt)
164
+ val.chomp!
165
+
166
+ process_commands(val, eval_string, target)
167
+ eval_string << "#{val}\n"
168
+
169
+ break eval_string if valid_expression?(eval_string)
170
+ end
171
+ end
172
+
173
+ # Process Pry commands. Pry commands are not Ruby methods and are evaluated
174
+ # prior to Ruby expressions.
175
+ # Commands can be modified/configured by the user: see `Pry::Commands`
176
+ # This method should not need to be invoked directly - it is called
177
+ # by `Pry#r`.
178
+ # @param [String] val The current line of input.
179
+ # @param [String] eval_string The cumulative lines of input for
180
+ # multi-line input.
181
+ # @param [Binding] target The receiver of the commands.
182
+ def process_commands(val, eval_string, target)
183
+ def val.clear() replace("") end
184
+ def eval_string.clear() replace("") end
185
+
186
+ pattern, data = commands.commands.find do |name, data|
187
+ /^#{name}(?!\S)(?:\s+(.+))?/ =~ val
188
+ end
189
+
190
+ if pattern
191
+ args_string = $1
192
+ args = args_string ? args_string.split : []
193
+ action = data[:action]
194
+
195
+ options = {
196
+ :val => val,
197
+ :eval_string => eval_string,
198
+ :nesting => nesting,
199
+ :commands => commands.commands
200
+ }
201
+
202
+ # set some useful methods to be used by the action blocks
203
+ commands.opts = options
204
+ commands.target = target
205
+ commands.output = output
206
+
207
+ case action.arity <=> 0
208
+ when -1
209
+
210
+ # Use instance_exec() to make the `opts` method, etc available
211
+ commands.instance_exec(*args, &action)
212
+ when 1, 0
213
+
214
+ # ensure that we get the right number of parameters
215
+ # since 1.8.7 complains about incorrect arity (1.9.2
216
+ # doesn't care)
217
+ args_with_corrected_arity = args.values_at *0..(action.arity - 1)
218
+ commands.instance_exec(*args_with_corrected_arity, &action)
219
+ end
220
+
221
+ val.clear
222
+ end
223
+ end
224
+
225
+ # Returns the next line of input to be used by the pry instance.
226
+ # This method should not need to be invoked directly.
227
+ # @param [String] current_prompt The prompt to use for input.
228
+ # @return [String] The next line of input.
229
+ def readline(current_prompt="> ")
230
+
231
+ if input == Readline
232
+
233
+ # Readline must be treated differently
234
+ # as it has a second parameter.
235
+ input.readline(current_prompt, true)
236
+ else
237
+ if input.method(:readline).arity == 1
238
+ input.readline(current_prompt)
239
+ else
240
+ input.readline
241
+ end
242
+ end
243
+ end
244
+
245
+ # Returns the appropriate prompt to use.
246
+ # This method should not need to be invoked directly.
247
+ # @param [Boolean] first_line Whether this is the first line of input
248
+ # (and not multi-line input).
249
+ # @param [Object] target_self The receiver of the Pry session.
250
+ # @return [String] The prompt.
251
+ def select_prompt(first_line, target_self)
252
+
253
+ if first_line
254
+ Array(prompt).first.call(target_self, nesting.level)
255
+ else
256
+ Array(prompt).last.call(target_self, nesting.level)
257
+ end
258
+ end
259
+
260
+ if RUBY_VERSION =~ /1.9/
261
+ require 'ripper'
262
+
263
+ # Determine if a string of code is a valid Ruby expression.
264
+ # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
265
+ # @param [String] code The code to validate.
266
+ # @return [Boolean] Whether or not the code is a valid Ruby expression.
267
+ # @example
268
+ # valid_expression?("class Hello") #=> false
269
+ # valid_expression?("class Hello; end") #=> true
270
+ def valid_expression?(code)
271
+ !!Ripper::SexpBuilder.new(code).parse
272
+ end
273
+
274
+ else
275
+ require 'ruby_parser'
276
+
277
+ # Determine if a string of code is a valid Ruby expression.
278
+ # Ruby 1.9 uses Ripper, Ruby 1.8 uses RubyParser.
279
+ # @param [String] code The code to validate.
280
+ # @return [Boolean] Whether or not the code is a valid Ruby expression.
281
+ # @example
282
+ # valid_expression?("class Hello") #=> false
283
+ # valid_expression?("class Hello; end") #=> true
284
+ def valid_expression?(code)
285
+ RubyParser.new.parse(code)
286
+ rescue Racc::ParseError, SyntaxError
287
+ false
288
+ else
289
+ true
290
+ end
291
+ end
292
+
293
+ # Return a `Binding` object for `target` or return `target` if it is
294
+ # already a `Binding`.
295
+ # In the case where `target` is top-level then return `TOPLEVEL_BINDING`
296
+ # @param [Object] target The object to get a `Binding` object for.
297
+ # @return [Binding] The `Binding` object.
298
+ def binding_for(target)
299
+ if target.is_a?(Binding)
300
+ target
301
+ else
302
+ if target == TOPLEVEL_BINDING.eval('self')
303
+ TOPLEVEL_BINDING
304
+ else
305
+ target.__binding__
306
+ end
307
+ end
308
+ end
309
+ end