Created
August 17, 2014 03:32
-
-
Save JoshCheek/d894a020b07586350d10 to your computer and use it in GitHub Desktop.
Proof of concept for https://github.com/pry/pry/issues/779
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class RefThroughClosure | |
attr_reader :inspect # => nil | |
def initialize(object) | |
@inspect = "#<RefThroughClosure(#{object.inspect})>" # => "#<RefThroughClosure(:dont_track_me_bro)>" | |
@context = lambda { } # => #<Proc:0x007fa7fa03ff80@/Users/josh/Desktop/find_refs.rb:5 (lambda)> | |
end | |
end | |
class RefThroughIvar | |
attr_reader :inspect # => nil | |
def initialize(object) | |
@inspect = "#<RefThroughIvar(#{object.inspect})" # => "#<RefThroughIvar(:dont_track_me_bro)" | |
@object = object # => :dont_track_me_bro | |
end | |
end | |
module FindRef | |
def self.call(target) | |
found = {} # => {} | |
ObjectSpace.each_object(Proc) { |prc| # => ObjectSpace | |
binding = prc.binding rescue next # => #<Binding:0x007fa7f9962e88>, #<Binding:0x007fa7f9961f88>, #<Binding:0x007fa7f9961448>, #<Binding:0x007fa7f9960a48>, #<Binding:0x007fa7f9961718>, #<Binding:0x007fa7f9833350>, #<Binding:0x007fa7f9831a28>, #<Binding:0x007fa7f98304c0>, #<Binding:0x007fa7f983bb40>, #<Binding:0x007fa7f983b1e0>, #<Binding:0x007fa7f983a8a8>, #<Binding:0x007fa7f9839fe8>, #<Binding:0x007fa7f9839660>, #<Binding:0x007... | |
object = binding.eval 'self' # => SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving::Line, SeeingIsBelieving... | |
names_of_locals = binding.eval 'local_variables' # => [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method_name], [:method... | |
locals_that_reference = names_of_locals.select { |name| binding.eval(name.to_s).equal?(target) } # => [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [:object], [] | |
next if locals_that_reference.empty? # => true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, tr... | |
found[object] = { # => #<RefThroughClosure(:dont_track_me_bro)> | |
local_names: locals_that_reference, # => [:object] | |
binding: binding, # => #<Binding:0x007fa7f9912208> | |
closure: prc, # => #<Proc:0x007fa7fa03ff80@/Users/josh/Desktop/find_refs.rb:5 (lambda)> | |
} # => {:local_names=>[:object], :binding=>#<Binding:0x007fa7f9912208>, :closure=>#<Proc:0x007fa7fa03ff80@/Users/josh/Desktop/find_refs.rb:5 (lambda)>} | |
} # => 98 | |
ObjectSpace.each_object(Object) { |object| # => ObjectSpace | |
names_of_ivars = object.instance_variables # => [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], ... | |
ivars_that_reference = names_of_ivars.select { |name| object.instance_variable_get(name).equal?(target) } # => [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [], ... | |
next if ivars_that_reference.empty? # => true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, tr... | |
found[object] ||= {} # => {} | |
found[object][:ivars] = {ivar_names: ivars_that_reference} # => {:ivar_names=>[:@object]} | |
} # => 20470 | |
found # => {#<RefThroughClosure(:dont_track_me_bro)>=>{:local_names=>[:object], :binding=>#<Binding:0x007fa7f9912208>, :closure=>#<Proc:0x007fa7fa03ff80@/Users/josh/Desktop/find_refs.rb:5 (lambda)>}, #<RefThroughIvar(:dont_track_me_bro)=>{:ivars=>{:ivar_names=>[:@object]}}} | |
end | |
end | |
dont_track_me_bro = :dont_track_me_bro # => :dont_track_me_bro | |
ref_through_closure = RefThroughClosure.new(dont_track_me_bro) # => #<RefThroughClosure(:dont_track_me_bro)> | |
ref_through_ivar = RefThroughIvar.new(dont_track_me_bro) # => #<RefThroughIvar(:dont_track_me_bro) | |
require 'pp' # => true | |
pp FindRef.call(dont_track_me_bro) # => {#<RefThroughClosure(:dont_track_me_bro)>=>{:local_names=>[:object], :binding=>#<Binding:0x007fa7f9912208>, :closure=>#<Proc:0x007fa7fa03ff80@/Users/josh/Desktop/find_refs.rb:5 (lambda)>}, #<RefThroughIvar(:dont_track_me_bro)=>{:ivars=>{:ivar_names=>[:@object]}}} | |
# >> {#<RefThroughClosure(:dont_track_me_bro)>=> | |
# >> {:local_names=>[:object], | |
# >> :binding=>#<Binding:0x007fa7f9912208>, | |
# >> :closure=> | |
# >> #<Proc:0x007fa7fa03ff80@/Users/josh/Desktop/find_refs.rb:5 (lambda)>}, | |
# >> #<RefThroughIvar(:dont_track_me_bro)=>{:ivars=>{:ivar_names=>[:@object]}}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment