pry 0.3.0 → 0.4.0pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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