Skip to content

Instantly share code, notes, and snippets.

@JoshCheek
Created August 17, 2014 03:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JoshCheek/d894a020b07586350d10 to your computer and use it in GitHub Desktop.
Save JoshCheek/d894a020b07586350d10 to your computer and use it in GitHub Desktop.
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