Permalink
Browse files

Prevented local variables from being leaked into bindings used by Pry…

… (fixes #662)
  • Loading branch information...
1 parent d86f374 commit 083b06aba2b342157392d1ae5d043a453d811269 @Mon-Ouie Mon-Ouie committed Jul 22, 2012
Showing with 32 additions and 16 deletions.
  1. +26 −16 lib/pry/core_extensions.rb
  2. +6 −0 test/test_pry.rb
View
42 lib/pry/core_extensions.rb
@@ -1,3 +1,23 @@
+class Pry
+ # @retun [String] Code of the method used when implementing Pry's
+ # __binding__.
+ #
+ # @see Object#__binding__
+ BindingImplMethod = [<<-METHOD, __FILE__, __LINE__ + 1]
+ # Get a binding with 'self' set to self, and no locals.
+ #
+ # The default definee is determined by the context in which the
+ # definition is eval'd.
+ #
+ # Please don't call this method directly, see {__binding__}.
+ #
+ # @return [Binding]
+ def __pry__
+ binding
+ end
+ METHOD
+end
+
class Object
# Start a Pry REPL on self.
#
@@ -45,42 +65,32 @@ def pry(object=nil, hash={})
#
# @return [Binding]
def __binding__
+ # If you ever feel like changing this method, be careful about variables
+ # that you use. They shouldn't be inserted into the binding that will
+ # eventually be retruning.
+
# When you're cd'd into a class, methods you define should be added to it.
if is_a?(Module)
# class_eval sets both self and the default definee to this class.
return class_eval "binding"
end
unless respond_to?(:__pry__)
- binding_impl_method = [<<-METHOD, __FILE__, __LINE__ + 1]
- # Get a binding with 'self' set to self, and no locals.
- #
- # The default definee is determined by the context in which the
- # definition is eval'd.
- #
- # Please don't call this method directly, see {__binding__}.
- #
- # @return [Binding]
- def __pry__
- binding
- end
- METHOD
-
# The easiest way to check whether an object has a working singleton class
# is to try and define a method on it. (just checking for the presence of
# the singleton class gives false positives for `true` and `false`).
# __pry__ is just the closest method we have to hand, and using
# it has the nice property that we can memoize this check.
begin
# instance_eval sets the default definee to the object's singleton class
- instance_eval(*binding_impl_method)
+ instance_eval(*Pry::BindingImplMethod)
# If we can't define methods on the Object's singleton_class. Then we fall
# back to setting the default definee to be the Object's class. That seems
# nicer than having a REPL in which you can't define methods.
rescue TypeError
# class_eval sets the default definee to self.class
- self.class.class_eval(*binding_impl_method)
+ self.class.class_eval(*Pry::BindingImplMethod)
end
end
View
6 test/test_pry.rb
@@ -31,6 +31,12 @@ def o.==(other)
lambda { Pry.binding_for(o) }.should.not.raise Exception
end
+
+ it "should not leak local variables" do
+ [Object.new, Array, 3].each do |obj|
+ Pry.binding_for(obj).eval("local_variables").should.be.empty
+ end
+ end
end
describe "open a Pry session on an object" do

0 comments on commit 083b06a

Please sign in to comment.